Manual de uso del API de Podcast
El API de podcast expone la información pública de los programas de audio y sus episodios. El flujo recomendado es:
- Consultar los programas disponibles (sin episodios) mediante
GET /api/podcast/programs. - Solicitar un programa específico con
GET /api/podcast/programs?slug=<programa>para obtener sus episodios publicados (sin detalles extensos). - Obtener la información completa de un episodio con
GET /api/podcast/episodes?slug=<episodio>[&programId=<programa>].
Nota: En el entorno de producción actual solo se habilitan operaciones de lectura (
GET). Las rutasPOST,PUTyDELETErequieren permisos adicionales y autorización explícita del proyecto.
Autenticación
- Incluye
Authorization: Bearer <token>en cada solicitud. - El token debe estar activo y tener permisos sobre el recurso que consultas.
- Usa
Content-Type: application/jsonpara llamadas con cuerpo.
Permisos
read: necesario para consumir programas o episodios.create,update,delete: requeridos para crear, actualizar o eliminar episodios (solo si están habilitados en tu entorno).
Si el token está expirado, desactivado o carece del permiso correspondiente, la API responde con 401 o 403.
Códigos de respuesta comunes
200 OK: respuesta exitosa.201 Created: episodio creado correctamente (POST).204 No Content: episodio eliminado correctamente (DELETE).400 Bad Request: parámetros inválidos o sin slug requerido.401 / 403: token ausente, inválido o sin permisos.404 Not Found: recurso inexistente, filtrado o no publicado.405 Method Not Allowed: el método no está habilitado.409 Conflict: slug duplicado al crear.500 Internal Server Error: error interno no controlado.
Programas — /api/podcast/programs
Lista de programas (GET)
Devuelve los programas de la página asociada al token sin incluir episodios. Usa las categorías (categoryId) y anfitriones (authorId) para filtrar programas.
Query params
limit(número > 0, opcional): máximo de programas a devolver (hasta 100).categoryId(string, opcional): slug de categoría para filtrar programas.authorId(string, opcional): slug de anfitrión para filtrar programas.search(string, opcional): busca en nombre, descripción o slug del programa.
curl "https://cms.begraffic.com/api/podcast/programs?categoryId=marketing" \
-H "Authorization: Bearer TU_TOKEN"Respuesta
{
"count": 2,
"programs": [
{
"id": "marketing-lab",
"name": "Marketing Lab",
"slug": "marketing-lab",
"description": "Historias y estrategias de marketing digital.",
"playlistUrl": "https://open.spotify.com/playlist/...",
"coverImageUrl": "https://cdn.ejemplo.com/cover.jpg",
"participants": ["Ana García", "Luis Ocampo"],
"categoryId": "marketing",
"categoryName": "Marketing",
"authorId": "ana-garcia",
"authorName": "Ana García",
"episodesCount": 12,
"createdAt": "2024-02-10T12:00:00.000Z",
"updatedAt": "2024-05-05T09:30:00.000Z"
}
]
}Detalle de programa (GET con slug)
curl "https://cms.begraffic.com/api/podcast/programs?slug=marketing-lab" \
-H "Authorization: Bearer TU_TOKEN"Respuesta
{
"program": {
"id": "marketing-lab",
"name": "Marketing Lab",
"slug": "marketing-lab",
"description": "Historias y estrategias de marketing digital.",
"playlistUrl": "https://open.spotify.com/playlist/...",
"coverImageUrl": "https://cdn.ejemplo.com/cover.jpg",
"participants": ["Ana García", "Luis Ocampo"],
"categoryId": "marketing",
"categoryName": "Marketing",
"authorId": "ana-garcia",
"authorName": "Ana García",
"episodesCount": 12,
"createdAt": "2024-02-10T12:00:00.000Z",
"updatedAt": "2024-05-05T09:30:00.000Z"
},
"episodes": [
{
"id": "estrategia-2025",
"title": "Estrategia 2025",
"slug": "estrategia-2025",
"coverImageUrl": "https://cdn.ejemplo.com/cover.jpg",
"publishedAt": "2024-05-10T15:00:00.000Z"
},
{
"id": "lanzamiento-2024",
"title": "Lanzamiento 2024",
"slug": "lanzamiento-2024",
"coverImageUrl": "https://cdn.ejemplo.com/cover.jpg",
"publishedAt": "2024-04-20T10:00:00.000Z"
}
]
}Los episodios devueltos están publicados y listos para consumo público; solo incluyen nombre, identificadores, portada y fecha. Usa el endpoint de episodios para obtener detalles completos.
Episodios — /api/podcast/episodes
Detalle (GET con slug)
Devuelve toda la información del episodio, incluyendo contenido HTML y metadatos. El parámetro slug es obligatorio; opcionalmente puedes especificar programId para desambiguar cuando varios programas comparten el mismo slug.
curl "https://cms.begraffic.com/api/podcast/episodes?slug=estrategia-2025&programId=marketing-lab" \
-H "Authorization: Bearer TU_TOKEN"Respuesta
{
"episode": {
"id": "estrategia-2025",
"title": "Estrategia 2025",
"slug": "estrategia-2025",
"excerpt": "Un vistazo a la estrategia 2025.",
"status": "published",
"categoryId": "marketing",
"categoryName": "Marketing",
"authorId": "ana-garcia",
"authorName": "Ana García",
"programId": "marketing-lab",
"programSlug": "marketing-lab",
"programName": "Marketing Lab",
"pageId": "workspace-page",
"tableId": "empresa-123",
"tags": ["estrategia", "2025"],
"isScheduled": false,
"scheduledFor": null,
"publishedAt": "2024-05-10T15:00:00.000Z",
"createdAt": "2024-05-01T12:00:00.000Z",
"updatedAt": "2024-05-05T09:30:00.000Z",
"youtubeUrl": "https://youtu.be/ejemplo",
"coverImageUrl": "https://cdn.ejemplo.com/cover.jpg",
"autoGeneratedBlog": false,
"autoGeneratedDetails": false,
"autoGeneratedSources": null,
"generationStatus": "completed",
"generationError": null,
"generationUpdatedAt": "2024-05-05T09:30:00.000Z",
"content": {
"html": "<h1>Bienvenidos</h1>",
"htmlPreview": "<h1>Bienvenidos</h1>"
},
"metadata": null
}
}Si el episodio no está publicado o su fecha programada es futura, la API responde 404. Para obtener listados usa el endpoint de programas.
Creación y mantenimiento (solo si están habilitados)
Las siguientes rutas requieren permisos específicos en el token:
POST /api/podcast/episodes: crea un episodio dentro de un programa.PUT /api/podcast/episodes?slug=<slug>[&programId=<programa>]: actualiza un episodio existente (el slug no cambia).DELETE /api/podcast/episodes?slug=<slug>[&programId=<programa>]: elimina el episodio indicado.
Campos clave en POST y PUT
title,slug,status,programIdson obligatorios (status∈draft,published,hidden,archived).contentaceptahtmlyhtmlPreview.coverImage/coverImageUrlmantienen la portada.isScheduled+scheduledForprograman publicaciones futuras (ISO 8601).- Si
autoGeneratedBlogestrue, puedes reportar progreso congenerationStatus,generationError,generationUpdatedAtyautoGeneratedSources. categoryId/authorIdse heredan del programa si se omiten.
No envíes createdAt, updatedAt ni publishedAt; la API los asigna.
Recomendaciones
- Usa
/api/podcast/programspara descubrir contenido; recurre a/api/podcast/episodesúnicamente para el detalle final. - Normaliza
programId,categoryIdyauthorIda minúsculas sin espacios antes de enviar solicitudes. - Evita ejecutar
POST/PUTen paralelo sobre el mismoslugpara prevenir condiciones de carrera. - Cuando dependas de episodios con autogeneración, revisa
generationStatusygenerationUpdatedAtpara refrescar contenido una vez concluido el proceso.