Referencia de la API REST

En esta página

EmDash expone su interfaz de programación de aplicaciones (API) admitida en /_emdash/api/. Use el documento OpenAPI 3.1 generado para parámetros de solicitud, cuerpos, esquemas de respuesta, códigos de estado y generación de clientes:

GET /_emdash/api/openapi.json

El documento se genera a partir de los mismos esquemas Zod que usa la API. También refleja el tamaño máximo configurado para la subida de medios.

Límite del contrato público

El documento OpenAPI delimita la API REST admitida. EmDash también tiene rutas para su interfaz de administración y flujos de protocolo. Una ruta que existe en el árbol de código pero no aparece en OpenAPI no es una operación REST admitida para clientes externos.

Esta distinción aplica a rutas de copias de seguridad, administración de bylines, recorrido de relaciones, gestión de plugins, configuración inicial, importación y autenticación. Use la guía de copias de seguridad para backups y las herramientas MCP de bylines para la gestión de bylines admitida. Los endpoints OAuth son endpoints de protocolo; descúbralos a partir de los metadatos descritos en la sección OAuth de MCP en lugar de tratarlos como endpoints REST de aplicación.

Autenticación y autorización

La mayoría de las operaciones aceptan una cookie de sesión de EmDash o un token Bearer. Envíe un token de acceso personal o un token de acceso OAuth en el encabezado Authorization:

Authorization: Bearer $EMDASH_TOKEN

Los tokens Bearer están limitados por sus ámbitos (scopes) y el rol del usuario asociado. Las solicitudes con sesión usan el rol del usuario. Consulte roles de usuario y ámbitos de token para el modelo de autorización.

GET y POST /_emdash/api/comments/{collection}/{contentId} son públicos. La operación GET devuelve comentarios aprobados; la operación POST envía un comentario a moderación. El resto de operaciones de moderación de comentarios requieren autenticación.

Protección contra falsificación de solicitudes entre sitios

Para una solicitud que cambia estado y se autentica con una cookie de sesión, incluya este encabezado:

X-EmDash-Request: 1

Las solicitudes con token Bearer no requieren el encabezado porque no usan credenciales ambientales del navegador. Las solicitudes del navegador a una operación de escritura pública deben enviar el encabezado o tener un Origin que coincida con el origen público o de solicitud del sitio EmDash.

Envoltorios de respuesta

Una respuesta JSON correcta establece success en true y coloca el resultado específico de la operación en data:

{
	"success": true,
	"data": {
		"items": []
	}
}

Un error establece success en false e incluye un código estable legible por máquina y un mensaje. Algunos errores también incluyen details estructurados:

{
	"success": false,
	"error": {
		"code": "NOT_FOUND",
		"message": "Content item not found"
	}
}

Use los códigos de estado y los esquemas de error de cada operación OpenAPI. Los estados habituales son 400 para entrada no válida, 401 para credenciales ausentes o no válidas, 403 por ámbito o permiso insuficiente, 404 para un recurso inexistente, 409 por conflicto de estado, 413 por una subida demasiado grande, 422 cuando un plugin rechaza el guardado y 500 por un fallo interno.

Inventario de endpoints

El ID de operación es estable dentro del contrato generado y los generadores de clientes OpenAPI suelen usarlo como nombre de método. El siguiente inventario se contrasta con el documento OpenAPI generado.

Contenido

MétodoRutaOperaciónResumen
GET/_emdash/api/content/{collection}listContentListar elementos de contenido
POST/_emdash/api/content/{collection}createContentCrear un elemento de contenido
GET/_emdash/api/content/{collection}/{id}getContentObtener un elemento de contenido
PUT/_emdash/api/content/{collection}/{id}updateContentActualizar un elemento de contenido
DELETE/_emdash/api/content/{collection}/{id}deleteContentEliminar un elemento de contenido (eliminación lógica)
POST/_emdash/api/content/{collection}/{id}/publishpublishContentPublicar un elemento de contenido
POST/_emdash/api/content/{collection}/{id}/unpublishunpublishContentDespublicar un elemento de contenido
POST/_emdash/api/content/{collection}/{id}/schedulescheduleContentProgramar contenido para publicación futura
DELETE/_emdash/api/content/{collection}/{id}/scheduleunscheduleContentCancelar la publicación programada
POST/_emdash/api/content/{collection}/{id}/duplicateduplicateContentDuplicar un elemento de contenido
POST/_emdash/api/content/{collection}/{id}/restorerestoreContentRestaurar un elemento de contenido desde la papelera
DELETE/_emdash/api/content/{collection}/{id}/permanentpermanentDeleteContentEliminar permanentemente un elemento de contenido
GET/_emdash/api/content/{collection}/{id}/comparecompareContentComparar revisiones en vivo y borrador
POST/_emdash/api/content/{collection}/{id}/discard-draftdiscardDraftDescartar cambios del borrador
GET/_emdash/api/content/{collection}/{id}/lockgetEntryLockLeer el bloqueo de edición de la entrada
POST/_emdash/api/content/{collection}/{id}/lockacquireEntryLockTomar o renovar el bloqueo de edición de la entrada
DELETE/_emdash/api/content/{collection}/{id}/lockreleaseEntryLockLiberar el bloqueo de edición del llamador
GET/_emdash/api/content/{collection}/{id}/translationsgetContentTranslationsObtener traducciones de un elemento de contenido
GET/_emdash/api/content/{collection}/{id}/terms/{taxonomy}getContentTermsObtener términos de taxonomía asignados a un elemento
POST/_emdash/api/content/{collection}/{id}/terms/{taxonomy}setContentTermsEstablecer términos de taxonomía en un elemento
GET/_emdash/api/content/{collection}/authorslistContentAuthorsListar autores distintos del contenido de una collection
GET/_emdash/api/content/{collection}/trashlistTrashedContentListar elementos de contenido en la papelera

Medios

MétodoRutaOperaciónResumen
GET/_emdash/api/medialistMediaListar elementos multimedia
POST/_emdash/api/mediauploadMediaSubir un elemento multimedia
GET/_emdash/api/media/folderslistMediaFoldersListar carpetas de medios
POST/_emdash/api/media/folderscreateMediaFolderCrear una carpeta de medios
GET/_emdash/api/media/folders/{id}getMediaFolderObtener una carpeta de medios
PUT/_emdash/api/media/folders/{id}updateMediaFolderActualizar una carpeta de medios
DELETE/_emdash/api/media/folders/{id}deleteMediaFolderEliminar una carpeta de medios
GET/_emdash/api/media/{id}getMediaObtener un elemento multimedia
PUT/_emdash/api/media/{id}updateMediaActualizar metadatos de medios
DELETE/_emdash/api/media/{id}deleteMediaEliminar un elemento multimedia
GET/_emdash/api/media/{id}/usagegetMediaUsageObtener detalles de uso de medios
PUT/_emdash/api/media/{id}/replacereplaceMediaImageReemplazar una imagen multimedia
POST/_emdash/api/admin/media-usage/repairrepairMediaUsageReparar índices de uso de medios
GET/_emdash/api/admin/media-usage/progressgetMediaUsageProgressObtener progreso de indexación de uso de medios
POST/_emdash/api/admin/media-usage/progressadvanceMediaUsageProgressAvanzar la indexación de uso de medios
GET/_emdash/api/admin/media-usage/worklistMediaUsageWorkListar trabajo durable de uso de medios
GET/_emdash/api/admin/media-usage/activationgetMediaUsageActivationObtener estado de activación de uso de medios
POST/_emdash/api/admin/media-usage/activationadvanceMediaUsageActivationAvanzar la activación de uso de medios
POST/_emdash/api/admin/media-usage/work/retryretryMediaUsageWorkReintentar un trabajo durable de uso de medios
GET/_emdash/api/admin/media-usage/collection-deletionslistMediaUsageCollectionDeletionsListar eliminaciones durable de collections
POST/_emdash/api/admin/media-usage/collection-deletions/retryretryMediaUsageCollectionDeletionReintentar una eliminación de collection
POST/_emdash/api/media/upload-urlgetMediaUploadUrlObtener un destino de subida de medios
POST/_emdash/api/media/{id}/confirmconfirmMediaUploadConfirmar una subida de medios
PUT/_emdash/api/media/{id}/uploaduploadPendingMediaSubir un archivo multimedia pendiente a través de EmDash

Esquema

MétodoRutaOperaciónResumen
GET/_emdash/api/schema/block-typeslistBlockTypesListar tipos de bloque
POST/_emdash/api/schema/block-typescreateBlockTypeCrear un tipo de bloque
GET/_emdash/api/schema/block-types/{slug}getBlockTypeObtener un tipo de bloque
PUT/_emdash/api/schema/block-types/{slug}updateBlockTypeActualizar un tipo de bloque
POST/_emdash/api/schema/block-types/{slug}/versions/{version}/activateactivateBlockTypeVersionActivar una versión de tipo de bloque
GET/_emdash/api/schema/collectionslistCollectionsListar todas las collections
POST/_emdash/api/schema/collectionscreateCollectionCrear una collection
GET/_emdash/api/schema/collections/{slug}getCollectionObtener una collection
PUT/_emdash/api/schema/collections/{slug}updateCollectionActualizar una collection
DELETE/_emdash/api/schema/collections/{slug}deleteCollectionEliminar una collection
GET/_emdash/api/schema/collections/{slug}/fieldslistFieldsListar campos de una collection
POST/_emdash/api/schema/collections/{slug}/fieldscreateFieldCrear un campo
GET/_emdash/api/schema/collections/{slug}/fields/{fieldSlug}getFieldObtener un campo
PUT/_emdash/api/schema/collections/{slug}/fields/{fieldSlug}updateFieldActualizar un campo
DELETE/_emdash/api/schema/collections/{slug}/fields/{fieldSlug}deleteFieldEliminar un campo
POST/_emdash/api/schema/collections/reorderreorderCollectionsReordenar collections en la barra lateral del admin
POST/_emdash/api/schema/collections/{slug}/fields/reorderreorderFieldsReordenar campos en una collection
GET/_emdash/api/schema/orphanslistOrphanedTablesListar tablas de contenido huérfanas
POST/_emdash/api/schema/orphans/{slug}registerOrphanedTableRegistrar una tabla huérfana como collection

Comentarios

MétodoRutaOperaciónResumen
GET/_emdash/api/comments/{collection}/{contentId}listPublicCommentsListar comentarios aprobados del contenido
POST/_emdash/api/comments/{collection}/{contentId}createCommentEnviar un comentario nuevo
GET/_emdash/api/admin/commentslistAdminCommentsListar comentarios para moderación
GET/_emdash/api/admin/comments/countsgetCommentCountsObtener recuentos por estado de comentarios
POST/_emdash/api/admin/comments/bulkbulkCommentActionAprobar, marcar spam, enviar a papelera o eliminar comentarios en lote
GET/_emdash/api/admin/comments/{id}getCommentObtener un comentario
DELETE/_emdash/api/admin/comments/{id}deleteCommentEliminar permanentemente un comentario
PUT/_emdash/api/admin/comments/{id}/statusupdateCommentStatusCambiar el estado de un comentario

Taxonomías

MétodoRutaOperaciónResumen
GET/_emdash/api/taxonomieslistTaxonomiesListar todas las definiciones de taxonomía
GET/_emdash/api/taxonomies/{name}getTaxonomyObtener una definición de taxonomía
PUT/_emdash/api/taxonomies/{name}updateTaxonomyActualizar una definición de taxonomía
DELETE/_emdash/api/taxonomies/{name}deleteTaxonomyEliminar una taxonomía, sus términos y sus asignaciones al contenido
GET/_emdash/api/taxonomies/{name}/translationslistTaxonomyTranslationsListar cada variante de locale de una definición de taxonomía
POST/_emdash/api/taxonomies/{name}/reorderreorderTermsEstablecer el orden manual de un grupo de términos hermanos
GET/_emdash/api/taxonomies/{name}/termslistTermsListar términos de una taxonomía
POST/_emdash/api/taxonomies/{name}/termscreateTermCrear un término
GET/_emdash/api/taxonomies/{name}/terms/{slug}getTermObtener un término por slug
PUT/_emdash/api/taxonomies/{name}/terms/{slug}updateTermActualizar un término
DELETE/_emdash/api/taxonomies/{name}/terms/{slug}deleteTermEliminar un término

Menús

MétodoRutaOperaciónResumen
GET/_emdash/api/menuslistMenusListar todos los menús con recuento de elementos
POST/_emdash/api/menuscreateMenuCrear un menú
GET/_emdash/api/menus/{name}getMenuObtener un menú con todos sus elementos
PUT/_emdash/api/menus/{name}updateMenuActualizar un menú
DELETE/_emdash/api/menus/{name}deleteMenuEliminar un menú y sus elementos
POST/_emdash/api/menus/{name}/itemscreateMenuItemAñadir un elemento a un menú
PUT/_emdash/api/menus/{name}/items/{id}updateMenuItemActualizar un elemento de menú
DELETE/_emdash/api/menus/{name}/items/{id}deleteMenuItemEliminar un elemento de menú
POST/_emdash/api/menus/{name}/reorderreorderMenuItemsReordenar elementos de menú en lote

Secciones

MétodoRutaOperaciónResumen
GET/_emdash/api/sectionslistSectionsListar secciones
POST/_emdash/api/sectionscreateSectionCrear una sección
GET/_emdash/api/sections/{slug}getSectionObtener una sección por slug
PUT/_emdash/api/sections/{slug}updateSectionActualizar una sección
DELETE/_emdash/api/sections/{slug}deleteSectionEliminar una sección

Widgets

MétodoRutaOperaciónResumen
GET/_emdash/api/widget-areaslistWidgetAreasListar todas las áreas de widgets
POST/_emdash/api/widget-areascreateWidgetAreaCrear un área de widgets
GET/_emdash/api/widget-areas/{name}getWidgetAreaObtener un área de widgets con sus widgets
DELETE/_emdash/api/widget-areas/{name}deleteWidgetAreaEliminar un área de widgets y sus widgets
POST/_emdash/api/widget-areas/{name}/widgetscreateWidgetAñadir un widget a un área
PUT/_emdash/api/widget-areas/{name}/widgets/{id}updateWidgetActualizar un widget
DELETE/_emdash/api/widget-areas/{name}/widgets/{id}deleteWidgetEliminar un widget
POST/_emdash/api/widget-areas/{name}/reorderreorderWidgetsReordenar widgets en un área

Configuración

MétodoRutaOperaciónResumen
GET/_emdash/api/settingsgetSettingsObtener la configuración del sitio
PUT/_emdash/api/settingsupdateSettingsActualizar la configuración del sitio

Búsqueda

MétodoRutaOperaciónResumen
GET/_emdash/api/searchsearchBúsqueda de texto completo en collections
GET/_emdash/api/search/suggestsearchSuggestSugerencias de autocompletado de búsqueda
POST/_emdash/api/search/rebuildrebuildSearchIndexReconstruir el índice de búsqueda de una collection
POST/_emdash/api/search/enableenableSearchActivar o desactivar la búsqueda para una collection
GET/_emdash/api/search/statsgetSearchStatsObtener estadísticas del índice de búsqueda

Redirecciones

MétodoRutaOperaciónResumen
GET/_emdash/api/redirectslistRedirectsListar redirecciones
POST/_emdash/api/redirectscreateRedirectCrear una regla de redirección
GET/_emdash/api/redirects/{id}getRedirectObtener una redirección
PUT/_emdash/api/redirects/{id}updateRedirectActualizar una redirección
DELETE/_emdash/api/redirects/{id}deleteRedirectEliminar una redirección
GET/_emdash/api/redirects/404slistNotFoundEntriesListar entradas del registro 404
POST/_emdash/api/redirects/404spruneNotFoundLogPodar entradas antiguas del registro 404
DELETE/_emdash/api/redirects/404sclearNotFoundLogBorrar todas las entradas del registro 404
GET/_emdash/api/redirects/404s/summarygetNotFoundSummaryObtener resumen 404 agrupado por ruta

Usuarios

MétodoRutaOperaciónResumen
GET/_emdash/api/admin/userslistUsersListar usuarios
GET/_emdash/api/admin/users/{id}getUserObtener detalles de un usuario
PUT/_emdash/api/admin/users/{id}updateUserActualizar un usuario
POST/_emdash/api/admin/users/{id}/disabledisableUserDesactivar una cuenta de usuario
POST/_emdash/api/admin/users/{id}/enableenableUserActivar una cuenta de usuario
GET/_emdash/api/admin/allowed-domainslistAllowedDomainsListar dominios de correo permitidos
POST/_emdash/api/admin/allowed-domainscreateAllowedDomainAñadir un dominio de correo permitido
PUT/_emdash/api/admin/allowed-domains/{domain}updateAllowedDomainActualizar un dominio permitido
DELETE/_emdash/api/admin/allowed-domains/{domain}deleteAllowedDomainQuitar un dominio permitido

Transferencia

MétodoRutaOperaciónResumen
GET/_emdash/api/admin/transfer/capabilitiesgetTransferCapabilitiesObtener capacidades de transferencia del sitio
GET/_emdash/api/admin/transfer/importslistTransferImportsListar importaciones del sitio
POST/_emdash/api/admin/transfer/importscreateTransferImportCrear una importación del sitio
GET/_emdash/api/admin/transfer/imports/{id}getTransferImportObtener una importación del sitio
GET/_emdash/api/admin/transfer/imports/{id}/missinglistTransferImportMissingFilesListar archivos del paquete pendientes de subir
PUT/_emdash/api/admin/transfer/imports/{id}/files/{path}uploadTransferImportFileSubir un archivo del paquete
POST/_emdash/api/admin/transfer/imports/{id}/analyzeanalyzeTransferImportAvanzar el análisis de importación
GET/_emdash/api/admin/transfer/imports/{id}/plangetTransferImportPlanObtener un plan de importación
POST/_emdash/api/admin/transfer/imports/{id}/cancelcancelTransferImportCancelar una importación del sitio
POST/_emdash/api/admin/transfer/imports/{id}/abandonabandonTransferImportAbandonar una importación fallida o cancelada
POST/_emdash/api/admin/transfer/imports/{id}/executeexecuteTransferImportIniciar una importación planificada
POST/_emdash/api/admin/transfer/imports/{id}/advanceadvanceTransferImportAvanzar una importación en ejecución
GET/_emdash/api/admin/transfer/imports/{id}/receiptgetTransferImportReceiptObtener un recibo de importación
GET/_emdash/api/admin/transfer/exportslistTransferExportsListar exportaciones del sitio
POST/_emdash/api/admin/transfer/exportscreateTransferExportIniciar una exportación del sitio
GET/_emdash/api/admin/transfer/exports/{id}getTransferExportObtener una exportación del sitio
POST/_emdash/api/admin/transfer/exports/{id}/advanceadvanceTransferExportAvanzar una exportación del sitio
GET/_emdash/api/admin/transfer/exports/{id}/manifestgetTransferExportManifestDescargar un manifiesto de exportación
GET/_emdash/api/admin/transfer/exports/{id}/files/{path}downloadTransferExportFileDescargar un archivo de exportación
GET/_emdash/api/admin/transfer/exports/{id}/archivedownloadTransferExportArchiveDescargar un archivo de exportación comprimido
GET/_emdash/api/admin/transfer/approvalslistTransferApprovalsListar aprobaciones de transferencia
POST/_emdash/api/admin/transfer/approvals/{id}/approveapproveTransferApprovalAprobar una solicitud de transferencia
POST/_emdash/api/admin/transfer/approvals/{id}/denydenyTransferApprovalRechazar una solicitud de transferencia

Ciclo de vida del contenido y bylines

La referencia del ciclo de vida del contenido define el estado, la revisión, los permisos, los conflictos y el comportamiento de hooks compartidos por REST, MCP, la CLI y el panel de administración.

Las lecturas de contenido devuelven un token opaco _rev cuando está disponible. Envíe _rev con PUT /content/{collection}/{id} para evitar sobrescribir un cambio hecho desde la lectura. Un token obsoleto produce un conflicto; vuelva a leer el elemento antes de reintentar. La CLI hace obligatoria esta comprobación para content update, mientras que el campo REST sigue siendo opcional para clientes que eligen deliberadamente una escritura incondicional.

Leer y actualizar una entrada

Lea la entrada antes de modificarla:

GET /_emdash/api/content/articles/01JARTICLE0000000000000000
Authorization: Bearer $EMDASH_TOKEN

La respuesta contiene sus campos, el estado de publicación y el token de revisión:

{
	"success": true,
	"data": {
		"item": {
			"id": "01JARTICLE0000000000000000",
			"type": "articles",
			"slug": "launch-notes",
			"status": "published",
			"data": { "title": "Launch notes" }
		},
		"_rev": "opaque-revision-token"
	}
}

Envíe solo los campos que deben cambiar, junto con el token de esa lectura:

PUT /_emdash/api/content/articles/01JARTICLE0000000000000000
Authorization: Bearer $EMDASH_TOKEN
Content-Type: application/json

{
	"data": { "title": "Updated launch notes" },
	"_rev": "opaque-revision-token"
}

Al cambiar una entrada publicada se crea un borrador mientras la versión anterior sigue en vivo. Use la operación de comparación para revisar ambas versiones y luego publique el borrador o descártelo. Despublicar conserva el contenido y su fecha de publicación, cancela cualquier programación pendiente y quita la entrada del sitio en vivo.

Los cuerpos de creación y actualización aceptan créditos de byline, y las respuestas de contenido incluyen la byline principal y los créditos ordenados. La lista de contenido puede filtrar por IDs de byline almacenados e incluir opcionalmente la byline inferida de un autor. Crear y gestionar los registros de byline en sí está disponible mediante las herramientas MCP de bylines, no el contrato REST público.

Las operaciones del ciclo de vida distinguen la eliminación lógica de la eliminación permanente. Restaurar devuelve el contenido de la papelera como borrador sin programación; la eliminación permanente quita un elemento de la papelera y no se puede deshacer. Publicar, despublicar, programar, cancelar programación, comparar, descartar borrador y duplicar son operaciones separadas para que los clientes soliciten una transición de estado a la vez.

Bloqueo de edición de entradas

Las collections pueden tomar un bloqueo de edición de siete minutos cuando un editor abre una entrada. Use las tres operaciones en /content/{collection}/{id}/lock para leer, adquirir o renovar y liberar la concesión.

Una respuesta de lectura o adquisición indica si el bloqueo está activado, si el llamador tiene la concesión y quién la tiene actualmente:

{
	"success": true,
	"data": {
		"enabled": true,
		"heldByCaller": false,
		"holder": {
			"userId": "01JUSER000000000000000000",
			"userName": "Ada",
			"acquiredAt": "2026-05-01T09:12:04.117Z",
			"expiresAt": "2026-05-01T09:19:04.117Z"
		}
	}
}

Cuando una collection tiene desactivado el bloqueo de edición, enabled es false y no se toma ninguna concesión. Volver a adquirir el mismo bloqueo y guardar la entrada prolongan una concesión del llamador.

El cuerpo de adquisición puede incluir un token opaco que identifica una sesión de edición y takeover: true cuando el usuario elige reemplazar la concesión de otro editor. Pase el mismo token como parámetro de consulta al liberar el bloqueo. Una segunda pestaña de la misma cuenta no podrá liberar por error la concesión de la primera.

Cuando otro usuario tiene la concesión, las escrituras protegidas de contenido devuelven 409 ENTRY_LOCKED. Los detalles del error identifican al titular y la caducidad. Para anular el bloqueo, envíe "overrideLock": true en el cuerpo JSON de una escritura con cuerpo, o ?overrideLock=true para una operación DELETE sin cuerpo.

Selecciones de referencia

Un campo reference enlaza una entrada con entradas de otra collection mediante una relación. Su valor no forma parte de data y está indexado por grupo de traducción, de modo que cada traducción de una entrada comparte una selección.

Los cuerpos de creación y actualización llevan selecciones bajo references, indexadas por slug de campo, cada una un array de como máximo 1000 IDs de entrada en orden de visualización. EmDash escribe la selección en la misma transacción que la entrada. La siguiente actualización reemplaza el autor de la entrada:

PUT /_emdash/api/content/articles/01JARTICLE0000000000000000
Authorization: Bearer $EMDASH_TOKEN
Content-Type: application/json

{
	"data": { "title": "Updated launch notes" },
	"references": { "author": ["01JAUTHOR00000000000000000"] },
	"_rev": "opaque-revision-token"
}

Un campo ligado al extremo hijo de su relación selecciona las entradas que apuntan a la que se escribe, sin orden propio. Los límites de relación se aplican en ambos extremos; se rechaza una selección que daría a una entrada enlazada más padres de los que permite la relación, igual que una que enlaza demasiadas entradas.

En una collection que conserva revisiones, una selección cambiada en una entrada publicada se prepara en el borrador con el resto de cambios pendientes. Pasa a estar en vivo al publicar la entrada y se descarta con el borrador. Al publicar se vuelve a comprobar toda la selección frente a los límites de la relación.

Una lectura de un solo elemento devuelve references indexadas por slug de campo. Cada campo contiene la primera página de entradas enlazadas, 50, con nextCursor cuando hay más, e informa del ID, slug, collection, título mostrado, locale resuelto y grupo de traducción de cada entrada. Un llamador autorizado a leer borradores ve una selección preparada cuando el borrador la lleva. La operación de listado de contenido no incluye referencias.

Las definiciones de relación y el recorrido de enlaces son rutas de administración, ausentes de OpenAPI y fuera del contrato público. Escriba y lea selecciones mediante las operaciones de contenido anteriores y muéstrelas en un sitio con getEmDashEntry() y getEmDashReferences().

Traducciones

El contrato REST público expone traducciones de contenido y traducciones de definiciones de taxonomía. La creación de contenido acepta translationOf, y la creación de taxonomías usa el mismo campo para añadir una variante de locale. Las operaciones de términos de contenido devuelven asignaciones conscientes del locale.

GET /taxonomies/{name} devuelve la definición del locale predeterminado del sitio cuando se omite locale, recurriendo al código de locale más bajo solo cuando el locale predeterminado no tiene definición. Una actualización se comporta distinto: cuando se omite locale, cambia la definición con el código de locale más bajo. Pase locale para que una actualización de taxonomía traducida alcance la definición prevista. Si ese locale no tiene definición, la actualización devuelve NOT_FOUND en lugar de recurrir a otro locale. La operación de traducciones devuelve cada definición del grupo compartido y los IDs aceptados por translationOf.

label y labelSingular pertenecen a la definición de un locale. hierarchical y collections pertenecen a la taxonomía: cada locale devuelve los mismos valores, y una actualización que envía cualquiera de ellos lo cambia para todos los locales. Crear una definición para un nombre que ya existe en otro locale la añade a esa taxonomía, haya o no translationOf en la solicitud. La nueva definición toma hierarchical y collections de la taxonomía, y una creación con valores distintos devuelve VALIDATION_ERROR.

Eliminar una taxonomía quita cada locale de su definición, todos sus términos y todas las asignaciones de esos términos al contenido. No elimina las entradas de contenido en sí.

La operación de reordenación de términos cambia un grupo de hermanos. El array ids puede contener solo parte de ese grupo; los términos listados intercambian sus posiciones existentes y los omitidos permanecen donde están. Por ejemplo, reordenar [A, B, C] con ids: ["C", "A"] produce [C, B, A]. Reordenar no cambia relaciones padre, y un orden de términos aplica en cada locale de su grupo de traducción.

Las rutas de traducción de menús, términos de taxonomía y bylines no están en el contrato REST público. Sus listados de traducción admitidos están disponibles mediante menu_translations, taxonomy_term_translations y byline_translations en el servidor MCP.

Endpoints de medios

Las operaciones de medios cubren listado, subida, actualización de metadatos, reemplazo de imágenes, carpetas, información de uso y mantenimiento del índice de uso. La guía de biblioteca de medios explica el flujo orientado al usuario y el significado de la cobertura de uso.

Listar e inspeccionar medios

GET /media admite paginación por cursor o por páginas numeradas, filtros por tipo MIME y nombre de archivo, carpetas y resúmenes de uso opcionales. Omita folderId para incluir todas las carpetas, o pase folderId=unfiled para devolver solo la biblioteca principal. Establezca includeUsage=1 en un listado o lectura de un elemento para incluir información de uso; cualquier otro valor no es válido.

usage.count cuenta filas de contenido activas distintas o locales cuya fuente indexada actual referencia el elemento multimedia, más cada configuración del sitio que lo selecciona (logo, favicon, seo.defaultOgImage). Las referencias repetidas en una entrada cuentan una vez, y las entradas en la papelera no cuentan. El número solo es visible para llamadores que pueden leer borradores; otros lectores autorizados de medios reciben count: null porque el recuento podría revelar contenido en borrador.

GET /media/{id}/usage devuelve las entradas de contenido que referencian el medio, paginadas. Cada página incluye también siteSettings, la configuración del sitio que selecciona el elemento multimedia, por ejemplo [{ "setting": "favicon" }]. La configuración del sitio se lee de los valores almacenados en cada solicitud y no depende de la indexación de uso.

Cada resultado de uso incluye un estado de cobertura:

EstadoSignificado
completeCada collection registrada tiene cobertura de uso actual.
neverNinguna collection registrada ha completado una reparación inicial de uso.
runningHay una reparación en curso.
partialSolo parte del conjunto de collections registradas tiene cobertura actual.
failedLa cobertura falló en el conjunto de collections registradas.
staleEl índice es más antiguo que el contenido que describe.
unknownEl estado almacenado no es reconocido por esta versión de EmDash.

Solo complete permite tratar un recuento cero como completo dentro de los tipos de campo indexados. Los recuentos son orientativos durante escrituras concurrentes; no bloquean el elemento multimedia ni garantizan que la eliminación sea segura. La indexación de uso cubre campos de imagen y archivo, campos repetidor de imagen, bloques de imagen y galería de Portable Text, y medios declarados por versiones de bloque retenidas en collections de EmDash. También se informan el logo del sitio, el favicon y la imagen social predeterminada. El uso no incluye bloques Portable Text personalizados, código de aplicación, HTML renderizado, otras configuraciones, menús, widgets, datos de plugins, sitios externos ni activos solo del proveedor.

Subida multipart directa

Envíe un archivo a través de EmDash publicándolo como campo file de una solicitud multipart:

curl --request POST \
	--header "Authorization: Bearer $EMDASH_TOKEN" \
	--form "file=@./cover.jpg;type=image/jpeg" \
	https://example.com/_emdash/api/media

curl añade el límite multipart. No establezca manualmente el encabezado Content-Type. El esquema OpenAPI MediaDirectUploadBody enumera los campos de metadatos opcionales y los esquemas de respuesta distinguen una subida nueva de un elemento existente deduplicado.

El cuerpo multipart también puede incluir width y height de imagen, un fieldId cuya lista de tipos MIME permitidos debe aplicarse y una thumbnail reducida para crear un marcador de posición de baja calidad. Un archivo nuevo devuelve 201 Created y está listo de inmediato. Bytes idénticos devuelven el elemento multimedia existente con 200 OK y deduplicated: true.

Flujo de destino de subida

Use el flujo de destino de subida cuando el cliente pueda subir directamente a almacenamiento compatible con S3. El elemento multimedia permanece pendiente y no aparece en la biblioteca estándar hasta que la confirmación tenga éxito.

  1. Solicitar un destino de subida

    POST /_emdash/api/media/upload-url
    Authorization: Bearer $EMDASH_TOKEN
    Content-Type: application/json
    
    {
    	"filename": "cover.jpg",
    	"contentType": "image/jpeg",
    	"size": 102400
    }

    La respuesta proporciona uploadUrl, method, headers, mediaId, storageKey y una caducidad. Cuando contentHash coincide con un archivo existente del mismo tipo MIME y tamaño, la respuesta establece existing: true; use ese elemento multimedia y no suba ni confirme otra copia.

  2. Subir los bytes

    Use el método y los encabezados devueltos. Resuelva una URL relativa a la raíz frente al sitio EmDash e incluya el token Bearer. Envíe solo los encabezados de subida devueltos a una URL absoluta en otro origen.

  3. Confirmar la subida

    POST /_emdash/api/media/01JMEDIA000000000000000000/confirm
    Authorization: Bearer $EMDASH_TOKEN
    Content-Type: application/json
    
    {
    	"size": 102400,
    	"width": 1920,
    	"height": 1080
    }

    La confirmación verifica el objeto almacenado y cambia el elemento de pending a ready. El tamaño y las dimensiones indicados deben coincidir con el archivo subido.

El almacenamiento local y R2 nativo devuelven un destino de subida EmDash del mismo origen. El almacenamiento compatible con S3 puede devolver una URL externa firmada. Los elementos pendientes quedan fuera del listado estándar de medios hasta que la confirmación tenga éxito.

Errores de subida

Los siguientes errores requieren una acción de recuperación distinta:

EstadoCódigoAcción
400NO_FILEAñada el campo file a una solicitud multipart o envíe el cuerpo de subida faltante.
400INVALID_TYPEUse un tipo MIME permitido que coincida con el elemento multimedia pendiente.
400VALIDATION_ERRORCorrija metadatos faltantes o no válidos, incluidos valores por encima del límite de tamaño configurado.
400FILE_NOT_FOUNDSuba el objeto al destino devuelto antes de confirmarlo.
400UPLOAD_SIZE_MISMATCHReinicie el flujo con el tamaño correcto; los tamaños declarado, subido y confirmado deben coincidir.
400 or 409INVALID_STATELea el elemento multimedia antes de reintentar. Puede que ya no esté pendiente, u otra solicitud pudo haberlo cambiado durante la confirmación.
404NOT_FOUNDUse un ID de medio pendiente existente.
413PAYLOAD_TOO_LARGEReduzca el tamaño del archivo o aumente maxUploadSize antes de iniciar otra subida.

Carpetas de medios

Los nombres de carpeta se recortan, limitan a 200 caracteres y se comparan tras normalización Unicode y minúsculas. Nombres como Photos, photos y PHOTOS entran en conflicto. Eliminar una carpeta devuelve sus medios a la biblioteca principal; no elimina medios, no cambia IDs ni URLs de medios ni registros de uso.

Reparar uso de medios

La activación, el progreso, las colas de trabajo, la limpieza de eliminaciones y la reparación del uso de medios son operaciones de operador bajo /_emdash/api/admin/media-usage/. Los usuarios con sesión necesitan schema:manage; los tokens Bearer también necesitan el ámbito admin.

Si el seguimiento está desactivado, pause los escritores directos de base de datos antes de la activación. EmDash bloquea temporalmente escrituras de contenido y esquema enviadas por sus API durante la configuración, pero no puede detener otro proceso que escriba directamente en la base de datos.

  1. Detenga los escritores directos de base de datos y espere a que terminen las escrituras en curso.
  2. Lea el estado de activación. expanded significa seguimiento desactivado, activating significa que EmDash prepara collections, y active significa que se rastrean los cambios de referencia de medios nuevos.
  3. Envíe una solicitud de activación con { "writersDrained": true }.
  4. Envíe solicitudes de progreso de una en una, esperando cada nextRequestInMs devuelto, hasta que la activación sea active.
  5. Reanude las escrituras directas en la base de datos.
  6. Continúe las solicitudes de progreso hasta que la indexación histórica sea ready y nextRequestInMs sea null.

Si una solicitud de escritura agota el tiempo o devuelve 409 o 500, lea el estado de activación y progreso antes de reintentar. Los lotes completados siguen registrados. Cuando lastErrorCode está establecido, mantenga detenidos los escritores directos, resuelva el problema indicado y envíe un reintento confirmado. La activación no se puede cancelar ni restablecer después de iniciarse; pruebe este procedimiento en una copia de staging y mantenga una copia de seguridad actual de la base de datos.

Las operaciones de listado de trabajo exponen indexación de entradas fallida o retrasada sin devolver contenido, referencias de medios, tokens de concesión, errores crudos de base de datos ni un recuento exacto de backlog. Reintentar un elemento es idempotente. 409 WORK_LEASE_ACTIVE significa que un worker sigue procesando el elemento; la respuesta incluye details.leaseExpiresAt, así que espere hasta ese momento y vuelva a leer el elemento antes de reintentar. 409 WORK_CHANGED significa que otra solicitud cambió el elemento de trabajo; lea su estado actual en lugar de sobrescribir el trabajo más reciente.

La operación de reparación acepta { "scope": "collection", "collection": "articles" } o { "scope": "all" }. Una reparación de todas las collections se ejecuta de forma síncrona y secuencial, por lo que puede tardar mucho en un sitio grande. Una respuesta 200 aún puede informar partial, failed o stale; inspeccione data.status, el estado por collection y los recuentos de origen antes de considerar completa la reparación.

Transferencia del sitio

Las operaciones de transferencia bajo /_emdash/api/admin/transfer/ exportan un sitio como paquete del sitio e importan uno en un sitio vacío. La guía de transferencia del sitio describe el flujo de exportación, subida, análisis, ejecución y recibo.

Los usuarios con sesión necesitan el permiso transfer:export o transfer:import, que solo tienen los administradores. Los tokens Bearer necesitan admin o el ámbito transfer:export, transfer:analyze o transfer:execute que indique cada operación. Las operaciones de aprobación aceptan solo sesiones iniciadas. Deciden solicitudes hechas por las herramientas MCP site_export_start y site_import_start; las operaciones REST de exportación y ejecución no requieren aprobación.

Mientras una importación se ejecuta, y tras fallar o cancelarse hasta que se abandone, la mayoría de las demás operaciones de escritura devuelven 503 TRANSFER_IMPORT_IN_PROGRESS. La guía enumera las operaciones que siguen disponibles.

Paginación

Las operaciones de listado describen sus parámetros de paginación en OpenAPI. La mayoría de operaciones paginadas por cursor aceptan un cursor opaco y un limit de 1 a 100, con valor predeterminado 50. Devuelva el nextCursor de la respuesta anterior sin modificar; no lo inspeccione ni lo construya. Algunas operaciones de medios también admiten páginas numeradas, y algunos listados especializados usan límites distintos, así que los clientes generados deben seguir el esquema de cada operación.

Tokenizadores de búsqueda

La operación de activación de búsqueda almacena un tokenizador por collection. Cambiarlo en una collection con búsqueda activada reconstruye el índice de esa collection.

ValorUso
porter unicode61Predeterminado para contenido en inglés que se beneficia del stemming Porter.
unicode61Idiomas que usan separadores de palabras pero no deben usar stemming inglés.
trigramTexto sin espacios, incluidos japonés, chino, tailandés, jemer, lao y birmano, o collections que necesitan coincidencia por subcadena. Las consultas de menos de tres caracteres Unicode no devuelven coincidencias.

Desactivar la búsqueda conserva el tokenizador almacenado para la próxima activación. La operación de reconstrucción usa el tokenizador almacenado y los pesos de campo de la collection.

Comentarios y redirecciones

Los envíos públicos de comentarios entran en la cola de moderación. Las operaciones de comentarios de administración listan todos los estados, devuelven recuentos, actualizan un estado, realizan moderación en lote y eliminan permanentemente un comentario. Una respuesta 429 significa que se alcanzó el límite de velocidad de envío.

Las operaciones de redirección gestionan reglas de redirección y el registro 404 por separado. Podar elimina entradas seleccionadas por el cuerpo de la solicitud, mientras que DELETE /redirects/404s borra todo el registro. Ninguna de las operaciones elimina reglas de redirección.