Référence de l'API REST

Sur cette page

EmDash expose son interface de programmation d’applications (API) prise en charge sous /_emdash/api/. Utilisez le document OpenAPI 3.1 généré pour les paramètres de requête, les corps, les schémas de réponse, les codes d’état et la génération de clients :

GET /_emdash/api/openapi.json

Le document est généré à partir des mêmes schémas Zod que ceux utilisés par l’API. Il reflète aussi la taille maximale configurée pour le téléversement de médias.

Limite du contrat public

Le document OpenAPI délimite l’API REST prise en charge. EmDash dispose aussi de routes pour son interface d’administration et les flux de protocole. Une route présente dans l’arborescence source mais absente d’OpenAPI n’est pas une opération REST prise en charge pour les clients externes.

Cette distinction s’applique aux routes de sauvegarde, d’administration des bylines, de parcours des relations, de gestion des plugins, de configuration initiale, d’importation et d’authentification. Utilisez le guide des sauvegardes pour les backups et les outils MCP byline pour la gestion des bylines prise en charge. Les points de terminaison OAuth sont des points de protocole ; découvrez-les à partir des métadonnées décrites dans la section OAuth MCP plutôt que de les traiter comme des points de terminaison REST applicatifs.

Authentification et autorisation

La plupart des opérations acceptent soit un cookie de session EmDash, soit un jeton Bearer. Envoyez un jeton d’accès personnel ou un jeton d’accès OAuth dans l’en-tête Authorization :

Authorization: Bearer $EMDASH_TOKEN

Les jetons Bearer sont limités par leurs scopes et le rôle de l’utilisateur associé. Les requêtes par session utilisent le rôle de l’utilisateur. Consultez rôles utilisateur et scopes de jeton pour le modèle d’autorisation.

GET et POST /_emdash/api/comments/{collection}/{contentId} sont publics. L’opération GET renvoie les commentaires approuvés ; l’opération POST soumet un commentaire à modération. Les autres opérations de modération de commentaires exigent une authentification.

Protection contre la falsification de requêtes intersites

Pour une requête modifiant l’état et authentifiée par un cookie de session, incluez cet en-tête :

X-EmDash-Request: 1

Les requêtes avec jeton Bearer n’exigent pas l’en-tête car elles n’utilisent pas les identifiants ambient du navigateur. Les requêtes navigateur vers une opération d’écriture publique doivent soit envoyer l’en-tête, soit avoir un Origin correspondant à l’origine publique ou de requête du site EmDash.

Enveloppes de réponse

Une réponse JSON réussie définit success à true et place le résultat propre à l’opération dans data :

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

Une erreur définit success à false et inclut un code stable lisible par machine et un message. Certaines erreurs incluent aussi des details structurés :

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

Utilisez les codes d’état et les schémas d’erreur de chaque opération OpenAPI. Les statuts courants sont 400 pour une entrée invalide, 401 pour des identifiants manquants ou invalides, 403 pour un scope ou une permission insuffisants, 404 pour une ressource absente, 409 pour un conflit d’état, 413 pour un téléversement trop volumineux, 422 lorsqu’un plugin rejette l’enregistrement, et 500 pour une défaillance interne.

Inventaire des points de terminaison

L’identifiant d’opération est stable dans le contrat généré et sert souvent de nom de méthode aux générateurs de clients OpenAPI. L’inventaire suivant est vérifié par rapport au document OpenAPI généré.

Contenu

MéthodeCheminOpérationRésumé
GET/_emdash/api/content/{collection}listContentLister les éléments de contenu
POST/_emdash/api/content/{collection}createContentCréer un élément de contenu
GET/_emdash/api/content/{collection}/{id}getContentObtenir un élément de contenu
PUT/_emdash/api/content/{collection}/{id}updateContentMettre à jour un élément de contenu
DELETE/_emdash/api/content/{collection}/{id}deleteContentSupprimer un élément de contenu (suppression logique)
POST/_emdash/api/content/{collection}/{id}/publishpublishContentPublier un élément de contenu
POST/_emdash/api/content/{collection}/{id}/unpublishunpublishContentDépublier un élément de contenu
POST/_emdash/api/content/{collection}/{id}/schedulescheduleContentPlanifier la publication future d’un contenu
DELETE/_emdash/api/content/{collection}/{id}/scheduleunscheduleContentAnnuler la publication planifiée
POST/_emdash/api/content/{collection}/{id}/duplicateduplicateContentDupliquer un élément de contenu
POST/_emdash/api/content/{collection}/{id}/restorerestoreContentRestaurer un élément de contenu depuis la corbeille
DELETE/_emdash/api/content/{collection}/{id}/permanentpermanentDeleteContentSupprimer définitivement un élément de contenu
GET/_emdash/api/content/{collection}/{id}/comparecompareContentComparer les révisions publiées et brouillon
POST/_emdash/api/content/{collection}/{id}/discard-draftdiscardDraftAbandonner les modifications du brouillon
GET/_emdash/api/content/{collection}/{id}/lockgetEntryLockLire le verrou d’édition de l’entrée
POST/_emdash/api/content/{collection}/{id}/lockacquireEntryLockPrendre ou renouveler le verrou d’édition de l’entrée
DELETE/_emdash/api/content/{collection}/{id}/lockreleaseEntryLockLibérer le verrou d’édition de l’appelant
GET/_emdash/api/content/{collection}/{id}/translationsgetContentTranslationsObtenir les traductions d’un élément de contenu
GET/_emdash/api/content/{collection}/{id}/terms/{taxonomy}getContentTermsObtenir les termes de taxonomie assignés à un élément
POST/_emdash/api/content/{collection}/{id}/terms/{taxonomy}setContentTermsDéfinir les termes de taxonomie sur un élément
GET/_emdash/api/content/{collection}/authorslistContentAuthorsLister les auteurs distincts du contenu d’une collection
GET/_emdash/api/content/{collection}/trashlistTrashedContentLister les éléments de contenu en corbeille

Médias

MéthodeCheminOpérationRésumé
GET/_emdash/api/medialistMediaLister les éléments médias
POST/_emdash/api/mediauploadMediaTéléverser un élément média
GET/_emdash/api/media/folderslistMediaFoldersLister les dossiers médias
POST/_emdash/api/media/folderscreateMediaFolderCréer un dossier média
GET/_emdash/api/media/folders/{id}getMediaFolderObtenir un dossier média
PUT/_emdash/api/media/folders/{id}updateMediaFolderMettre à jour un dossier média
DELETE/_emdash/api/media/folders/{id}deleteMediaFolderSupprimer un dossier média
GET/_emdash/api/media/{id}getMediaObtenir un élément média
PUT/_emdash/api/media/{id}updateMediaMettre à jour les métadonnées média
DELETE/_emdash/api/media/{id}deleteMediaSupprimer un élément média
GET/_emdash/api/media/{id}/usagegetMediaUsageObtenir les détails d’utilisation média
PUT/_emdash/api/media/{id}/replacereplaceMediaImageRemplacer une image média
POST/_emdash/api/admin/media-usage/repairrepairMediaUsageRéparer les index d’utilisation média
GET/_emdash/api/admin/media-usage/progressgetMediaUsageProgressObtenir la progression de l’indexation d’utilisation média
POST/_emdash/api/admin/media-usage/progressadvanceMediaUsageProgressFaire avancer l’indexation d’utilisation média
GET/_emdash/api/admin/media-usage/worklistMediaUsageWorkLister le travail durable d’utilisation média
GET/_emdash/api/admin/media-usage/activationgetMediaUsageActivationObtenir l’état d’activation de l’utilisation média
POST/_emdash/api/admin/media-usage/activationadvanceMediaUsageActivationFaire avancer l’activation de l’utilisation média
POST/_emdash/api/admin/media-usage/work/retryretryMediaUsageWorkRéessayer un travail durable d’utilisation média
GET/_emdash/api/admin/media-usage/collection-deletionslistMediaUsageCollectionDeletionsLister les suppressions durables de collections
POST/_emdash/api/admin/media-usage/collection-deletions/retryretryMediaUsageCollectionDeletionRéessayer une suppression de collection
POST/_emdash/api/media/upload-urlgetMediaUploadUrlObtenir une cible de téléversement média
POST/_emdash/api/media/{id}/confirmconfirmMediaUploadConfirmer un téléversement média
PUT/_emdash/api/media/{id}/uploaduploadPendingMediaTéléverser un fichier média en attente via EmDash

Schéma

MéthodeCheminOpérationRésumé
GET/_emdash/api/schema/block-typeslistBlockTypesLister les types de bloc
POST/_emdash/api/schema/block-typescreateBlockTypeCréer un type de bloc
GET/_emdash/api/schema/block-types/{slug}getBlockTypeObtenir un type de bloc
PUT/_emdash/api/schema/block-types/{slug}updateBlockTypeMettre à jour un type de bloc
POST/_emdash/api/schema/block-types/{slug}/versions/{version}/activateactivateBlockTypeVersionActiver une version de type de bloc
GET/_emdash/api/schema/collectionslistCollectionsLister toutes les collections
POST/_emdash/api/schema/collectionscreateCollectionCréer une collection
GET/_emdash/api/schema/collections/{slug}getCollectionObtenir une collection
PUT/_emdash/api/schema/collections/{slug}updateCollectionMettre à jour une collection
DELETE/_emdash/api/schema/collections/{slug}deleteCollectionSupprimer une collection
GET/_emdash/api/schema/collections/{slug}/fieldslistFieldsLister les champs d’une collection
POST/_emdash/api/schema/collections/{slug}/fieldscreateFieldCréer un champ
GET/_emdash/api/schema/collections/{slug}/fields/{fieldSlug}getFieldObtenir un champ
PUT/_emdash/api/schema/collections/{slug}/fields/{fieldSlug}updateFieldMettre à jour un champ
DELETE/_emdash/api/schema/collections/{slug}/fields/{fieldSlug}deleteFieldSupprimer un champ
POST/_emdash/api/schema/collections/reorderreorderCollectionsRéordonner les collections dans la barre latérale admin
POST/_emdash/api/schema/collections/{slug}/fields/reorderreorderFieldsRéordonner les champs d’une collection
GET/_emdash/api/schema/orphanslistOrphanedTablesLister les tables de contenu orphelines
POST/_emdash/api/schema/orphans/{slug}registerOrphanedTableEnregistrer une table orpheline comme collection

Commentaires

MéthodeCheminOpérationRésumé
GET/_emdash/api/comments/{collection}/{contentId}listPublicCommentsLister les commentaires approuvés du contenu
POST/_emdash/api/comments/{collection}/{contentId}createCommentSoumettre un nouveau commentaire
GET/_emdash/api/admin/commentslistAdminCommentsLister les commentaires à modérer
GET/_emdash/api/admin/comments/countsgetCommentCountsObtenir les comptages par statut de commentaire
POST/_emdash/api/admin/comments/bulkbulkCommentActionApprouver, marquer spam, corbeille ou supprimer des commentaires en lot
GET/_emdash/api/admin/comments/{id}getCommentObtenir un commentaire
DELETE/_emdash/api/admin/comments/{id}deleteCommentSupprimer définitivement un commentaire
PUT/_emdash/api/admin/comments/{id}/statusupdateCommentStatusChanger le statut d’un commentaire

Taxonomies

MéthodeCheminOpérationRésumé
GET/_emdash/api/taxonomieslistTaxonomiesLister toutes les définitions de taxonomie
GET/_emdash/api/taxonomies/{name}getTaxonomyObtenir une définition de taxonomie
PUT/_emdash/api/taxonomies/{name}updateTaxonomyMettre à jour une définition de taxonomie
DELETE/_emdash/api/taxonomies/{name}deleteTaxonomySupprimer une taxonomie, ses termes et leurs assignations au contenu
GET/_emdash/api/taxonomies/{name}/translationslistTaxonomyTranslationsLister chaque variante de locale d’une définition de taxonomie
POST/_emdash/api/taxonomies/{name}/reorderreorderTermsDéfinir l’ordre manuel d’un groupe de termes frères
GET/_emdash/api/taxonomies/{name}/termslistTermsLister les termes d’une taxonomie
POST/_emdash/api/taxonomies/{name}/termscreateTermCréer un terme
GET/_emdash/api/taxonomies/{name}/terms/{slug}getTermObtenir un terme par slug
PUT/_emdash/api/taxonomies/{name}/terms/{slug}updateTermMettre à jour un terme
DELETE/_emdash/api/taxonomies/{name}/terms/{slug}deleteTermSupprimer un terme
MéthodeCheminOpérationRésumé
GET/_emdash/api/menuslistMenusLister tous les menus avec le nombre d’éléments
POST/_emdash/api/menuscreateMenuCréer un menu
GET/_emdash/api/menus/{name}getMenuObtenir un menu avec tous ses éléments
PUT/_emdash/api/menus/{name}updateMenuMettre à jour un menu
DELETE/_emdash/api/menus/{name}deleteMenuSupprimer un menu et ses éléments
POST/_emdash/api/menus/{name}/itemscreateMenuItemAjouter un élément à un menu
PUT/_emdash/api/menus/{name}/items/{id}updateMenuItemMettre à jour un élément de menu
DELETE/_emdash/api/menus/{name}/items/{id}deleteMenuItemSupprimer un élément de menu
POST/_emdash/api/menus/{name}/reorderreorderMenuItemsRéordonner les éléments de menu par lot

Sections

MéthodeCheminOpérationRésumé
GET/_emdash/api/sectionslistSectionsLister les sections
POST/_emdash/api/sectionscreateSectionCréer une section
GET/_emdash/api/sections/{slug}getSectionObtenir une section par slug
PUT/_emdash/api/sections/{slug}updateSectionMettre à jour une section
DELETE/_emdash/api/sections/{slug}deleteSectionSupprimer une section

Widgets

MéthodeCheminOpérationRésumé
GET/_emdash/api/widget-areaslistWidgetAreasLister toutes les zones de widgets
POST/_emdash/api/widget-areascreateWidgetAreaCréer une zone de widgets
GET/_emdash/api/widget-areas/{name}getWidgetAreaObtenir une zone de widgets avec ses widgets
DELETE/_emdash/api/widget-areas/{name}deleteWidgetAreaSupprimer une zone de widgets et ses widgets
POST/_emdash/api/widget-areas/{name}/widgetscreateWidgetAjouter un widget à une zone
PUT/_emdash/api/widget-areas/{name}/widgets/{id}updateWidgetMettre à jour un widget
DELETE/_emdash/api/widget-areas/{name}/widgets/{id}deleteWidgetSupprimer un widget
POST/_emdash/api/widget-areas/{name}/reorderreorderWidgetsRéordonner les widgets dans une zone

Paramètres

MéthodeCheminOpérationRésumé
GET/_emdash/api/settingsgetSettingsObtenir les paramètres du site
PUT/_emdash/api/settingsupdateSettingsMettre à jour les paramètres du site

Recherche

MéthodeCheminOpérationRésumé
GET/_emdash/api/searchsearchRecherche full-text dans les collections
GET/_emdash/api/search/suggestsearchSuggestSuggestions de recherche en autocomplétion
POST/_emdash/api/search/rebuildrebuildSearchIndexReconstruire l’index de recherche d’une collection
POST/_emdash/api/search/enableenableSearchActiver ou désactiver la recherche pour une collection
GET/_emdash/api/search/statsgetSearchStatsObtenir les statistiques de l’index de recherche

Redirections

MéthodeCheminOpérationRésumé
GET/_emdash/api/redirectslistRedirectsLister les redirections
POST/_emdash/api/redirectscreateRedirectCréer une règle de redirection
GET/_emdash/api/redirects/{id}getRedirectObtenir une redirection
PUT/_emdash/api/redirects/{id}updateRedirectMettre à jour une redirection
DELETE/_emdash/api/redirects/{id}deleteRedirectSupprimer une redirection
GET/_emdash/api/redirects/404slistNotFoundEntriesLister les entrées du journal 404
POST/_emdash/api/redirects/404spruneNotFoundLogÉlaguer les anciennes entrées du journal 404
DELETE/_emdash/api/redirects/404sclearNotFoundLogEffacer toutes les entrées du journal 404
GET/_emdash/api/redirects/404s/summarygetNotFoundSummaryObtenir un résumé 404 groupé par chemin

Utilisateurs

MéthodeCheminOpérationRésumé
GET/_emdash/api/admin/userslistUsersLister les utilisateurs
GET/_emdash/api/admin/users/{id}getUserObtenir les détails d’un utilisateur
PUT/_emdash/api/admin/users/{id}updateUserMettre à jour un utilisateur
POST/_emdash/api/admin/users/{id}/disabledisableUserDésactiver un compte utilisateur
POST/_emdash/api/admin/users/{id}/enableenableUserActiver un compte utilisateur
GET/_emdash/api/admin/allowed-domainslistAllowedDomainsLister les domaines e-mail autorisés
POST/_emdash/api/admin/allowed-domainscreateAllowedDomainAjouter un domaine e-mail autorisé
PUT/_emdash/api/admin/allowed-domains/{domain}updateAllowedDomainMettre à jour un domaine autorisé
DELETE/_emdash/api/admin/allowed-domains/{domain}deleteAllowedDomainRetirer un domaine autorisé

Transfert

MéthodeCheminOpérationRésumé
GET/_emdash/api/admin/transfer/capabilitiesgetTransferCapabilitiesObtenir les capacités de transfert du site
GET/_emdash/api/admin/transfer/importslistTransferImportsLister les importations de site
POST/_emdash/api/admin/transfer/importscreateTransferImportCréer une importation de site
GET/_emdash/api/admin/transfer/imports/{id}getTransferImportObtenir une importation de site
GET/_emdash/api/admin/transfer/imports/{id}/missinglistTransferImportMissingFilesLister les fichiers du paquet restant à téléverser
PUT/_emdash/api/admin/transfer/imports/{id}/files/{path}uploadTransferImportFileTéléverser un fichier du paquet
POST/_emdash/api/admin/transfer/imports/{id}/analyzeanalyzeTransferImportFaire avancer l’analyse d’importation
GET/_emdash/api/admin/transfer/imports/{id}/plangetTransferImportPlanObtenir un plan d’importation
POST/_emdash/api/admin/transfer/imports/{id}/cancelcancelTransferImportAnnuler une importation de site
POST/_emdash/api/admin/transfer/imports/{id}/abandonabandonTransferImportAbandonner une importation échouée ou annulée
POST/_emdash/api/admin/transfer/imports/{id}/executeexecuteTransferImportDémarrer une importation planifiée
POST/_emdash/api/admin/transfer/imports/{id}/advanceadvanceTransferImportFaire avancer une importation en cours
GET/_emdash/api/admin/transfer/imports/{id}/receiptgetTransferImportReceiptObtenir un reçu d’importation
GET/_emdash/api/admin/transfer/exportslistTransferExportsLister les exportations de site
POST/_emdash/api/admin/transfer/exportscreateTransferExportDémarrer une exportation de site
GET/_emdash/api/admin/transfer/exports/{id}getTransferExportObtenir une exportation de site
POST/_emdash/api/admin/transfer/exports/{id}/advanceadvanceTransferExportFaire avancer une exportation de site
GET/_emdash/api/admin/transfer/exports/{id}/manifestgetTransferExportManifestTélécharger un manifeste d’exportation
GET/_emdash/api/admin/transfer/exports/{id}/files/{path}downloadTransferExportFileTélécharger un fichier d’exportation
GET/_emdash/api/admin/transfer/exports/{id}/archivedownloadTransferExportArchiveTélécharger une archive d’exportation
GET/_emdash/api/admin/transfer/approvalslistTransferApprovalsLister les approbations de transfert
POST/_emdash/api/admin/transfer/approvals/{id}/approveapproveTransferApprovalApprouver une demande de transfert
POST/_emdash/api/admin/transfer/approvals/{id}/denydenyTransferApprovalRefuser une demande de transfert

Cycle de vie du contenu et bylines

La référence du cycle de vie du contenu définit l’état, la révision, les permissions, les conflits et le comportement des hooks partagés par REST, MCP, la CLI et le panneau d’administration.

Les lectures de contenu renvoient un jeton opaque _rev lorsqu’il est disponible. Envoyez _rev avec PUT /content/{collection}/{id} pour éviter d’écraser une modification faite depuis la lecture. Un jeton obsolète produit un conflit ; relisez l’élément avant de réessayer. La CLI rend cette vérification obligatoire pour content update, tandis que le champ REST reste optionnel pour les clients qui choisissent délibérément une écriture inconditionnelle.

Lire et mettre à jour une entrée

Lisez l’entrée avant de la modifier :

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

La réponse contient ses champs, l’état de publication et le jeton de révision :

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

Envoyez uniquement les champs à modifier, avec le jeton de cette lecture :

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

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

Modifier une entrée publiée crée un brouillon tandis que la version précédente reste en ligne. Appelez l’opération de comparaison pour examiner les deux versions, puis publiez le brouillon ou abandonnez-le. Dépublier conserve le contenu et sa date de publication, annule toute planification en attente et retire l’entrée du site en ligne.

Les corps de création et de mise à jour acceptent des crédits byline, et les réponses de contenu incluent la byline principale et les crédits ordonnés. La liste de contenu peut filtrer par identifiants byline stockés et inclure optionnellement la byline inférée d’un auteur. La création et la gestion des enregistrements byline eux-mêmes passent par les outils MCP byline, pas le contrat REST public.

Les opérations du cycle de vie distinguent la suppression logique de la suppression définitive. Restaurer remet le contenu de la corbeille en brouillon sans planification ; la suppression définitive retire un élément de la corbeille et ne peut pas être annulée. Publier, dépublier, planifier, annuler la planification, comparer, abandonner le brouillon et dupliquer sont des opérations distinctes pour que les clients demandent une transition d’état à la fois.

Verrou d’édition d’entrée

Les collections peuvent prendre un verrou d’édition de sept minutes lorsqu’un éditeur ouvre une entrée. Utilisez les trois opérations sur /content/{collection}/{id}/lock pour lire, acquérir ou renouveler et libérer le bail.

Une réponse de lecture ou d’acquisition indique si le verrouillage est activé, si l’appelant détient le bail et qui le détient actuellement :

{
	"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"
		}
	}
}

Lorsqu’une collection a le verrouillage d’édition désactivé, enabled est false et aucun bail n’est pris. Acquérir à nouveau le même verrou et enregistrer l’entrée prolongent tous deux un bail détenu par l’appelant.

Le corps d’acquisition peut inclure un token opaque identifiant une session d’édition et takeover: true lorsque l’utilisateur choisit de remplacer le bail d’un autre éditeur. Passez le même token en paramètre de requête lors de la libération du verrou. Un second onglet du même compte ne pourra alors pas libérer par erreur le bail du premier.

Lorsqu’un autre utilisateur détient le bail, les écritures de contenu protégées renvoient 409 ENTRY_LOCKED. Les détails d’erreur identifient le détenteur et l’expiration. Pour outrepasser le verrou, envoyez "overrideLock": true dans le corps JSON d’une écriture avec corps, ou ?overrideLock=true pour une opération DELETE sans corps.

Sélections de référence

Un champ reference lie une entrée à des entrées d’une autre collection via une relation. Sa valeur ne fait pas partie de data et est indexée par groupe de traduction, de sorte que chaque traduction d’une entrée partage une sélection.

Les corps de création et de mise à jour portent les sélections sous references, indexées par slug de champ, chacune un tableau d’au plus 1000 identifiants d’entrée dans l’ordre d’affichage. EmDash écrit la sélection dans la même transaction que l’entrée. La mise à jour suivante remplace l’auteur de l’entrée :

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 champ lié à l’extrémité enfant de sa relation sélectionne les entrées pointant vers celle en cours d’écriture, sans ordre propre. Les limites de relation s’appliquent aux deux extrémités ; une sélection qui donnerait à une entrée liée plus de parents que la relation ne le permet est rejetée, tout comme une qui lie trop d’entrées.

Sur une collection qui conserve les révisions, une sélection modifiée sur une entrée publiée est mise en attente dans le brouillon avec les autres modifications en attente de l’entrée. Elle devient en ligne à la publication et est abandonnée avec le brouillon. La publication revérifie l’ensemble de la sélection par rapport aux limites de la relation.

Une lecture d’un seul élément renvoie references indexées par slug de champ. Chaque champ contient la première page des entrées liées, 50, avec nextCursor lorsqu’il y en a plus, et indique l’identifiant, le slug, la collection, le titre affiché, la locale résolue et le groupe de traduction de chaque entrée. Un appelant autorisé à lire les brouillons voit une sélection en attente lorsque le brouillon en porte une. L’opération de liste de contenu n’inclut pas les références.

Les définitions de relation et le parcours des liens sont des routes admin, absentes d’OpenAPI et hors du contrat public. Écrivez et lisez les sélections via les opérations de contenu ci-dessus et affichez-les sur un site avec getEmDashEntry() et getEmDashReferences().

Traductions

Le contrat REST public expose les traductions de contenu et les traductions de définitions de taxonomie. La création de contenu accepte translationOf, et la création de taxonomie utilise le même champ pour ajouter une variante de locale. Les opérations de termes de contenu renvoient des assignations sensibles à la locale.

GET /taxonomies/{name} renvoie la définition de la locale par défaut du site lorsque locale est omis, en revenant au code de locale le plus bas uniquement lorsque la locale par défaut n’a pas de définition. Une mise à jour se comporte différemment : lorsque locale est omis, elle modifie la définition au code de locale le plus bas. Passez locale pour qu’une mise à jour de taxonomie traduite atteigne la définition voulue. Si cette locale n’a pas de définition, la mise à jour renvoie NOT_FOUND au lieu de basculer vers une autre locale. L’opération de traductions renvoie chaque définition du groupe partagé et les identifiants acceptés par translationOf.

label et labelSingular appartiennent à la définition d’une locale. hierarchical et collections appartiennent à la taxonomie : chaque locale renvoie les mêmes valeurs, et une mise à jour qui envoie l’un ou l’autre le modifie pour toutes les locales. Créer une définition pour un nom qui existe déjà dans une autre locale l’ajoute à cette taxonomie, que la requête envoie translationOf ou non. La nouvelle définition reprend hierarchical et collections de la taxonomie, et une création avec des valeurs différentes renvoie VALIDATION_ERROR.

Supprimer une taxonomie retire chaque locale de sa définition, tous ses termes et toutes les assignations de ces termes au contenu. Elle ne supprime pas les entrées de contenu elles-mêmes.

L’opération de réordonnancement des termes modifie un groupe de frères. Le tableau ids peut ne contenir qu’une partie de ce groupe ; les termes listés échangent leurs positions existantes et les omis restent en place. Par exemple, réordonner [A, B, C] avec ids: ["C", "A"] produit [C, B, A]. Le réordonnancement ne change pas les relations parent, et un ordre de terme s’applique à chaque locale de son groupe de traduction.

Les routes de traduction de menus, de termes de taxonomie et de bylines ne figurent pas dans le contrat REST public. Leurs listes de traduction prises en charge sont disponibles via menu_translations, taxonomy_term_translations et byline_translations sur le serveur MCP.

Points de terminaison médias

Les opérations médias couvrent le listage, le téléversement, la mise à jour des métadonnées, le remplacement d’images, les dossiers, les informations d’utilisation et la maintenance de l’index d’utilisation. Le guide de la bibliothèque média explique le flux orienté utilisateur et la signification de la couverture d’utilisation.

Lister et inspecter les médias

GET /media prend en charge la pagination par curseur ou par pages numérotées, les filtres par type MIME et nom de fichier, les dossiers et des résumés d’utilisation optionnels. Omettez folderId pour inclure tous les dossiers, ou passez folderId=unfiled pour ne renvoyer que la bibliothèque principale. Définissez includeUsage=1 sur un listage ou une lecture d’élément pour inclure les informations d’utilisation ; toute autre valeur est invalide.

usage.count compte les lignes de contenu actives distinctes ou locales dont la source indexée actuelle référence l’élément média, plus chaque paramètre de site qui le sélectionne (logo, favicon, seo.defaultOgImage). Les références répétées dans une entrée comptent une fois, et les entrées en corbeille ne comptent pas. Le nombre n’est visible que pour les appelants autorisés à lire les brouillons ; les autres lecteurs média autorisés reçoivent count: null car le décompte pourrait révéler du contenu brouillon.

GET /media/{id}/usage renvoie les entrées de contenu référençant le média, paginées. Chaque page inclut aussi siteSettings, les paramètres de site sélectionnant l’élément média, par exemple [{ "setting": "favicon" }]. Les paramètres de site sont lus depuis les valeurs stockées à chaque requête et ne dépendent pas de l’indexation d’utilisation.

Chaque résultat d’utilisation inclut un statut de couverture :

StatutSignification
completeChaque collection enregistrée a une couverture d’utilisation à jour.
neverAucune collection enregistrée n’a terminé une réparation initiale d’utilisation.
runningUne réparation est en cours.
partialSeule une partie de l’ensemble de collections enregistrées a une couverture à jour.
failedLa couverture a échoué sur l’ensemble de collections enregistrées.
staleL’index est plus ancien que le contenu qu’il décrit.
unknownL’état stocké n’est pas reconnu par cette version d’EmDash.

Seul complete permet de traiter un décompte nul comme complet dans les types de champs indexés. Les décomptes sont indicatifs pendant les écritures concurrentes ; ils ne verrouillent pas l’élément média ni ne garantissent qu’une suppression est sûre. L’indexation d’utilisation couvre les champs image et fichier, les champs répéteur d’image, les blocs image et galerie Portable Text, et les médias déclarés par des versions de bloc conservées dans les collections EmDash. Le logo du site, le favicon et l’image sociale par défaut sont aussi signalés. L’utilisation n’inclut pas les blocs Portable Text personnalisés, le code applicatif, le HTML rendu, d’autres paramètres, les menus, les widgets, les données de plugins, les sites externes ni les actifs réservés au fournisseur.

Téléversement multipart direct

Envoyez un fichier via EmDash en le publiant comme champ file d’une requête multipart :

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

curl ajoute la limite multipart. Ne définissez pas manuellement l’en-tête Content-Type. Le schéma OpenAPI MediaDirectUploadBody liste les champs de métadonnées optionnels et les schémas de réponse distinguent un nouveau téléversement d’un élément existant dédupliqué.

Le corps multipart peut aussi inclure width et height d’image, un fieldId dont la liste de types MIME autorisés doit s’appliquer, et une thumbnail réduite pour créer un placeholder basse qualité. Un nouveau fichier renvoie 201 Created et est prêt immédiatement. Des octets identiques renvoient l’élément média existant avec 200 OK et deduplicated: true.

Flux de cible de téléversement

Utilisez le flux de cible de téléversement lorsque le client peut téléverser directement vers un stockage compatible S3. L’élément média reste en attente et n’apparaît pas dans la bibliothèque standard tant que la confirmation n’a pas réussi.

  1. Demander une cible de téléversement

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

    La réponse fournit uploadUrl, method, headers, mediaId, storageKey et une expiration. Lorsque contentHash correspond à un fichier existant de même type MIME et taille, la réponse définit existing: true ; utilisez cet élément média et ne téléversez ni ne confirmez une autre copie.

  2. Téléverser les octets

    Utilisez la méthode et les en-têtes renvoyés. Résolvez une URL relative à la racine par rapport au site EmDash et incluez le jeton Bearer. Envoyez uniquement les en-têtes de téléversement renvoyés vers une URL absolue sur une autre origine.

  3. Confirmer le téléversement

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

    La confirmation vérifie l’objet stocké et passe l’élément de pending à ready. La taille et les dimensions fournies doivent correspondre au fichier téléversé.

Le stockage local et R2 natif renvoient une cible de téléversement EmDash same-origin. Le stockage compatible S3 peut renvoyer une URL externe signée. Les éléments en attente restent hors de la liste média standard tant que la confirmation n’a pas réussi.

Erreurs de téléversement

Les erreurs suivantes exigent une action de récupération différente :

StatutCodeAction
400NO_FILEAjoutez le champ file à une requête multipart ou envoyez le corps de téléversement manquant.
400INVALID_TYPEUtilisez un type MIME autorisé correspondant à l’élément média en attente.
400VALIDATION_ERRORCorrigez les métadonnées manquantes ou invalides, y compris les valeurs au-delà de la limite de taille configurée.
400FILE_NOT_FOUNDTéléversez l’objet vers la cible renvoyée avant de confirmer.
400UPLOAD_SIZE_MISMATCHRedémarrez le flux avec la bonne taille ; les tailles déclarée, téléversée et confirmée doivent concorder.
400 or 409INVALID_STATELisez l’élément média avant de réessayer. Il peut ne plus être en attente, ou une autre requête l’a peut-être modifié pendant la confirmation.
404NOT_FOUNDUtilisez un identifiant média en attente existant.
413PAYLOAD_TOO_LARGERéduisez la taille du fichier ou augmentez maxUploadSize avant de lancer un autre téléversement.

Dossiers médias

Les noms de dossier sont rognés, limités à 200 caractères et comparés après normalisation Unicode et mise en minuscules. Des noms comme Photos, photos et PHOTOS entrent donc en conflit. Supprimer un dossier renvoie ses médias à la bibliothèque principale ; cela ne supprime pas les médias, ne change pas les identifiants ou URL média ni les enregistrements d’utilisation.

Réparer l’utilisation média

L’activation, la progression, les files de travail, le nettoyage des suppressions et la réparation de l’utilisation média sont des opérations opérateur sous /_emdash/api/admin/media-usage/. Les utilisateurs par session ont besoin de schema:manage ; les jetons Bearer ont aussi besoin du scope admin.

Si le suivi est désactivé, mettez en pause les écrivains directs de base de données avant l’activation. EmDash bloque temporairement les écritures de contenu et de schéma envoyées via ses API pendant la configuration, mais ne peut pas arrêter un autre processus écrivant directement dans la base de données.

  1. Arrêtez les écrivains directs de base de données et attendez la fin des écritures en cours.
  2. Lisez l’état d’activation. expanded signifie suivi désactivé, activating signifie qu’EmDash prépare les collections, et active signifie que les nouveaux changements de référence média sont suivis.
  3. Envoyez une requête d’activation avec { "writersDrained": true }.
  4. Envoyez les requêtes de progression une par une, en attendant chaque nextRequestInMs renvoyé, jusqu’à ce que l’activation soit active.
  5. Reprenez les écritures directes en base de données.
  6. Poursuivez les requêtes de progression jusqu’à ce que l’indexation historique soit ready et nextRequestInMs soit null.

Si une requête d’écriture expire ou renvoie 409 ou 500, lisez l’état d’activation et de progression avant de réessayer. Les lots terminés restent enregistrés. Lorsque lastErrorCode est défini, gardez les écrivains directs arrêtés, résolvez le problème signalé et envoyez une nouvelle tentative confirmée. L’activation ne peut pas être annulée ni réinitialisée après le démarrage ; testez cette procédure sur une copie de staging et conservez une sauvegarde de base de données à jour.

Les opérations de liste de travail exposent l’indexation d’entrées échouée ou retardée sans renvoyer le contenu, les références média, les jetons de bail, les erreurs brutes de base de données ni un décompte exact de backlog. Réessayer un élément est idempotent. 409 WORK_LEASE_ACTIVE signifie qu’un worker traite encore l’élément ; la réponse inclut details.leaseExpiresAt, attendez jusqu’à ce moment et relisez l’élément avant de réessayer. 409 WORK_CHANGED signifie qu’une autre requête a modifié l’élément de travail ; lisez son état actuel plutôt que d’écraser le travail plus récent.

L’opération de réparation accepte { "scope": "collection", "collection": "articles" } ou { "scope": "all" }. Une réparation de toutes les collections s’exécute de façon synchrone et séquentielle, ce qui peut prendre longtemps sur un grand site. Une réponse 200 peut quand même signaler partial, failed ou stale ; inspectez data.status, le statut par collection et les décomptes sources avant de considérer la réparation terminée.

Transfert de site

Les opérations de transfert sous /_emdash/api/admin/transfer/ exportent un site sous forme de paquet de site et en importent un dans un site vide. Le guide de transfert de site décrit le flux d’exportation, de téléversement, d’analyse, d’exécution et de reçu.

Les utilisateurs par session ont besoin de la permission transfer:export ou transfer:import, réservée aux administrateurs. Les jetons Bearer ont besoin de admin ou du scope transfer:export, transfer:analyze ou transfer:execute nommé par chaque opération. Les opérations d’approbation n’acceptent que les sessions connectées. Elles tranchent les demandes faites par les outils MCP site_export_start et site_import_start ; les opérations REST d’exportation et d’exécution ne prennent pas d’approbation.

Pendant qu’une importation s’exécute, et après échec ou annulation jusqu’à abandon, la plupart des autres opérations d’écriture renvoient 503 TRANSFER_IMPORT_IN_PROGRESS. Le guide liste les opérations qui restent disponibles.

Pagination

Les opérations de liste décrivent leurs paramètres de pagination dans OpenAPI. La plupart des opérations paginées par curseur acceptent un cursor opaque et une limit de 1 à 100, par défaut 50. Renvoyez le nextCursor de la réponse précédente tel quel ; ne l’inspectez ni ne le construisez. Certaines opérations médias prennent aussi en charge les pages numérotées, et certaines listes spécialisées utilisent des limites différentes ; les clients générés doivent suivre le schéma de chaque opération.

Tokeniseurs de recherche

L’opération d’activation de recherche stocke un tokeniseur par collection. Le modifier sur une collection avec recherche activée reconstruit l’index de cette collection.

ValeurUsage
porter unicode61Par défaut pour le contenu anglais bénéficiant du stemming Porter.
unicode61Langues utilisant des séparateurs de mots sans stemming anglais.
trigramTexte sans espaces, y compris japonais, chinois, thaï, khmer, lao et birman, ou collections nécessitant une correspondance par sous-chaîne. Les requêtes de moins de trois caractères Unicode ne renvoient aucune correspondance.

Désactiver la recherche conserve le tokeniseur stocké pour la prochaine activation. L’opération de reconstruction utilise le tokeniseur stocké et les poids de champ de la collection.

Commentaires et redirections

Les soumissions publiques de commentaires entrent dans la file de modération. Les opérations admin de commentaires listent tous les statuts, renvoient des comptages, mettent à jour un statut, modèrent en lot et suppriment définitivement un commentaire. Une réponse 429 signifie que la limite de débit de soumission a été atteinte.

Les opérations de redirection gèrent séparément les règles de redirection et le journal 404 enregistré. L’élagage retire les entrées sélectionnées par le corps de la requête, tandis que DELETE /redirects/404s efface tout le journal. Aucune de ces opérations ne supprime les règles de redirection.