Referencia de la API REST
EmDash expone una API REST en /_emdash/api/ para la gestión de contenido, subida de medios y operaciones de esquema.
Autenticación
Sección titulada «Autenticación»Las solicitudes a la API requieren autenticación mediante un token Bearer:
Authorization: Bearer <token>Genera tokens a través de la interfaz de administración o de forma programática.
Formato de Respuesta
Sección titulada «Formato de Respuesta»Todas las respuestas siguen un formato consistente:
// Exito{ "success": true, "data": { ... }}
// Error{ "success": false, "error": { "code": "ERROR_CODE", "message": "Mensaje legible para humanos", "details": { ... } }}Endpoints de Contenido
Sección titulada «Endpoints de Contenido»Listar Contenido
Sección titulada «Listar Contenido»GET /_emdash/api/content/:collectionParámetros
Sección titulada «Parámetros»| Parámetro | Tipo | Descripción |
|---|---|---|
collection | string | Slug de la colección (ruta) |
cursor | string | Cursor de paginación (consulta) |
limit | number | Elementos por página (consulta, predeterminado: 50) |
status | string | Filtrar por estado (consulta) |
orderBy | string | Campo por el que ordenar (consulta) |
order | string | Dirección de orden: asc o desc (consulta) |
Respuesta
Sección titulada «Respuesta»{ "success": true, "data": { "items": [ { "id": "01HXK5MZSN...", "type": "posts", "slug": "hello-world", "data": { "title": "Hola mundo", ... }, "status": "published", "createdAt": "2025-01-24T12:00:00Z", "updatedAt": "2025-01-24T12:00:00Z" } ], "nextCursor": "eyJpZCI6..." }}Obtener Contenido
Sección titulada «Obtener Contenido»GET /_emdash/api/content/:collection/:idRespuesta
Sección titulada «Respuesta»{ "success": true, "data": { "item": { "id": "01HXK5MZSN...", "type": "posts", "slug": "hello-world", "data": { "title": "Hola mundo", ... }, "status": "published", "createdAt": "2025-01-24T12:00:00Z", "updatedAt": "2025-01-24T12:00:00Z" } }}Crear Contenido
Sección titulada «Crear Contenido»POST /_emdash/api/content/:collectionContent-Type: application/jsonCuerpo de la Solicitud
Sección titulada «Cuerpo de la Solicitud»{ "data": { "title": "Nueva entrada", "content": [...] }, "slug": "new-post", "status": "draft"}Respuesta
Sección titulada «Respuesta»{ "success": true, "data": { "item": { ... } }}Actualizar Contenido
Sección titulada «Actualizar Contenido»PUT /_emdash/api/content/:collection/:idContent-Type: application/jsonCuerpo de la Solicitud
Sección titulada «Cuerpo de la Solicitud»{ "data": { "title": "Titulo actualizado" }, "status": "published"}Eliminar Contenido
Sección titulada «Eliminar Contenido»DELETE /_emdash/api/content/:collection/:idRespuesta
Sección titulada «Respuesta»{ "success": true, "data": { "success": true }}Endpoints de Medios
Sección titulada «Endpoints de Medios»Listar Medios
Sección titulada «Listar Medios»GET /_emdash/api/mediaParámetros
Sección titulada «Parámetros»| Parámetro | Tipo | Descripción |
|---|---|---|
cursor | string | Cursor de paginación |
limit | number | Elementos por página (predeterminado: 20) |
mimeType | string | Filtrar por prefijo de tipo MIME |
Respuesta
Sección titulada «Respuesta»{ "success": true, "data": { "items": [ { "id": "01HXK5MZSN...", "filename": "photo.jpg", "mimeType": "image/jpeg", "size": 102400, "width": 1920, "height": 1080, "url": "https://cdn.example.com/photo.jpg", "createdAt": "2025-01-24T12:00:00Z" } ], "nextCursor": "eyJpZCI6..." }}Obtener Medio
Sección titulada «Obtener Medio»GET /_emdash/api/media/:idCrear Medio
Sección titulada «Crear Medio»POST /_emdash/api/mediaContent-Type: application/jsonCuerpo de la Solicitud
Sección titulada «Cuerpo de la Solicitud»{ "filename": "photo.jpg", "mimeType": "image/jpeg", "size": 102400, "width": 1920, "height": 1080, "storageKey": "uploads/photo.jpg"}Actualizar Medio
Sección titulada «Actualizar Medio»PUT /_emdash/api/media/:idContent-Type: application/jsonCuerpo de la Solicitud
Sección titulada «Cuerpo de la Solicitud»{ "alt": "Descripcion de la foto", "caption": "Pie de foto"}Eliminar Medio
Sección titulada «Eliminar Medio»DELETE /_emdash/api/media/:idObtener Archivo de Medio
Sección titulada «Obtener Archivo de Medio»GET /_emdash/api/media/file/:keySirve el contenido real del archivo. Solo para almacenamiento local.
Endpoints de Revisiones
Sección titulada «Endpoints de Revisiones»Listar Revisiones
Sección titulada «Listar Revisiones»GET /_emdash/api/content/:collection/:entryId/revisionsParámetros
Sección titulada «Parámetros»| Parámetro | Tipo | Descripción |
|---|---|---|
limit | number | Máximo de revisiones a devolver (predeterminado: 50) |
Respuesta
Sección titulada «Respuesta»{ "success": true, "data": { "items": [ { "id": "01HXK5MZSN...", "collection": "posts", "entryId": "01HXK5MZSN...", "data": { ... }, "createdAt": "2025-01-24T12:00:00Z" } ], "total": 5 }}Obtener Revisión
Sección titulada «Obtener Revisión»GET /_emdash/api/revisions/:revisionIdRestaurar Revisión
Sección titulada «Restaurar Revisión»POST /_emdash/api/revisions/:revisionId/restoreRestaura el contenido al estado de esta revisión y crea una nueva revisión.
Endpoints de Esquema
Sección titulada «Endpoints de Esquema»Listar Colecciones
Sección titulada «Listar Colecciones»GET /_emdash/api/schema/collectionsRespuesta
Sección titulada «Respuesta»{ "success": true, "data": { "items": [ { "id": "01HXK5MZSN...", "slug": "posts", "label": "Entradas", "labelSingular": "Entrada", "supports": ["drafts", "revisions", "preview"] } ] }}Obtener Colección
Sección titulada «Obtener Colección»GET /_emdash/api/schema/collections/:slugParámetros
Sección titulada «Parámetros»| Parámetro | Tipo | Descripción |
|---|---|---|
includeFields | boolean | Incluir definiciones de campos (consulta) |
Crear Colección
Sección titulada «Crear Colección»POST /_emdash/api/schema/collectionsContent-Type: application/jsonCuerpo de la Solicitud
Sección titulada «Cuerpo de la Solicitud»{ "slug": "products", "label": "Products", "labelSingular": "Product", "description": "Product catalog", "supports": ["drafts", "revisions"]}Actualizar Colección
Sección titulada «Actualizar Colección»PATCH /_emdash/api/schema/collections/:slugContent-Type: application/jsonEliminar Colección
Sección titulada «Eliminar Colección»DELETE /_emdash/api/schema/collections/:slugParámetros
Sección titulada «Parámetros»| Parámetro | Tipo | Descripción |
|---|---|---|
force | boolean | Eliminar incluso si la colección tiene contenido (consulta) |
Listar Campos
Sección titulada «Listar Campos»GET /_emdash/api/schema/collections/:slug/fieldsCrear Campo
Sección titulada «Crear Campo»POST /_emdash/api/schema/collections/:slug/fieldsContent-Type: application/jsonCuerpo de la Solicitud
Sección titulada «Cuerpo de la Solicitud»{ "slug": "price", "label": "Price", "type": "number", "required": true, "validation": { "min": 0 }}Actualizar Campo
Sección titulada «Actualizar Campo»PATCH /_emdash/api/schema/collections/:collectionSlug/fields/:fieldSlugContent-Type: application/jsonEliminar Campo
Sección titulada «Eliminar Campo»DELETE /_emdash/api/schema/collections/:collectionSlug/fields/:fieldSlugReordenar Campos
Sección titulada «Reordenar Campos»POST /_emdash/api/schema/collections/:slug/fields/reorderContent-Type: application/jsonCuerpo de la Solicitud
Sección titulada «Cuerpo de la Solicitud»{ "fieldSlugs": ["title", "content", "author", "publishedAt"]}Exportación de Esquema
Sección titulada «Exportación de Esquema»Exportar Esquema (JSON)
Sección titulada «Exportar Esquema (JSON)»GET /_emdash/api/schemaAccept: application/jsonExportar Esquema (TypeScript)
Sección titulada «Exportar Esquema (TypeScript)»GET /_emdash/api/schema?format=typescriptAccept: text/typescriptDevuelve interfaces TypeScript para todas las colecciones.
Endpoints de Plugins
Sección titulada «Endpoints de Plugins»Listar Plugins
Sección titulada «Listar Plugins»GET /_emdash/api/pluginsObtener Plugin
Sección titulada «Obtener Plugin»GET /_emdash/api/plugins/:pluginIdHabilitar Plugin
Sección titulada «Habilitar Plugin»POST /_emdash/api/plugins/:pluginId/enableDeshabilitar Plugin
Sección titulada «Deshabilitar Plugin»POST /_emdash/api/plugins/:pluginId/disableCódigos de Error
Sección titulada «Códigos de Error»| Código | Estado HTTP | Descripción |
|---|---|---|
NOT_FOUND | 404 | Recurso no encontrado |
VALIDATION_ERROR | 400 | Datos de entrada inválidos |
UNAUTHORIZED | 401 | Token faltante o inválido |
FORBIDDEN | 403 | Permisos insuficientes |
CONTENT_LIST_ERROR | 500 | Error al listar contenido |
CONTENT_CREATE_ERROR | 500 | Error al crear contenido |
CONTENT_UPDATE_ERROR | 500 | Error al actualizar contenido |
CONTENT_DELETE_ERROR | 500 | Error al eliminar contenido |
MEDIA_LIST_ERROR | 500 | Error al listar medios |
MEDIA_CREATE_ERROR | 500 | Error al crear medio |
SCHEMA_ERROR | 400 | Error en operación de esquema |
DUPLICATE_SLUG | 409 | El slug ya existe |
RESERVED_SLUG | 400 | El slug está reservado |
Endpoints de Búsqueda
Sección titulada «Endpoints de Búsqueda»Búsqueda Global
Sección titulada «Búsqueda Global»GET /_emdash/api/search?q=hello+worldParámetros
Sección titulada «Parámetros»| Parámetro | Tipo | Descripción |
|---|---|---|
q | string | Consulta de búsqueda (requerida) |
collections | string | Slugs de colección separados por comas |
status | string | Filtrar por estado (predeterminado: publicado) |
limit | number | Máximo de resultados (predeterminado: 20) |
cursor | string | Cursor de paginación |
Respuesta
Sección titulada «Respuesta»{ "results": [ { "collection": "posts", "id": "01HXK5MZSN...", "slug": "hello-world", "title": "Hola mundo", "snippet": "...this is a <mark>hello</mark> <mark>world</mark> example...", "score": 0.95 } ], "nextCursor": "eyJvZmZzZXQiOjIwfQ"}Sugerencias de Búsqueda
Sección titulada «Sugerencias de Búsqueda»GET /_emdash/api/search/suggest?q=hel&limit=5Devuelve títulos con coincidencia de prefijo para autocompletar.
Reconstruir Índice de Búsqueda
Sección titulada «Reconstruir Índice de Búsqueda»POST /_emdash/api/search/rebuildReconstruye el índice FTS para todas o colecciones específicas.
Estadísticas de Búsqueda
Sección titulada «Estadísticas de Búsqueda»GET /_emdash/api/search/statsDevuelve recuentos de documentos indexados por colección.
Endpoints de Secciones
Sección titulada «Endpoints de Secciones»Listar Secciones
Sección titulada «Listar Secciones»GET /_emdash/api/sectionsGET /_emdash/api/sections?source=themeGET /_emdash/api/sections?search=newsletterObtener Sección
Sección titulada «Obtener Sección»GET /_emdash/api/sections/:slugCrear Sección
Sección titulada «Crear Sección»POST /_emdash/api/sectionsContent-Type: application/json
{ "slug": "my-section", "title": "My Section", "keywords": ["keyword1"], "content": [...]}Actualizar Sección
Sección titulada «Actualizar Sección»PUT /_emdash/api/sections/:slugEliminar Sección
Sección titulada «Eliminar Sección»DELETE /_emdash/api/sections/:slugEndpoints de Configuración
Sección titulada «Endpoints de Configuración»Obtener Toda la Configuración
Sección titulada «Obtener Toda la Configuración»GET /_emdash/api/settingsActualizar Configuración
Sección titulada «Actualizar Configuración»POST /_emdash/api/settingsContent-Type: application/json
{ "siteTitle": "Mi sitio", "tagline": "Un gran sitio", "postsPerPage": 10}Endpoints de Menús
Sección titulada «Endpoints de Menús»Listar Menús
Sección titulada «Listar Menús»GET /_emdash/api/menusObtener Menú
Sección titulada «Obtener Menú»GET /_emdash/api/menus/:nameCrear Menú
Sección titulada «Crear Menú»POST /_emdash/api/menusContent-Type: application/json
{ "name": "footer", "label": "Footer Navigation"}Actualizar Menú
Sección titulada «Actualizar Menú»PUT /_emdash/api/menus/:nameEliminar Menú
Sección titulada «Eliminar Menú»DELETE /_emdash/api/menus/:nameAñadir Elemento de Menú
Sección titulada «Añadir Elemento de Menú»POST /_emdash/api/menus/:name/itemsContent-Type: application/json
{ "type": "page", "referenceCollection": "pages", "referenceId": "page_about", "label": "About Us"}Reordenar Elementos de Menú
Sección titulada «Reordenar Elementos de Menú»POST /_emdash/api/menus/:name/reorderContent-Type: application/json
{ "items": [ { "id": "item_1", "parentId": null, "sortOrder": 0 }, { "id": "item_2", "parentId": null, "sortOrder": 1 }, { "id": "item_3", "parentId": "item_2", "sortOrder": 0 } ]}Endpoints de Taxonomía
Sección titulada «Endpoints de Taxonomía»Listar Definiciones de Taxonomía
Sección titulada «Listar Definiciones de Taxonomía»GET /_emdash/api/taxonomiesCrear Taxonomía
Sección titulada «Crear Taxonomía»POST /_emdash/api/taxonomiesContent-Type: application/json
{ "name": "genre", "label": "Genres", "labelSingular": "Genre", "hierarchical": true, "collections": ["books", "movies"]}Listar Términos
Sección titulada «Listar Términos»GET /_emdash/api/taxonomies/:name/termsCrear Término
Sección titulada «Crear Término»POST /_emdash/api/taxonomies/:name/termsContent-Type: application/json
{ "slug": "tutorials", "label": "Tutoriales", "parentId": "term_abc", "description": "How-to guides"}Actualizar Término
Sección titulada «Actualizar Término»PUT /_emdash/api/taxonomies/:name/terms/:slugEliminar Término
Sección titulada «Eliminar Término»DELETE /_emdash/api/taxonomies/:name/terms/:slugEstablecer Términos de Entrada
Sección titulada «Establecer Términos de Entrada»POST /_emdash/api/content/:collection/:id/terms/:taxonomyContent-Type: application/json
{ "termIds": ["term_news", "term_featured"]}Endpoints de Áreas de Widgets
Sección titulada «Endpoints de Áreas de Widgets»Listar Áreas de Widgets
Sección titulada «Listar Áreas de Widgets»GET /_emdash/api/widget-areasObtener Área de Widgets
Sección titulada «Obtener Área de Widgets»GET /_emdash/api/widget-areas/:nameCrear Área de Widgets
Sección titulada «Crear Área de Widgets»POST /_emdash/api/widget-areasContent-Type: application/json
{ "name": "sidebar", "label": "Barra lateral principal", "description": "Appears on posts"}Eliminar Área de Widgets
Sección titulada «Eliminar Área de Widgets»DELETE /_emdash/api/widget-areas/:nameAñadir Widget
Sección titulada «Añadir Widget»POST /_emdash/api/widget-areas/:name/widgetsContent-Type: application/json
{ "type": "content", "title": "Acerca de", "content": [...]}Actualizar Widget
Sección titulada «Actualizar Widget»PUT /_emdash/api/widget-areas/:name/widgets/:idEliminar Widget
Sección titulada «Eliminar Widget»DELETE /_emdash/api/widget-areas/:name/widgets/:idReordenar Widgets
Sección titulada «Reordenar Widgets»POST /_emdash/api/widget-areas/:name/reorderContent-Type: application/json
{ "widgetIds": ["widget_1", "widget_2", "widget_3"]}Endpoints de Gestión de Usuarios
Sección titulada «Endpoints de Gestión de Usuarios»Listar Usuarios
Sección titulada «Listar Usuarios»GET /_emdash/api/admin/usersGET /_emdash/api/admin/users?role=40GET /_emdash/api/admin/users?search=johnObtener Usuario
Sección titulada «Obtener Usuario»GET /_emdash/api/admin/users/:idActualizar Usuario
Sección titulada «Actualizar Usuario»PATCH /_emdash/api/admin/users/:idContent-Type: application/json
{ "name": "John Doe", "role": 40}Habilitar Usuario
Sección titulada «Habilitar Usuario»POST /_emdash/api/admin/users/:id/enableDeshabilitar Usuario
Sección titulada «Deshabilitar Usuario»POST /_emdash/api/admin/users/:id/disableEndpoints de Autenticación
Sección titulada «Endpoints de Autenticación»Estado de Configuración
Sección titulada «Estado de Configuración»GET /_emdash/api/setup/statusDevuelve si la configuración está completa y si existen usuarios.
Inicio de sesión con clave de acceso
Sección titulada «Inicio de sesión con clave de acceso»POST /_emdash/api/auth/passkey/optionsObtiene las opciones de autenticación WebAuthn.
POST /_emdash/api/auth/passkey/verifyContent-Type: application/json
{ "id": "credential-id", "rawId": "...", "response": {...}, "type": "public-key"}Verifica la clave de acceso y crea una sesión.
Enlace mágico
Sección titulada «Enlace mágico»POST /_emdash/api/auth/magic-link/sendContent-Type: application/json
{ "email": "user@example.com"}GET /_emdash/api/auth/magic-link/verify?token=xxxCerrar sesión
Sección titulada «Cerrar sesión»POST /_emdash/api/auth/logoutUsuario actual
Sección titulada «Usuario actual»GET /_emdash/api/auth/meInvitar usuario
Sección titulada «Invitar usuario»POST /_emdash/api/auth/inviteContent-Type: application/json
{ "email": "newuser@example.com", "role": 30}Gestión de claves de acceso
Sección titulada «Gestión de claves de acceso»GET /_emdash/api/auth/passkeyEnumera las claves de acceso del usuario.
POST /_emdash/api/auth/passkey/register/optionsPOST /_emdash/api/auth/passkey/register/verifyRegistra una nueva clave de acceso.
PATCH /_emdash/api/auth/passkey/:idContent-Type: application/json
{ "name": "MacBook Pro"}Renombra una clave de acceso.
DELETE /_emdash/api/auth/passkey/:idElimina una clave de acceso.
Endpoints de importación
Sección titulada «Endpoints de importación»Analizar exportación de WordPress
Sección titulada «Analizar exportación de WordPress»POST /_emdash/api/import/wordpress/analyzeContent-Type: multipart/form-data
archivo: <archivo WXR>Ejecutar importación de WordPress
Sección titulada «Ejecutar importación de WordPress»POST /_emdash/api/import/wordpress/executeContent-Type: application/json
{ "analysisId": "...", "options": { "includeMedia": true, "includeTaxonomies": true, "includeMenus": true }}Limitación de tasa
Sección titulada «Limitación de tasa»Los endpoints de la API pueden estar sujetos a limitación de tasa según la configuración del despliegue. Cuando se aplica la limitación, las respuestas incluyen:
HTTP/1.1 429 Too Many RequestsRetry-After: 60La API admite CORS para solicitudes del navegador. Configura los orígenes permitidos en tu despliegue.