The Course APIs provide access to the complete Platzi course catalog loaded from the courses cache.
Get Full Course Catalog
curl http://localhost:8080/api/courses
Endpoint
Returns the complete course catalog with all categories, routes, courses, modules, and classes.
Response
Array of course categories Display name (e.g., “Desarrollo Web”)
Array of learning routes/courses Platzi URL for this route
If true, this route is a single course (not a multi-course route)
Array of courses (only if isCourse=false)
Array of course modules (only if isCourse=true) Array of class objects Drive file IDs for class content Google Drive file ID for video
Google Drive file ID for poster image
Google Drive file ID for slides PDF
Additional resources for the class
Course catalog statistics Number of individual classes
Example Response
{
"categories" : [
{
"id" : "web-dev" ,
"name" : "Desarrollo Web" ,
"icon" : "💻" ,
"description" : "Aprende desarrollo web" ,
"type" : "career" ,
"routes" : [
{
"id" : "frontend" ,
"name" : "Desarrollo Frontend" ,
"url" : "https://platzi.com/escuela/frontend" ,
"isCourse" : false ,
"courseCount" : 5 ,
"courses" : [
{
"name" : "Curso de HTML y CSS" ,
"id" : "html-css" ,
"publicId" : "curso-html-css" ,
"url" : "https://platzi.com/cursos/html-css" ,
"moduleCount" : 4 ,
"classCount" : 32 ,
"foundInDrive" : true ,
"modules" : [
{
"name" : "Introducción" ,
"classes" : [
{
"name" : "Bienvenida al curso" ,
"order" : 1 ,
"files" : {
"video" : "1aB2cD3eF4gH5iJ6kL7mN8oP9qR0" ,
"poster" : "1aB2cD3eF4gH5iJ6kL7mN8oP9qR1" ,
"slides" : "1aB2cD3eF4gH5iJ6kL7mN8oP9qR2"
},
"resources" : [
{
"name" : "Código de ejemplo" ,
"file" : "1aB2cD3eF4gH5iJ6kL7mN8oP9qR3"
}
]
}
]
}
]
}
]
}
]
}
],
"stats" : {
"totalCategories" : 12 ,
"totalRoutes" : 45 ,
"totalCourses" : 234 ,
"totalClasses" : 5678
}
}
Cache Behavior
The server automatically reloads the cache if courses_cache.json is modified on disk.
Get Bootstrap Data
curl http://localhost:8080/api/bootstrap
Endpoint
Returns a lightweight version of the course catalog with module summaries instead of full class data. Use this for initial page load to reduce payload size.
Response
Same structure as /api/courses, but:
modules array contains summaries instead of full class objects
Each module has name, classCount, and classes (numeric count)
Individual class details are omitted
Example Response
{
"categories" : [
{
"routes" : [
{
"courses" : [
{
"name" : "Curso de HTML y CSS" ,
"moduleCount" : 4 ,
"classCount" : 32 ,
"modules" : [
{
"name" : "Introducción" ,
"classCount" : 8 ,
"classes" : 8
}
]
}
]
}
]
}
],
"stats" : {
"totalCategories" : 12 ,
"totalRoutes" : 45 ,
"totalCourses" : 234 ,
"totalClasses" : 5678
}
}
Bootstrap payload is typically 60-80% smaller than the full course catalog. Use this for faster initial page loads.
Get Course Detail
curl http://localhost:8080/api/course-detail/web-dev/frontend/curso-html-css
Endpoint
GET /api/course-detail/{catRef}/{routeRef}/{courseRef}
Returns detailed information for a specific course.
Path Parameters
Category identifier. Can be:
Numeric index (e.g., 0, 1, 2)
Category id field
Category name (exact match)
Slugified category name
Route identifier. Can be:
Numeric index (e.g., 0, 1, 2)
Route id field
Route name (exact match)
Slugified route name
URL slug extracted from route URL
Course identifier. Can be:
Numeric index (e.g., 0, 1, 2)
Course id field
Course name (exact match)
Slugified course name
URL slug extracted from course URL
Course publicId
Response
Course public ID or index
Numeric indices for category/route/course Route array index within category
Course array index within route
Complete course object with modules and classes
Whether the route is a single-course route
Example Response
{
"catId" : "web-dev" ,
"routeId" : "frontend" ,
"courseId" : "curso-html-css" ,
"indices" : {
"catIdx" : 0 ,
"routeIdx" : 1 ,
"courseIdx" : 0
},
"course" : {
"name" : "Curso de HTML y CSS" ,
"url" : "https://platzi.com/cursos/html-css" ,
"modules" : [
// Full module and class data
]
},
"isCourseRoute" : false
}
Error Responses
The category reference that was searched
The route reference that was searched
The course reference that was searched
404 Not Found
{
"error" : "course_not_found" ,
"catRef" : "invalid-cat" ,
"routeRef" : "invalid-route" ,
"courseRef" : "invalid-course"
}
400 Bad Request
{
"error" : "invalid_course_detail_path" ,
"expected" : "/api/course-detail/<catId>/<routeId>/<courseId>"
}
curl http://localhost:8080/api/cache-meta
Endpoint
Returns metadata about the currently loaded courses cache.
Response
Absolute path to the cache file
Filename (e.g., courses_cache.json)
Cache source: data, viewer, external, or none
Last modified time in ISO 8601 format
Last modified time as Unix epoch
Course statistics (same as in /api/courses)
Payload size information Size of full catalog in bytes
Size of bootstrap catalog in bytes
Example Response
{
"cache_file_path" : "/home/user/platzi-viewer/courses_cache.json" ,
"cache_file_name" : "courses_cache.json" ,
"source" : "data" ,
"mtime" : "2026-03-07T10:30:00Z" ,
"mtimeEpoch" : 1741344600 ,
"stats" : {
"totalCategories" : 12 ,
"totalRoutes" : 45 ,
"totalCourses" : 234 ,
"totalClasses" : 5678
},
"payloadBytes" : {
"full" : 2457600 ,
"bootstrap" : 524288
}
}
File References
All file references in the course catalog are Google Drive file IDs :
Format: 10+ character alphanumeric strings (e.g., 1aB2cD3eF4gH5iJ6kL7mN8oP9qR0)
Used in files.video, files.poster, files.slides, and resources[].file fields
Stream files via /drive/files/{fileId} endpoint
Local file references (local:...) are not supported in Drive mode. All files must be Drive IDs.
Public ID Generation
Course publicId is generated using this priority:
URL slug (extracted from url field)
Course id field
Slugified course name
Module Summaries
In bootstrap mode, modules contain:
{
"name" : "Module Name" ,
"classCount" : 8 ,
"classes" : 8
}
In full mode, modules contain complete classes array with all class details.
Next Steps
Progress API Track user progress through courses
Drive Proxy Stream course files from Google Drive