Internal Content API
Accès IA délégué par l'utilisateur
Les utilisateurs du CMS peuvent créer des jetons API personnels expirant à partir de leur profil. Un jeton personnel s'authentifie en tant qu'utilisateur propriétaire et est autorisé par l'intersection des capacités du jeton, des sites sélectionnés, du rôle actuel du propriétaire, des attributions de sites actuelles et du flux de travail de contenu normal. Il devient immédiatement inutilisable lorsque le propriétaire est inactif ou n'a plus accès au CMS.
Les jetons personnels sont destinés au contenu, à la navigation, aux Shared Slot, aux médias, à l'engagement et aux brouillons de flux de travail. Les opérations au niveau de l'installation restent uniquement un jeton système. Les demandes d'écriture personnelles qui créent ou sélectionnent du contenu doivent fournir le site cible plutôt que de s'appuyer sur le site de secours du site principal de l'installation. L'activité de l'API continue d'enregistrer le jeton, tandis que les acteurs d'audit de page et de révision se résolvent en faveur de l'utilisateur délégant.
Chaque jeton personnel peut également comporter une liste autorisée facultative d'adresses IPv4/IPv6 exactes ou de réseaux CIDR et son propre plafond de 30, 60, 120 ou 300 requêtes par minute. Une liste de réseaux vide autorise n'importe quelle adresse client, préservant le comportement du jeton existant ; les jetons sans plafond stocké utilisent 60 requêtes par minute. Ces contraintes actives sont incluses dans la découverte authentifiée sous token.network_policy, et une limite spécifique au jeton peut donc être inférieure à la limitation de l'API à l'échelle de l'installation.
Objectif
Le Internal Content API est un CMS sécurisé API pour les outils d'IA et d'opérateur fiables. Il permet à ces outils d'inspecter les contrats de contenu CMS, de créer du contenu en premier brouillon, de remplacer des emplacements spécifiques appartenant à des pages sur des pages de brouillon existantes, d'exécuter des opérations de publication explicites via JSON structuré et de demander des instantanés de rendu d'administrateur sur liste autorisée pour le contrôle qualité visuel sans se connecter, supprimer ou automatiser l'interface utilisateur de l'administrateur du navigateur.
Phase 1 est implémenté en tant que API non public, protégé par jeton, JSON uniquement, pour la découverte de contenu en lecture seule et la création de brouillons de pages via des plans de contenu validés. La phase 2A ajoute des bases sûres pour les menus de navigation, Shared Slots et l'affectation explicite des emplacements de page Shared Slot. La phase 2B ajoute un remplacement contrôlé du brouillon uniquement pour le contenu des emplacements appartenant à la page sur les pages existantes. Les points de terminaison de publication sont explicites et nécessitent content.publish ; le contenu appliqué reste à l’état de brouillon et n’est pas publié. Le API reste intentionnellement étroit : pas de récupération à distance, pas de suppression de page large via l'application de contenu, pas de remplacement des emplacements sauvegardés sur Shared Slot et pas de publication en cascade Shared Slot.
Positionnement produit
L'Internal Content API est :
- une API CMS interne, destinée aux opérateurs
- protégée par token
- non publique
- pas une API de diffusion de CMS headless
- pas un substitut aux permissions d'administration
- pas un substitut à l'import/export
- pas une intégration avec un fournisseur d'IA
Le cœur du CMS doit être propriétaire de cette API, car elle porte sur des concepts de contenu du cœur : sites, pages, layouts, slots, blocs, traductions, navigation et shared slots. Les outils d'IA ou d'opérateur peuvent appeler l'API, mais le cœur du CMS ne doit pas embarquer de logique d'intégration OpenAI, LLM, crawler ou propre à un fournisseur.
Préfixe de route
Le préfixe canonique est :
/webadmin/api
Cela maintient le API à l'intérieur des limites d'administration du CMS tout en utilisant un segment API concis et familier. Les points de terminaison de type ressource doivent résider directement sous ce préfixe, tels que /webadmin/api/pages et /webadmin/api/blocks.
.
Avant de planifier le contenu, lisez le package CMS Inventory avec GET /webadmin/api/inventory. Il s’agit du contrat de conception et de création par bloc et c’est le premier document qu’une IA doit lire. Le bloc html est réservé aux humains : il reste lisible via le API, mais chaque mutation API le touchant est rejetée avec 422 et le code stable block_type_not_api_writable, et aucune fonctionnalité ne remplace cela. Pour un bloc application, découvrez d'abord une définition prête et son schéma de paramètres via GET /webadmin/api/applications ; Les écritures API peuvent faire référence à des applications enregistrées mais ne peuvent pas introduire de code exécutable ou de chemins de fichiers.
La découverte
API commence à :
GET /webadmin/api
Les appelants non authentifiés reçoivent uniquement le bootstrap sécurisé public JSON. Les appelants authentifiés reçoivent des métadonnées sécurisées de la version du produit ainsi que des liens vers OpenAPI, le guide de l'IA, le contrat de contenu, des exemples, la validation/l'application du contenu, les pages, les blocs, les médias, la navigation et Shared Slots. Les outils d'IA/opérateur externes doivent démarrer à partir de cette réponse de découverte en direct au lieu de lire le référentiel CMS ou la documentation du package local.
Utilisation des opérations de contenu basées sur un plan :
POST /webadmin/api/content/validate
POST /webadmin/api/content/apply
Choix de routes à éviter :
/webadmin/internal-api, parce que c'est inutilement verbeux/webadmin/api/content-plans/..., parce quecontent-plansest trop technique et trop étroit pour le contrat d'URL- placer toutes les ressources sous
/webadmin/api/content/..., parce que les API de ressource doivent rester claires et directes /admin, parce que le CMS ne doit pas supposer que le chemin/admindu produit hôte lui appartient/cms, parce que/cmsreste réservé aux seuls assets statiques du CMS
Authentification
L'API utilise l'authentification par token Bearer :
Authorization: Bearer <token>
Le CMS comporte deux surfaces de jetons. Les éditeurs, les administrateurs de site et les super-administrateurs créent des jetons API personnels à partir de Profile -> Personal API Tokens ; ces jetons agissent en tant que propriétaires dans les limites du rôle réel, du site, du flux de travail, du réseau et des capacités. Les super administrateurs créent des jetons système API à partir de System -> API Tokens pour une automatisation explicitement autorisée au niveau de l'installation. Le CMS stocke uniquement un hachage SHA-256 ainsi qu'un aperçu sécurisé dans la table de base de données cms_api_tokens. Le jeton brut est affiché une fois immédiatement après sa création et n'est plus jamais affiché.
Le panneau de jeton unique fournit des contrôles de copie pour le jeton complet et l'exemple .env local généré. Les commentaires sur la copie sont annoncés de manière accessible et la mise en œuvre du navigateur inclut une solution de secours pour les environnements sans le Presse-papiers moderne API.
Tokens créés avec l'ancien ensemble de fonctionnalités de création de pages par défaut sont traités comme éligibles pour la fonctionnalité admin.render en lecture seule au moment de l'exécution, de sorte que les outils d'opérateur de confiance peuvent utiliser des instantanés visuels d'assurance qualité de l'administrateur sur liste autorisée après la mise à jour sans faire pivoter le jeton. Les jetons personnalisés restreints qui n'incluent pas l'ancien ensemble par défaut restent restreints.
Les deux écrans de jetons incluent une action historique pour chaque jeton. Il ouvre un modal WebBlocks UI avec les 10 derniers enregistrements d'activité API pour ce jeton. Les enregistrements d'activité sont intentionnellement petits : heure de la demande, statut, méthode, chemin sans chaîne de requête, nom de la route, capacité requise lors de l'évaluation d'une protection de capacité, adresse IP et valeur courte de l'agent utilisateur. Le CMS ne stocke pas les corps de requête, les chaînes de requête, les corps de réponse, les valeurs de jeton de porteur, les hachages de jetons ou les aperçus de jetons dans les lignes d'activité. Les lignes d'activité plus anciennes sont automatiquement supprimées afin que chaque jeton ne conserve que les 10 derniers enregistrements.
Les utilisateurs peuvent modifier, révoquer et supprimer leurs propres jetons personnels ; Les super administrateurs gèrent les jetons système. La modification modifie les métadonnées de la stratégie sans révéler le secret. La révocation désactive immédiatement l'accès à API tout en conservant la ligne d'audit. La suppression d'un jeton le supprime définitivement ainsi que son historique d'activité.
Les outils locaux d'IA et d'opérateur doivent stocker le jeton généré dans un magasin secret d'opérateur de confiance.
Utilisez l'URL de base Internal Content API dans la configuration de l'opérateur local :
WEBBLOCKS_CMS_API_URL=https://example.com/webadmin/api
WEBBLOCKS_CMS_API_TOKEN=...
Le runtime CMS ne nécessite pas WEBBLOCKS_CMS_INTERNAL_API_TOKEN.
Règles d'authentification :
- les jetons manquants, erronés ou révoqués renvoient JSON
401 - les jetons révoqués cessent de fonctionner immédiatement
- les jetons ne doivent jamais être imprimés dans les journaux, les diagnostics et le support rapports, tests ou exemples de documentation
- la comparaison de jetons doit utiliser une comparaison à temps constant
- les requêtes API réussies mettent à jour les
last_used_atetlast_used_ip - du jeton
- Les requêtes API réussies stockent également un agent utilisateur tronqué pour le contexte d'audit de l'opérateur
- les réponses de ressources normales et toutes les erreurs sont JSON ; Les routes d'assurance qualité visuelles sur liste autorisée peuvent renvoyer un HTML direct uniquement lorsque l'appelant demande explicitement un format HTML
Exemple de demande :
GET /webadmin/api/sites
Authorization: Bearer <token>
Accept: application/json
Content-Type: application/json
Capacités
Les propriétaires de jetons choisissent les fonctionnalités lors de la création ou de la modification d'un jeton personnel ; Les super administrateurs font de même pour les jetons système. La modification n’expose ni ne fait pivoter le secret. Un formulaire de jeton personnel affiche uniquement les capacités que le rôle actuel du propriétaire peut déléguer, et chaque demande revérifie ce rôle actif. La découverte expose les fonctionnalités efficaces sans renvoyer la valeur du jeton, le hachage du jeton ou l'aperçu du jeton. Les jetons de création de page standard utilisent ces fonctionnalités :
content.readcontent.validatecontent.applynavigation.writeshared-slots.writemedia.readsite-settings.write
Les capacités avancées sont des options distinctes et ne sont pas sélectionnées par défaut :
Les points de terminaison
navigation.deleteshared-slots.deletedomains.writedomains.deletesite-assets.readsite-assets.writeengagement.readengagement.moderateplugins.readplugins.installplugins.manageplugins.setupplugins.uninstallcommerce.readcommerce.products.writecommerce.orders.readmedia.writemedia.uploadmedia.replacemedia.movemedia.deletecontent.publishpages.deletecontent.blocks.deletebackups.createpage-assets.write
Write vérifient la fonctionnalité appropriée côté serveur. Les fonctionnalités manquantes renvoient JSON 403 avec les conseils api_discovery_url, openapi_url, documentation_url et example_url. Les jetons de création de page normaux ne doivent pas inclure de fonctionnalités destructrices telles que la suppression de la navigation, la suppression de Shared Slot, la publication de contenu, l'installation/la gestion/la configuration/la désinstallation de plugins ou la suppression de page. La lecture des commentaires/évaluations nécessite un engagement.read explicite ; la modification du statut du commentaire nécessite un engagement.moderate explicite. L'automatisation du cycle de vie du plug-in nécessite des fonctionnalités de plug-in explicites, et l'accès au produit/commande WebBlocks Commerce API nécessite des fonctionnalités de commerce explicites.
Limite de débit
Chaque itinéraire /webadmin/api et les anciens itinéraires /admin-api partagent deux budgets de requête. Le budget par client-IP et jeton est par défaut de 120 requêtes par minute (CMS_INTERNAL_API_RATE_LIMIT_PER_MINUTE). Un backstop IP indépendant est défini par défaut sur 300 requêtes par minute sur tous les jetons fournis et les chemins API (CMS_INTERNAL_API_IP_RATE_LIMIT_PER_MINUTE), y compris les tentatives de jetons non valides. La rotation des jetons ne réinitialise pas ce filet de sécurité. Le dépassement de l’un ou l’autre budget renvoie 429 avec un en-tête Retry-After. Les valeurs de configuration non positives reviennent aux valeurs par défaut.
Lire les budgets en direct de x-rate-limit sur GET /webadmin/api/openapi.json : requests_per_minute est le budget jeton et IP et ip_requests_per_minute est le budget IP indépendant. Les clients partageant une adresse IP doivent coordonner leur volume de demandes combiné.
Un super administrateur actif peut remplacer les deux budgets sous Système → Paramètres → Sécurité. Les valeurs du panneau basées sur la base de données ont priorité sur la configuration de l'installation et s'appliquent aux demandes ultérieures sans réinitialiser les compteurs existants. Utiliser les paramètres d'installation par défaut supprime les remplacements de sécurité et restaure les budgets configurés. L'enregistrement ou la restauration ne modifie pas le .env ou les paramètres du serveur. Les budgets de demande acceptent des entiers positifs jusqu’à 1 000 000. Les limites spécifiques aux jetons personnels restent des limites supplémentaires ; les modifier ne modifie pas ces budgets API partagés.
Les couches d'hébergement, proxy ou CDN devant le site peuvent imposer une limite inférieure à celle du CMS. Par conséquent, un client en masse tel qu'une traduction de l'ensemble du site doit suivre son rythme et reculer sur 429 au lieu de réessayer immédiatement.
Les jetons personnels comportent en outre un plafond configurable de 30, 60, 120 ou 300 requêtes par minute ; les jetons personnels existants sans valeur enregistrée en utilisent 60. Ils peuvent également restreindre l'accès aux adresses IPv4/IPv6 exactes ou aux réseaux CIDR. La découverte authentifiée signale ces paramètres sous token.network_policy. L'adresse IP client résolue de Laravel fait autorité, de sorte que les hôtes derrière un proxy inverse ou un CDN doivent faire confiance uniquement à leurs véritables adresses proxy et aux en-têtes transférés avant de s'appuyer sur la liste autorisée.
Modèle de l'API
L'API comporte deux modes complémentaires.
API de ressources
Les endpoints de ressource reflètent les opérations équivalentes de l'administration, une par une :
- lister et lire les pages
- lister et lire les blocs
- lister les sites, les langues (locales), les layouts et les types de bloc
- plus tard, créer ou mettre à jour directement des ressources de page en brouillon
- plus tard, lister ou garantir les slots de page
- plus tard, ajouter, mettre à jour, déplacer et supprimer des blocs via des endpoints de ressource
- plus tard, ajouter des blocs enfants via des endpoints de ressource
- plus tard, gérer la navigation et les shared slots
Endpoints de ressource de la phase 1 :
GET /webadmin/api/sites
GET /webadmin/api/locales
GET /webadmin/api/locale-options
POST /webadmin/api/locales
PATCH /webadmin/api/locales/{locale}
GET /webadmin/api/page-layouts
GET /webadmin/api/block-types
GET /webadmin/api/content-contract
GET /webadmin/api/pages
GET /webadmin/api/pages/{page}
GET /webadmin/api/pages/{page}/versions
GET /webadmin/api/pages/{page}/versions/{version}
POST /webadmin/api/pages/{page}/versions/{version}/candidate
POST /webadmin/api/pages/{page}/version-candidates/{candidate}/apply
DELETE /webadmin/api/pages/{page}/version-candidates/{candidate}
POST /webadmin/api/pages/{page}/publish
POST /webadmin/api/pages/{page}/publish-page-owned-blocks
POST /webadmin/api/pages/{page}/slots/{slot}/shared-slot
PUT /webadmin/api/pages/{page}/slots/{slot}/source
GET /webadmin/api/pages/{page}/assets
POST /webadmin/api/pages/{page}/assets/{type}
PATCH /webadmin/api/pages/{page}/assets/{pageAsset}
DELETE /webadmin/api/pages/{page}/assets/{pageAsset}
GET /webadmin/api/media
POST /webadmin/api/media/fetch
GET /webadmin/api/blocks
GET /webadmin/api/blocks/{block}
PATCH /webadmin/api/blocks/{block}
POST /webadmin/api/pages/{page}/slots/{slot}/blocks
PATCH /webadmin/api/pages/{page}/slots/{slot}/blocks/reorder
DELETE /webadmin/api/pages/{page}/slots/{slot}/blocks/{block}
GET /webadmin/api/navigation-menus
GET /webadmin/api/navigation-menus/{navigationMenu}
POST /webadmin/api/navigation-menus
POST /webadmin/api/navigation-menus/{navigationMenu}/items
PATCH /webadmin/api/navigation-menus/{navigationMenu}/items/{item}
PATCH /webadmin/api/navigation-menus/{navigationMenu}/items/reorder
DELETE /webadmin/api/navigation-menus/{navigationMenu}/items/{item}
GET /webadmin/api/shared-slots
GET /webadmin/api/shared-slots/{sharedSlot}
POST /webadmin/api/shared-slots
POST /webadmin/api/shared-slots/{sharedSlot}/blocks
PATCH /webadmin/api/shared-slots/{sharedSlot}/blocks/reorder
DELETE /webadmin/api/shared-slots/{sharedSlot}/blocks/{block}
DELETE /webadmin/api/shared-slots/{sharedSlot}/blocks
GET /webadmin/api/plugins
POST /webadmin/api/plugins/install
POST /webadmin/api/plugins/{plugin}/enable
POST /webadmin/api/plugins/{plugin}/setup
POST /webadmin/api/plugins/{plugin}/disable
DELETE /webadmin/api/plugins/{plugin}
GET /webadmin/api/commerce/products
POST /webadmin/api/commerce/products
PATCH /webadmin/api/commerce/products/{product}
GET /webadmin/api/commerce/orders
GET /webadmin/api/commerce/orders/{order}
GET /webadmin/api/sites/{site}/assets/css
PUT /webadmin/api/sites/{site}/assets/css
GET /webadmin/api/locale-options renvoie le catalogue de sélecteurs de paramètres régionaux de langue standard organisé sous la forme d'une liste plate locale_options. Les outils API doivent choisir un locale_option renvoyé lors de la création d'un paramètre régional de langue normale au lieu d'inventer des chaînes code et name.
POST /webadmin/api/locales et PATCH /webadmin/api/locales/{locale} nécessitent site-settings.write et acceptent uniquement les champs de paramètres régionaux sécurisés : locale_option, code, name, is_default et is_enabled. L'envoi de locale_option copie le code canonique et le nom anglais du catalogue standard ; Les directs code et name restent disponibles pour les cas de variantes nationales contrôlées ou de cas personnalisés/opérateurs. Le paramètre is_default=true force l'activation des paramètres régionaux et rétrograde toute valeur par défaut précédente via l'invariant de paramètres régionaux CMS normal. Les outils de migration doivent corriger un identifiant de paramètres régionaux existant lors de la correction d'une erreur de configuration de langue uniquement, telle que la modification d'une nouvelle installation allemande à paramètres régionaux uniques de en à de, afin que les relations existantes entre les pages, les blocs et les paramètres régionaux du site conservent leurs identifiants.
API de validation/application de contenu
Les endpoints content validate/apply traitent des plans de contenu complets en plusieurs étapes :
POST /webadmin/api/content/validate
POST /webadmin/api/content/apply
validate vérifie un plan de contenu complet et n'écrit rien. apply valide de nouveau le plan puis crée, de façon transactionnelle, la page en brouillon demandée, les éléments de navigation, les Shared Slots, les arbres de blocs des Shared Slots et les affectations de Shared Slots aux slots de page. Il peut également remplacer des slots nommés appartenant à la page sur une page en brouillon existante lorsque le plan utilise mode: replace_existing_draft_page et comporte un garde-fou optimiste. C'est utile pour les pages générées par IA, les gabarits, les pages de départ, les en-têtes/pieds de page partagés et les utilitaires de migration, où le CMS doit éviter le contenu créé à moitié.
Le corps de la requête peut toujours contenir un champ plan ou un autre payload structuré de plan de contenu. L'URL doit rester /content/validate et /content/apply.
Les deux modes sont nécessaires :
- la Resource API expose aux outils internes le modèle de contenu et les contrats existants du CMS
- la Content Validate / Apply API évite les écritures partielles lors de constructions de pages plus importantes
Appliquer le point de restauration
POST /content/apply accepte un indicateur create_restore_point: true de niveau supérieur facultatif. Lorsqu'il est défini, le CMS prend une sauvegarde complète du système (base de données plus téléchargements) comme point de restauration avant que n'applique le plan, afin qu'un opérateur puisse revenir en arrière à partir de System -> Backups si une application générée par l'IA tourne mal.
{
"create_restore_point": true,
"plan": { "mode": "create_draft_page", "page": { "...": "..." } }
}
Règles :
- cela nécessite le dédié
backups.createcapacité, qui ne fait pas partie de l'ensemble de création de pages par défaut ; sans cela, la requête renvoie JSON403 - le plan est validé en premier, donc un plan invalide revient
422sans créer de sauvegarde inutile - si la sauvegarde ne peut pas être créée, l'application est abandonnée et renvoie JSON
409; le contenu n’est jamais appliqué sans le filet de sécurité demandé - en cas de succès, la réponse de candidature comprend un
restore_pointobjet avec la sauvegardeid,type(content_apply),label,status, etcreated_at - la sauvegarde est complète et synchrone, ce qui ajoute une latence notable ; utilisez-le pour des applications importantes ou destructrices, pas pour une automatisation à haute fréquence
Le API expose intentionnellement uniquement la création de points de restauration. La restauration, le téléchargement et la suppression des sauvegardes restent dans l'interface utilisateur d'administration de l'opérateur et ne font pas partie du jeton API.
.
API des plugins et de Commerce
Les outils opérateurs fiables peuvent gérer les plug-ins installés manuellement via des points de terminaison de cycle de vie explicites :
GET /webadmin/api/plugins
POST /webadmin/api/plugins/install
POST /webadmin/api/plugins/{plugin}/enable
POST /webadmin/api/plugins/{plugin}/setup
POST /webadmin/api/plugins/{plugin}/disable
DELETE /webadmin/api/plugins/{plugin}
GET /webadmin/api/plugins/catalog
GET /webadmin/api/plugins/catalog/{plugin}
POST /webadmin/api/plugins/catalog/{plugin}/install
POST /webadmin/api/plugins/catalog/{plugin}/update
Ces points de terminaison nécessitent respectivement plugins.read, plugins.install, plugins.manage, plugins.setup ou plugins.uninstall. Ils fonctionnent avec l'authentification du porteur et ne nécessitent pas de session de navigateur authentifiée. Le point de terminaison d’installation manuelle accepte un artefact ZIP de plug-in validé. Les demandes de liste/détails du catalogue nécessitent plugins.read ; L'installation et la mise à jour du catalogue nécessitent plugins.install et réutilisent le client de catalogue CMS, les contrôles de compatibilité, la validation de la taille des artefacts/ZIP et la vérification SHA-256. Une mise à jour du catalogue doit être plus récente que la version installée et restaure l'état activé précédent du plug-in uniquement après la validation du démarrage et la configuration de la base de données. Les deux chemins d’installation maintiennent un plugin nouvellement installé désactivé par défaut. Depuis le CMS 1.92.0, l'installation, les mises à jour et l'activation appliquent automatiquement les modifications requises de la base de données du plugin. Un échec d'installation laisse le plugin désactivé avec une action de nouvelle tentative explicite. Panel/API active et configure le rejet des plugins incompatibles avec HTTP 409 et plugin_incompatible avant de changer d'état. CMS 1.94.0 ajoute une vérification de démarrage isolée obligatoire, des packages conservés, une quarantaine d'exécution et /webadmin/plugin-recovery ; voir Plugin System pour les conditions de récupération. La désinstallation est limitée aux plugins désactivés téléchargés manuellement et préserve les tables appartenant aux plugins.
Lorsque WebBlocks Commerce est activé et prêt à être configuré, des outils fiables peuvent créer/répertorier des produits et lire les commandes :
GET /webadmin/api/commerce/products
POST /webadmin/api/commerce/products
PATCH /webadmin/api/commerce/products/{product}
GET /webadmin/api/commerce/orders
GET /webadmin/api/commerce/orders/{order}
Les lectures de produits Commerce nécessitent commerce.read, les écritures de produits nécessitent commerce.products.write et les lectures de commandes nécessitent commerce.orders.read. Si le plug-in est désactivé ou si les migrations de configuration n'ont pas été exécutées, les points de terminaison Commerce renvoient JSON 409 avec des instructions de configuration au lieu d'une erreur de base de données brute.
Le bloc webblocks-commerce-buy-button appartenant au plugin est détectable à partir de GET /webadmin/api/block-types et GET /webadmin/api/content-contract uniquement lorsque le plugin est activé. Ses paramètres nécessitent settings.commerce_product_id à partir de GET /webadmin/api/commerce/products ; valider/appliquer les rejets des identifiants de produits manquants, inconnus ou inactifs. Le paiement reste sur le flux public Commerce/PayPal. Le CMS API crée des produits et des blocs de pages, mais il ne collecte pas de données de carte et ne démarre pas de flux de saisie de carte.
Mises à jour des champs natifs du bloc existant
Utilisez la validation/l'application du contenu pour créer une page complète en une seule transaction. Pour les modifications de brouillon incrémentielles, utilisez la topologie de bloc Page API pour ajouter, réorganiser ou supprimer des blocs appartenant à des pages individuelles. Utilisez le point de terminaison de mise à jour du bloc existant uniquement lorsque le bloc existe déjà et que la modification est mappée à un champ natif sécurisé :
GET /webadmin/api/media?kind=image
PATCH /webadmin/api/blocks/{block}
Le point de terminaison nécessite content.apply. Si le bloc fait partie d'une arborescence source Shared Slot, le jeton doit également avoir shared-slots.write.
Les champs pris en charge sont intentionnellement étroits :
media_idouasset_idpournavbar-brandetsidebar-brandmédias de logomedia_idouasset_idpourhero,section,card,cta, etcontent_headermédias de fondsettings.urlsettings.targetsettings.aria_labelsettings.background_positionsettings.background_overlaysettings.show_searchpourheader-actionssettings.show_mode_togglepourheader-actionssettings.show_accent_togglepourheader-actionssettings.show_language_switcherpourheader-actions- traductions de textes telles que
titleetsubtitle - traductions de blocs d'images via
translations.image.alt_text,translations.image.caption, ou le raccourcitranslations.alt_textettranslations.caption - Regroupement de la visionneuse de galerie d'images via
settings.viewer_enabledet une minusculesettings.viewer_group; Blocs d'images activés et non liés partageant un rendu de groupe dans une visionneuse de galerie CMS existante tout en restant positionnés indépendamment - formulaire de contact traductions via
translations.contact_form.submit_labelettranslations.contact_form.success_message, ou les mêmes noms en sténographie, à côté detitleetcontent urlvariant
Les champs traduits sont écrits dans la famille de traduction à laquelle appartient le type de bloc, pour les paramètres régionaux de la demande (les paramètres régionaux par défaut du site lorsque locale est omis) :
Famille
text
| Champ | Détails |
|---|---|
| text | |
| Types de blocs Champs | , héros, riche-text, colonnes, cta et la plupart des blocs content |
| En-tête | title, eyebrow, subtitle, content, meta |
button
| Champ | Détails |
|---|---|
| button | |
| Types de blocs Champs | button |
| En-tête | title |
image
| Champ | Détails |
|---|---|
| image | |
| Types de blocs Champs | image |
| En-tête | caption, alt_text (également accepté sous les noms title, subtitle) |
contact_form
| Champ | Détails |
|---|---|
| contact_form | |
| Types de blocs Champs | contact_form |
| En-tête | title, content, submit_label, success_message |
A que la famille ne possède pas est refusé avec 422 et le code unsupported_block_translation_fields, et un type de bloc sans famille de traduction refuse carrément translations avec unsupported_block_translations — ni l'un ni l'autre n'est écrit dans la table de texte, où rien ne pourrait le lire. Une locale que le site du bloc n'a pas activée est refusée avec invalid_block_translation_locale. Les lignes stockées sont renvoyées sous block.translations, saisies par famille.
Pour les blocs Image, une chaîne explicitement vide ou null efface le caption ou alt_text des paramètres régionaux sélectionnés ; les alias title et subtitle ont le même comportement. Les champs omis conservent leurs valeurs stockées. La suppression du texte de l’image éditoriale préserve les autres langues, les références multimédias et les liaisons dynamiques. Une légende éditoriale vide ne produit aucune légende fig à moins qu'une liaison dynamique n'en fournisse une ; la solution de secours média/source dynamique existante pour le texte alternatif reste en vigueur.
A Les submit_label et success_message du formulaire de contact sont des traductions, pas des paramètres : ils constituent le seul moyen de localiser le bouton et le texte de confirmation du formulaire, et ils ne peuvent pas être définis via settings.
.
Le point de terminaison rejette les champs de topologie et d'implémentation de base de données tels que parent_id, slot_type_id, block_type_id, type, sort_order et children. Il rejette également le HTML brut, les URL de médias distants et les URL sources. Les médias existants peuvent être sélectionnés dans la bibliothèque multimédia du CMS, mais ce API n'importe ni ne télécharge de nouveaux médias distants.
Exemple :
{
"locale": "en",
"media_id": 12,
"settings": {
"url": "/",
"target": "_self",
"aria_label": "WebBlocks CMS home"
},
"translations": {
"title": "WebBlocks CMS",
"subtitle": "A modern block-based CMS."
}
}
Pour un bloc Image existant, mettez à jour la ligne de traduction d'image appartenant aux paramètres régionaux avec :
{
"locale": "en",
"translations": {
"image": {
"alt_text": "Dashboard-style ecosystem panel",
"caption": "Homepage ecosystem panel"
}
}
}
Topologie de blocs de pages API
Pour l'édition incrémentielle de brouillons de pages, la topologie des blocs appartenant à la page peut être modifiée une opération à la fois sans envoyer de plan de contenu complet :
POST /webadmin/api/pages/{page}/slots/{slot}/blocks
PATCH /webadmin/api/pages/{page}/slots/{slot}/blocks/reorder
DELETE /webadmin/api/pages/{page}/slots/{slot}/blocks/{block}
{slot} est un slug d'emplacement appartenant à une page. Ces points de terminaison sont intentionnellement protégés contre les brouillons et étroits :
- ils fonctionnent uniquement sur les pages brouillon ; une page non brouillon renvoie JSON
409avec le codepage_not_draft. Utiliser le contenu et appliquer des mises à jour par étapes pour les pages publiées. - ils fonctionnent uniquement sur les emplacements appartenant à la page ; un emplacement soutenu par Shared Slot renvoie JSON
422. Utilisez les points de terminaison Shared Slot pour le contenu Shared Slot. - un emplacement de page inconnu renvoie JSON
404.
POST .../blocks ajoute un bloc en utilisant la même charge utile de bloc normalisé que celle appliquée au contenu (type, settings, translations et children imbriqué). De nouveaux blocs sont créés avec le statut draft et ajoutés à la fin de l'emplacement. Transmettez parent_id pour l'ajouter sous un bloc de conteneur existant dans le même emplacement ; le parent doit accepter les enfants. La création et la réorganisation nécessitent content.apply.
PATCH .../blocks/reorder renumérote un groupe frère. Le tableau blocks doit contenir chaque identifiant de frère ou sœur pour un seul groupe parent exactement une fois, dans l'ordre souhaité ; le parent est dérivé des blocs soumis. La soumission d'un groupe partiel renvoie JSON 422.
DELETE .../blocks/{block} supprime le bloc et tout son sous-arbre et renvoie deleted_blocks_count. La suppression nécessite la fonctionnalité dédiée content.blocks.delete, qui ne fait pas partie de l'ensemble de fonctionnalités de création de pages par défaut. Les blocs source Shared Slot ne peuvent pas être supprimés via ce point de terminaison.
Chaque écriture capture une révision de page afin que les brouillons de modifications restent réversibles.
Actions de héros et CTA
hero et cta sont des conteneurs ordinaires dont les boutons d'action sont de simples enfants button_link — déclarez-les sous children comme n'importe quel autre bloc imbriqué. Deux champs de bloc facultatifs restent un raccourci pour le cas courant à un ou deux boutons :
{
"type": "hero",
"translations": { "title": "Welcome" },
"primary_cta": { "label": "Get started", "url": "/signup" },
"secondary_cta": { "label": "Docs", "url": "https://example.com/docs" }
}
Les deux champs acceptent un objet avec un label requis et un url requis, ou null pour laisser l'action non définie. Les URL doivent être un chemin interne sécurisé ou une URL http(s). Le raccourci écrit les deux premiers enfants button_link, le résultat est donc impossible à distinguer des boutons qu'un éditeur ajoute à la main. Déclarer explicitement les enfants est la forme canonique et le seul moyen de créer plus de deux boutons. L'envoi de primary_cta ou secondary_cta sur tout autre type de bloc est rejeté.
Les champs fonctionnent partout où une charge utile de bloc est acceptée : validation/application des plans de contenu, POST /pages/{page}/slots/{slot}/blocks et POST /shared-slots/{sharedSlot}/blocks.
Rendu de page API
Révision de la version de la page et restauration des candidats
La récupération
Page utilise un workflow d'inspection-prévisualisation-application. Il n’existe aucun point de terminaison de restauration directe.
GET /webadmin/api/pages/{page}/versionsrépertorie les versions enregistrées avec leur état de page, leurs champs d'audit et un résumé des modifications par rapport à la version précédente.GET .../versions/{version}renvoie le résultat complet de la comparaison et de l’état de référence. Les deux nécessitentcontent.read.POST .../versions/{version}/candidatenécessitecontent.apply. Il crée un brouillon de candidat privé à partir de l'instantané et renvoie l'URL d'aperçu de son navigateur. La page source n'est pas modifiée.POST .../version-candidates/{candidate}/applynécessite à la foiscontent.applyetcontent.publish. La candidature est rejetée avec JSON409et le coderestore_candidate_stalesi la page source a changé après la préparation du candidat. Une application réussie crée les versions de sécurité normales avant et après restauration et supprime le brouillon technique.DELETE .../version-candidates/{candidate}nécessitecontent.apply; il supprime le candidat sans changer la page source.
Les candidats sont délibérément absents de la découverte de pages et de l'exportation de sites ordinaires. Les outils doivent toujours inspecter la version, préparer un candidat, restituer ou ouvrir son preview_url, puis appeler apply_url après l'approbation explicite de l'opérateur.
GET /webadmin/api/pages/{page}/render nécessite content.read et renvoie la page rendue exactement telle que l'aperçu de l'administrateur du navigateur la rend : blocs de brouillon inclus, X-Robots-Tag: noindex, nofollow, et jamais via la voie publique, donc rien à ce sujet ne publie quoi que ce soit.
Ajoutez ?format=html pour le balisage lui-même au lieu de l'enveloppe JSON, et ?locale=de pour restituer une traduction spécifique ; la valeur par défaut est la langue par défaut du site. Un paramètre régional pour lequel la page n'a pas de traduction renvoie 422 avec page_translation_missing et les paramètres régionaux dont il dispose. Les pages sources Shared Slot modifient l'échafaudage et renvoient 422 avec page_not_renderable, correspondant au 404 de l'administrateur du navigateur.
Rendering était déjà accessible avant que ce point de terminaison n'existe : GET /webadmin/pages/{page}/preview accepte un jeton Bearer avec content.read ainsi qu'une session d'administrateur, et le fait toujours. Le API ajoute une enveloppe JSON et des liens découverte/OpenAPI. L'aperçu du navigateur accepte également un code locale : la langue doit être activée pour le site et disposer d'une traduction de page. L'omettre conserve la langue par défaut. Les deux aperçus transmettent la langue choisie pour bloquer le rendu ; ni enregistre ni publie de contenu.
Dans tous les cas, effectuez le rendu avant de signaler qu'une page est terminée. L'application du contenu indique ce qui a été stocké, ce qui n'est pas la même chose que ce qui est rendu : un bloc wrapper sans enfants, un emplacement attribué au mauvais Shared Slot ou une mise en page sans les emplacements que le plan supposait tous s'appliquer proprement et produire toujours une page dont personne ne veut.
Traduction de pages API
Les traductions de page possèdent une identité de page localisée et les remplacements SEO et Open Graph au niveau de la page. Content Apply écrit une ligne de traduction pour un paramètre régional lors de la création d'une page ; ces points de terminaison indiquent comment cette ligne est relue et modifiée par la suite.
GET /webadmin/api/pages/{page}/translations répertorie toutes les traductions sur une page avec name, slug, path, seo_title, seo_description, seo_keywords, list_excerpt, og_title, og_description et og_image_media_id. list_excerpt est la phrase par langue qu'un bloc de liste de pages affiche sous le titre de cette page sur une fiche de liste ; il est limité à 300 caractères et revient à la description SEO lorsqu'il est vide. Les mêmes champs apparaissent désormais sur chaque traduction dans GET /webadmin/api/pages/{page}.
POST /webadmin/api/pages/{page}/translations/{locale} nécessite content.apply et ajoute une traduction pour un paramètre régional déjà activé pour le site de pages. Le segment {locale} accepte un code régional ou un ID numérique. Seul name est requis : omettez slug et path et les deux sont dérivés du nom, exactement comme l'administrateur du navigateur les dérive. La création d'une traduction pour un paramètre régional que la page possède déjà renvoie 422 avec le code page_translation_exists.
PATCH /webadmin/api/pages/{page}/translations/{translation} nécessite content.apply et écrit uniquement les champs transportés par la requête, afin qu'un outil puisse définir seo_description sans renvoyer l'identité de la page. Envoyez null pour effacer un champ facultatif.
Slug et le chemin se déplacent toujours ensemble. L'envoi de path redérive le slug de son dernier segment ; l'envoi de slug seul déplace la page vers /{slug}. Les chemins sont canonisés, vérifiés par rapport aux routes réservées du CMS et de l'hôte, et doivent rester uniques pour le site et les paramètres régionaux. Étant donné que le titre et le slug Page lisent la traduction par défaut, renommer cette traduction renomme la page elle-même.
Les champs hors identité localisée et SEO sont rejetés avec 422 et le code unsupported_page_translation_fields, qui les nomme en blocked_fields. L'état de la page, la mise en page et le contenu du bloc ont leurs propres points de terminaison.
Actifs de page API
Les pages peuvent charger leurs propres fichiers /site/... CSS et JS en plus des ressources à l'échelle du site :
GET /webadmin/api/pages/{page}/assets
POST /webadmin/api/pages/{page}/assets/{type}
PATCH /webadmin/api/pages/{page}/assets/{pageAsset}
DELETE /webadmin/api/pages/{page}/assets/{pageAsset}
{type} est css ou js. La liste est disponible pour tout jeton valide ; les points de terminaison d'écriture nécessitent la fonctionnalité d'adhésion dédiée page-assets.write, qui ne fait pas partie de l'ensemble de création de pages par défaut.
Le contrat path est délibérément étroit et constitue la limite de sécurité pour ce API :
- il doit s'agir d'un chemin local commençant par
/site/et se terminant par.cssou.jscorrespondant au type d'actif - URL externes (
http://, Les cheminshttps://), relatifs au protocole (//),javascript:etdata:sont rejetés - la traversée de répertoires, les barres obliques inverses, les chaînes de requête et les fragments sont rejetés
Ce point de terminaison uniquement attache un fichier existant à une page ; il n'écrit jamais le contenu du fichier. Écrivez le fichier lui-même avec les actifs du site API (PUT /webadmin/api/sites/{site}/assets/{type}, qui nécessite site-assets.write) ou depuis l'interface utilisateur d'administration.
Les champs pris en charge sont path (obligatoire lors de la création), sort_order, is_enabled et, pour les actifs JS uniquement, is_defer, is_async et is_module. load_position est dérivé du type (head pour CSS, body_end pour JS), correspondant à l'éditeur d'administration. Le type css/js est immuable lors de la mise à jour ; supprimez et rajoutez pour le modifier.
Contrairement aux points de terminaison de topologie de bloc de page, les ressources de page ne sont pas uniquement des brouillons : elles peuvent être modifiées sur n'importe quelle page, en fonction de l'onglet Actifs de page d'administration. Chaque écriture capture une révision de page.
Shared Slot Topologie de bloc API
Shared Slot les arborescences de blocs ont leurs propres points de terminaison de topologie car ils sont partagés sur chaque page à laquelle l'emplacement est attribué :
PATCH /webadmin/api/shared-slots/{sharedSlot}/blocks/reorder
DELETE /webadmin/api/shared-slots/{sharedSlot}/blocks/{block}
DELETE /webadmin/api/shared-slots/{sharedSlot}/blocks
Les blocs d'ajout restent à POST /shared-slots/{sharedSlot}/blocks, et la modification des champs de contenu sécurisé d'un seul bloc reste à PATCH /blocks/{block} (qui accepte déjà les blocs source Shared Slot avec shared-slots.write). Les nouveaux points de terminaison ajoutent les opérations de topologie manquantes :
PATCH .../blocks/reorderrenumérote un groupe frère ; le tableaublocksdoit contenir chaque identifiant de frère ou sœur pour un seul groupe parent exactement une fois, dans l'ordre souhaité. Il nécessite queshared-slots.write.DELETE .../blocks/{block}supprime un bloc et son sous-arbre et renvoiedeleted_blocks_count.DELETE .../blocksefface chaque bloc de l'emplacement afin qu'un outil puisse effacer et remplacer un Shared Slot ; il renvoiedeleted_blocks_count.- Les deux suppressions nécessitent
shared-slots.writeainsi que la capacité dédiéecontent.blocks.delete.
Contrairement aux modifications de blocs de page, celles-ci ne sont pas uniquement des brouillons : les Shared Slots n'ont pas de concept de brouillon de page. La réorganisation ou la suppression d'un bloc Shared Slot déjà publié affecte donc immédiatement chaque page attribuée, c'est pourquoi la suppression est protégée par la capacité destructrice de content.blocks.delete. Chaque écriture reconstruit les affectations de page de l'emplacement et capture une révision Shared Slot afin que les modifications restent réversibles.
Paramètres du site API
Aà côté de branding, head, timezone et public-theme, trois autres champs de site sont accessibles en écriture. Tous les trois nécessitent site-settings.write.
PATCH /webadmin/api/sites/{site}/seo écrit seo_title, seo_description et seo_keywords : les métadonnées de secours à l'échelle du site dont une page publique hérite lorsque sa propre traduction de page ne comporte aucune substitution. Partiellement, et null efface un champ. Les remplacements au niveau de la page appartiennent à la traduction de la page ; voir la traduction de page API ci-dessus.
PATCH /webadmin/api/sites/{site}/contact-recipient écrit contact_recipient_email, l'adresse à laquelle les soumissions du formulaire de contact sont envoyées par courrier. Envoyez une valeur vide pour revenir au destinataire du système. Un formulaire de contact assemblé via le API ne fait rien d'utile tant que cela n'est pas défini.
PUT /webadmin/api/sites/{site}/locales remplace les paramètres régionaux du site définis à partir de locale_ids. Les paramètres régionaux par défaut sont toujours conservés, exactement comme le formulaire d'administration, et les paramètres régionaux doivent d'abord être activés globalement via POST/PATCH /webadmin/api/locales. Une traduction de page ne peut pas être enregistrée pour des paramètres régionaux que le site n'a pas activés. Il s'agit donc du point de terminaison qui rend les nouveaux paramètres régionaux utilisables sur un site.
Ce point de terminaison est plus strict que le formulaire d'administration sur un point : il refuse de détacher les paramètres régionaux qui ont encore des traductions de pages sur le site, et le 422 nomme les paramètres régionaux et le nombre. Le formulaire permet à un opérateur de le faire en connaissance de cause ; un outil sans surveillance rendrait silencieusement le contenu orphelin.
Domaine du site API
Les enregistrements de domaine décident quel nom d'hôte correspond à quel site, de sorte que l'administrateur du navigateur les conserve derrière l'accès au niveau du système. Les points de terminaison API sont :
PATCH /webadmin/api/sites/{site}/seoPATCH /webadmin/api/sites/{site}/contact-recipientPUT /webadmin/api/sites/{site}/localesGET /webadmin/api/sites/{site}/domainsnécessitecontent.readPOST /webadmin/api/sites/{site}/domainsnécessitedomains.writePUT /webadmin/api/sites/{site}/domains/{domain}nécessitedomains.writePOST /webadmin/api/sites/{site}/domains/{domain}/primarynécessitedomains.writeDELETE /webadmin/api/sites/{site}/domains/{domain}nécessite le destructeurdomains.deleteGET /webadmin/api/domains/{domain}/statusnécessitecontent.read
Ces points de terminaison vivaient auparavant uniquement sous un préfixe /admin-api et ne vérifiaient rien au-delà de la validité du jeton, de sorte que n'importe quel jeton pouvait ajouter ou supprimer un domaine. Ils relèvent désormais du /webadmin/api avec le reste du API et chaque itinéraire comporte une capacité. Le préfixe /admin-api continue de fonctionner pour les outils de provisionnement existants, avec les mêmes exigences de capacité et une route supplémentaire, GET /admin-api/sites ; les nouvelles intégrations devraient utiliser /webadmin/api, dont les chemins sont également couverts par l'exemption CSRF que l'ancien préfixe n'a jamais eu.
Shared Slot Métadonnées API
PATCH /webadmin/api/shared-slots/{sharedSlot} nécessite shared-slots.write et modifie le Shared Slot lui-même plutôt que ses blocs : label, handle, slot, layout et is_active. Seuls les champs présents sont écrits. Les handles restent uniques par site, le nom de l'emplacement doit être résolu en un type d'emplacement publié, et la page source Shared Slot et ses affectations sont ensuite reconstruites exactement au fur et à mesure que l'administrateur du navigateur les reconstruit. Un changement de métadonnées ou de statut capture une révision Shared Slot.
Le déplacement d'un Shared Slot vers un autre site n'est pas pris en charge ici et est rejeté avec 422 et le code unsupported_shared_slot_fields, qui couvre également tout autre champ en dehors de cet ensemble. Les déplacements intersites restent dans l'administrateur du navigateur avec les autres opérations de transfert de site.
DELETE /webadmin/api/shared-slots/{sharedSlot} nécessite la capacité destructrice shared-slots.delete et applique la même protection que l'administrateur du navigateur : un Shared Slot toujours référencé par un emplacement de page n'est jamais supprimé. La réponse 422 contient le code shared_slot_in_use et un tableau usage nommant les emplacements de page de référence, afin qu'un outil puisse d'abord les détacher avec PUT /webadmin/api/pages/{page}/slots/{slot}/source. Si les colonnes de référence Shared Slot n'ont pas encore été migrées, le point de terminaison renvoie 409 avec shared_slots_not_ready au lieu de deviner.
Médiathèque API
La bibliothèque multimédia API est intentionnellement séparée des autorisations de contenu étendu afin que les outils d'IA/opérateur puissent bénéficier de la découverte de médias ou du nettoyage des métadonnées sans recevoir de pouvoirs d'écriture non liés.
Capacités :
media.read: répertorier et inspecter les enregistrements de la médiathèque CMS existants.media.upload: télécharger des fichiers dans la médiathèque.media.write: mettre à jour les métadonnées sécurisées sur les enregistrements multimédias existants.media.replace: remplacer un fichier multimédia existant tout en préservant son identifiant multimédia.media.move: déplacer le média entre les dossiers ou effacer son dossier.media.delete: supprimez les médias inutilisés avec la même protection d'utilisation que le panneau d'administration.
Portée de la phase 1 :
GET /webadmin/api/media
POST /webadmin/api/media
GET /webadmin/api/media/{media}
PATCH /webadmin/api/media/{media}
POST /webadmin/api/media/{media}/replace
POST /webadmin/api/media/{media}/move
DELETE /webadmin/api/media/{media}
GET /webadmin/api/media renvoie les enregistrements multimédias existants avec des champs sécurisés tels que l'identifiant, le genre, le titre, le nom de fichier, le nom d'origine, le type MIME, la visibilité, l'URL publique lorsqu'elle est disponible, le texte alternatif, les dimensions, la prévisualisation et l'étiquette de métadonnées compacte. Il nécessite media.read. Pendant la transition depuis les anciens jetons API, content.read peut également être accepté pour la découverte de médias en lecture seule afin que les intégrations de création de pages existantes continuent de fonctionner.
GET /webadmin/api/media/folders répertorie les dossiers de la bibliothèque multimédia avec leur nombre de médias, et POST /webadmin/api/media/folders nécessite media.write et en crée un à partir de name, avec slug et parent_id en option. Un nom qui existe déjà sous le même parent est refusé avec 422 et le code media_folder_exists, et la réponse porte le dossier existant donc un outil de nouvelle tentative le réutilise au lieu de créer des doublons. Téléchargements de fichiers dans un dossier avec folder_id ; déplacer des médias existants avec POST /webadmin/api/media/{media}/move.
POST /webadmin/api/media nécessite media.upload et accepte les téléchargements multipart/form-data dans la bibliothèque multimédia CMS normale. Le fichier téléchargé devient une ligne media normale et est visible dans l'écran Média de l'administrateur du navigateur et dans les sélecteurs de médias. La validation du téléchargement reflète les types de fichiers autorisés par la bibliothèque multimédia de l'administrateur du navigateur : images courantes, vidéos, PDF, documents Office, fichiers texte/CSV/RTF et ZIP.
Les champs de métadonnées pris en charge sont folder_id, title, alt_text, caption et description. Le point de terminaison renvoie l'objet multimédia créé avec son identifiant et son URL publique lorsqu'il est disponible.
PATCH /webadmin/api/media/{media} nécessite media.write et met à jour uniquement les métadonnées descriptives sécurisées :
titlealt_textcaptiondescription
POST /webadmin/api/media/{media}/replace nécessite media.replace et remplace le fichier binaire stocké tout en préservant l'identifiant du média et les références existantes. Le fichier de remplacement doit correspondre au même type de support que l'enregistrement existant, tel que image à image ou document à document. La réponse inclut les détails d'utilisation actuelle afin que les outils puissent voir si le remplacement affecte les blocs, la marque du site ou le référencement de la page.
POST /webadmin/api/media/{media}/move nécessite media.move et accepte folder_id, y compris null pour effacer l'affectation du dossier.
DELETE /webadmin/api/media/{media} nécessite media.delete et utilise la même protection d'utilisation que l'administrateur du navigateur. Les médias référencés par des blocs, des galeries, des pièces jointes, la marque du site ou le référencement des pages ne sont pas supprimés ; le API renvoie à la place 422 avec les détails d'utilisation.
Ce API ne prend explicitement pas en charge :
- modification directe du disque, du chemin, du nom de fichier, du type MIME, du type, de la visibilité, de la taille, des dimensions, du téléchargeur ou des relations d'utilisation
- récupération ou importation d'URL de médias distants
Cette limite permet aux outils d'IA/opérateur de recevoir uniquement les puissances multimédias dont ils ont besoin. Par exemple, un jeton de création de page peut lire et télécharger des médias sans pouvoir supprimer ou remplacer les fichiers existants, tandis qu'un jeton de maintenance approuvé peut être accordé explicitement à media.replace ou media.delete.
Remplacement de slots sur une page en brouillon existante
Le remplacement sur une page en brouillon existante reste dans le contrat validate/apply :
POST /webadmin/api/content/validate
POST /webadmin/api/content/apply
Utilisez mode: replace_existing_draft_page pour remplacer un ou plusieurs emplacements appartenant à une page sur une page de brouillon existante. L'opération nécessite content.validate pour la validation et content.apply pour l'application. Il ne nécessite pas pages.delete, car il ne s'agit pas d'une opération générale de suppression de page.
Page Translation path est l’URL publique canonique. Les nouveaux plans doivent utiliser des chemins tels que /contact, /features, /games/fruit-train ou /docs/internal-content-api ; /p/... est uniquement compatible avec les anciennes versions. Les trajectoires de relèvement de barres obliques sont normalisées segment par segment, de sorte que /docs/internal-content-api/ devient /docs/internal-content-api et n'est pas réduit en docsinternal-content-api. CMS dérive le slug de page court du segment de chemin final, de sorte que /games/fruit-train stocke le slug fruit-train et le chemin /games/fruit-train. Les zones de route réservées telles que /webadmin, /webadmin/api, /cms, /search, /search.json, /contact-messages, /install et les routes d'authentification de l'hôte ne peuvent pas être créées en tant que chemins de page publics.
Exemple :
{
"plan": {
"mode": "replace_existing_draft_page",
"site": "default",
"locale": "en",
"page": {
"id": 9,
"expected_path": "/contact",
"status": "draft"
},
"replace_slots": {
"main": [
{
"type": "plain_text",
"translations": {
"content": "Updated draft contact content."
}
}
]
}
}
}
Règles :
- la page cible doit être au statut
draft expected_pathouexpected_updated_atest obligatoireexpected_pathutilise le chemin public canonique de Page Translation, pas un alias hérité/p/...- la page cible doit appartenir au site demandé et la langue (locale) doit être activée pour ce site
- chaque slot doit exister sur la page et utiliser des blocs appartenant à la page
- les slots adossés à des Shared Slots sont rejetés au lieu d'être vidés
- seuls les blocs des
replace_slotsnommés sont supprimés - les anciens blocs sont supprimés et les nouveaux écrits dans une seule transaction
- des révisions de page sont capturées avant et après l'application
- aucune publication, récupération/import de médias, suppression large ou effacement des affectations de Shared Slot n'a lieu
Mises à jour échelonnées de la page publiée
Les pages publiées ne peuvent pas être remplacées directement. Pour les pages de documentation liées à la source ou d'autres pages en direct qui doivent rester publiques pendant la préparation des modifications de contenu, utilisez les modes de mise à jour par étapes :
.
create_staged_update_for_published_page
replace_staged_page_update
promote_staged_page_update
create_staged_update_for_published_page crée un brouillon de page intermédiaire à partir de la page source publiée uniquement lorsque cette page source ne dispose pas déjà d'un brouillon de mise à jour intermédiaire actif. La répétition de l'appel de création pour la même page source renvoie le brouillon intermédiaire actif existant avec data.reused_staged_update=true au lieu de créer une autre page technique. La page source reste publiée sur son chemin public existant. La page intermédiaire stocke les métadonnées settings.staged_update avec l'ID de la page source, le chemin source, l'horodatage mis à jour de la source, l'état du cycle de vie et les emplacements gérés. Il utilise un chemin de brouillon interne tel que /staged-updates/page-123/update-456, il n'entre donc pas en collision avec le chemin canonique source et n'est pas acheminé publiquement. L'URL d'aperçu d'administrateur normale /webadmin/pages/{page}/preview peut afficher la page intermédiaire pour les sessions d'administration authentifiées ou les jetons porteur CMS API avec content.read.
.
replace_staged_page_update réutilise le brouillon de règles de remplacement par rapport au brouillon de page intermédiaire. Utilisez-le pour chaque révision ultérieure après l'existence d'un brouillon par étapes. Il remplace uniquement les emplacements appartenant à la page et rejette les emplacements soutenus par Shared Slot.
promote_staged_page_update applique le contenu de l'emplacement appartenant à la page intermédiaire à la page source publiée dans une transaction. Il conserve le chemin de la page source, l'état, la mise en page, les affectations Shared Slot et les paramètres de la page, sauf si une mise à jour source_sync sur liste autorisée est fournie. Les blocs appartenant à la page sponsorisée sont écrits sous la forme published afin que la page publique reflète immédiatement le contenu promu. Le contenu Shared Slot n’est jamais mis en cascade. Une fois les versions de sécurité pré/post-promotion de la page source capturées, la page technique intermédiaire est supprimée dans la même transaction ; une promotion ratée laisse donc le projet disponible pour correction. La promotion nécessite la capacité d'itinéraire normale content.apply et la capacité avancée content.publish.
Al'abandon d'un brouillon intermédiaire actif utilise DELETE /webadmin/api/pages/{staged_page}/staged-update. Ce point de terminaison de suppression étroite nécessite content.apply, accepte uniquement un brouillon de page avec des métadonnées de mise à jour par étapes actives et ne modifie jamais la page source publiée ou ses versions enregistrées. Cela évite d'accorder à un outil de création de pages la large capacité pages.delete simplement pour nettoyer son propre brouillon technique.
Si un plan d'application normalisé réussit la validation mais échoue lors des écritures transactionnelles, le API renvoie la validation normale JSON avec ok=false et une erreur à plan.apply. L'exception détaillée est enregistrée dans les journaux d'application ; Les réponses API restent sécurisées pour le public et n'incluent pas de traces de pile, de composants internes de base de données, de jetons ou de chemins locaux.
Exemple de flux de travail par étapes :
{
"plan": {
"mode": "create_staged_update_for_published_page",
"site": "default",
"locale": "en",
"page": {
"id": 123
},
"expected_source_path": "/docs",
"managed_slots": ["main"]
}
}
Puis remplacez le contenu intermédiaire :
{
"plan": {
"mode": "replace_staged_page_update",
"staged_page_id": 456,
"expected_source_page_id": 123,
"expected_source_path": "/docs",
"replace_slots": {
"main": [
{
"type": "plain_text",
"translations": {
"content": "Replacement staged content."
}
}
]
}
}
}
Promouvoir après aperçu et approbation explicite :
{
"plan": {
"mode": "promote_staged_page_update",
"staged_page_id": 456,
"expected_source_page_id": 123,
"expected_source_path": "/docs",
"promote_slots": ["main"]
}
}
Aucune nouvelle table de schéma n'est requise pour ce flux de travail ; Les métadonnées actives du cycle de vie intermédiaire utilisent la colonne Page settings JSON existante. Les pages techniques promues ne sont pas conservées car les versions des pages sources fournissent le suivi de récupération.
La mise à niveau des installations à partir d'une version qui a archivé des pages intermédiaires promues peut prévisualiser et supprimer ces enregistrements hérités une fois :
php artisan webblocks:staged-updates:prune --dry-run
php artisan webblocks:staged-updates:prune
La commande sélectionne uniquement les pages archivées dont les métadonnées intermédiaires indiquent explicitement type=published_page_update et state=promoted. Les brouillons actifs et les pages archivées ordinaires ne sont jamais candidats.
Métadonnées de synchronisation de la source
Les plans de contenu peuvent conserver un objet source_sync limité et sans secret pour les flux de synchronisation de documentation IA/opérateur. Les réglages de page arbitraires sont rejetés. La forme acceptée est :
{
"page": {
"settings": {
"source_sync": {
"type": "markdown_documentation",
"source_id": "webblocks-cms:docs/internal-content-api.md",
"source_path": "docs/internal-content-api.md",
"source_sha256": "64-character-lowercase-sha256",
"managed_slots": ["main"],
"last_synced_at": "2026-06-25T00:00:00Z"
}
}
}
}
Apply enregistre ces métadonnées dans les réglages de la page, et les réponses de l'API de liste/détail des pages exposent les mêmes champs source_sync autorisés pour des rapprochements ultérieurs. N'y incluez pas de tokens, de valeurs d'environnement, de chemins absolus locaux ou serveur, ni d'autres secrets.
Endpoints de publication explicites
La publication est distincte de content apply et exige un token doté de content.publish.
POST /webadmin/api/pages/{page}/publish
POST /webadmin/api/pages/{page}/publish-page-owned-blocks
POST /webadmin/api/pages/{page}/archive
POST /webadmin/api/pages/{page}/publish publie l'enregistrement de la page. Son payload par défaut ne concerne que la page :
{
"include_page_owned_blocks": false
}
Règles :
- omis
include_page_owned_blocksse comporte commefalse include_page_owned_blocks: falsepublie uniquement l'enregistrement de la page et laisse les brouillons ou les blocs en cours de révision inchangésinclude_page_owned_blocks: truepublie les blocs brouillon et en cours de révision appartenant aux emplacements de page non partagés de la page, y compris les blocs enfants imbriqués- les blocs déjà publiés restent inchangés
- Les emplacements sauvegardés sur Shared Slot sont exclus et signalés dans la réponse
- champs en cascade Shared Slot non pris en charge tels que
publish_shared_slots,include_shared_slot_blocks, oushared_slot_cascaderetour JSON422 - la réponse inclut les métadonnées d'identifiant/statut/chemin de page, si les blocs appartenant à la page ont été inclus, le nombre publié, les résumés Shared Slot exclus et l'identifiant de révision de la page
POST /webadmin/api/pages/{page}/publish-page-owned-blocks publie uniquement les blocs appartenant à la page non publiés et ne modifie pas l'état du flux de travail de la page. Il utilise la même capacité content.publish et la même règle d'exclusion Shared Slot.
POST /webadmin/api/pages/{page}/archive retire la page du site public : les pages archivées renvoient 404 aux visiteurs et leurs éléments de menu liés à la page cessent de s'afficher dans les menus publics. Il utilise la même fonctionnalité content.publish et reflète les règles de flux de travail d'administration : autorisé à partir de in_review et published, un brouillon de page renvoie JSON 422, le réarchivage d'une page archivée est un échec et les pages de mise à jour par étapes sont rejetées (promouvez-les ou supprimez-les à la place). La réponse inclut les métadonnées de la page, from_status et l'ID de révision de la page capturé. La publication à nouveau de la page annule l'archive.
I/les outils de l'opérateur ne doivent pas supposer que la publication de page rend public tout le contenu des blocs. Utilisez include_page_owned_blocks: true uniquement lorsque l'utilisateur a explicitement approuvé la publication de tous les blocs non publiés appartenant à cette page. Le contenu Shared Slot doit être examiné et publié séparément.
Endpoint du contrat de contenu
GET /webadmin/api/content-contract est un point de terminaison de découverte en lecture seule pour les outils d'IA/opérateurs de confiance. Il renvoie le préfixe API, les URL de validation/application, le modèle d'URL d'aperçu de l'administrateur, les indicateurs de sécurité, les URL de découverte, les modèles de création de pages recommandés, un contrat de direction de conception lisible par machine et des métadonnées de contrat de bloc nettoyées.
Avant de choisir une arborescence de blocs, les outils doivent lire design_direction, sélectionner une valeur pour chacun des character, density, typography, geometry, imagery, corners, contrast et framing, et expliquez comment la carte de composition implémente ces choix. Il s'agit d'un contrat de planification plutôt que d'un magasin de contenu caché : le résultat s'exprime à travers les paramètres de bloc natifs, les jetons de thème publics et le site stable CSS. Sa politique de composition rend les colonnes claires par défaut pour les nouveaux plans API, conserve l'adhésion aux cartes et nécessite une justification de limite de contenu/d'action pour chaque collection de cartes. Une source contenant trois articles courts ne constitue pas une telle justification.
framing est une dimension de planification et non des données de page persistantes. Choisissez open, restrained, framed ou dense-ui en fonction du contenu et du contexte. N'utilisez pas une carte ou un panneau bordé simplement pour organiser une section. Le cadrage doit communiquer l’indépendance sémantique, l’interaction ou les limites de l’entité. Les conteneurs externes de héros, les groupes de fonctionnalités/principes, les wrappers de section, les colonnes de navigation/pied de page, les bandes CTA, les statistiques décoratives et les divisions éditoriales ne sont pas encadrés par défaut. Préférez les espaces, la hiérarchie typographique, la disposition asymétrique, les séparateurs, les changements de ton, les sections larges, l'alignement, le décalage/chevauchement et les règles restreintes. L’audit requis des surfaces encadrées doit justifier chaque surface encadrée non-entité ; « séparer visuellement la section » n'est pas suffisant.
La section adjacente design_fixtures publie des arbres de blocs natifs canoniques, des instructions de conception compatibles, des hooks publics attendus, des anti-modèles et des tailles de capture déterministes de bureau/mobile. Son statut distingue un contrat de rendu basé sur la source des captures d'écran approuvées par l'homme. Les outils peuvent utiliser une arborescence de luminaires comme référence de composition, mais ne doivent pas revendiquer une approbation visuelle alors que le registre rapporte render_contract_ready_capture_pending. Consultez les contrats de composition disponibles dans design_fixtures de la réponse de découverte.
Le point de terminaison est le comportement générique du produit CMS. Il ne doit pas renvoyer de secrets spécifiques à l'installation, de valeurs de jeton, de contenu brut de Blade, de chemins absolus du système de fichiers, de chemins de serveur privé ou d'instructions spécifiques au site. Les lignes de contrat de bloc peuvent inclure le handle/slug, l'étiquette, la catégorie, le statut, le conteneur et la prise en charge des enfants, les champs traduisibles, les champs de paramètres partagés et le comportement racine du moteur de rendu public.
I Les outils doivent appeler ce point de terminaison ou GET /webadmin/api/block-types avant de créer un plan et doivent utiliser uniquement les descripteurs présents dans l'installation actuelle.
Les contrats
Block peuvent exposer des champs d'icônes et de badges publics facultatifs, notamment settings.icon_slug, settings.icon_tone, settings.icon_size, settings.badge_tone et une copie traduite de eyebrow/badge_label. Les outils doivent traiter les icônes slug comme des sélections basées sur un catalogue plutôt que comme du texte libre ; Le rendu public ignore les icônes inconnues ou inactives et émet uniquement des classes wb-icon wb-icon-{slug} sécurisées pour les lignes actives du catalogue WebBlocks UI. settings.icon_tone est un paramètre de tonalité visuelle publique partagé, et non une copie appartenant aux paramètres régionaux, et accepte uniquement default, soft, brand, accent, highlight, bold et quiet ; settings.icon_size accepte default, sm, lg ou xl et correspond à la classe de taille WebBlocks UI correspondante. info, success, warning et danger restent des tonalités d'état sémantiques pour les badges, les alertes, la validation et les commentaires. Les tonalités ou tailles d'icônes inconnues sont rejetées lors de la validation du plan de contenu ou ignorées par le rendu public comme solution de secours sûre. La tonalité du badge n'est exposée que lorsque le bloc possède également une copie traduite de l'étiquette du badge.
GET /webadmin/api/icon-catalog?context=content renvoie les slugs d'icônes de sécurité actifs que les clients API peuvent attribuer aux blocs de contenu public. Utilisez context=navigation pour classer les suggestions marquées par la navigation en premier pour les choix d'icônes d'éléments de navigation ; les deux contextes renvoient toujours chaque icône active car le contexte est un indice plutôt qu'une liste autorisée. Les outils API doivent lire ce point de terminaison avant d'envoyer des valeurs settings.icon_slug ou des valeurs icon de navigation et ne doivent pas deviner les noms d'icônes du manifeste WebBlocks UI.
Le contrat contact_form comprend des métadonnées de formulaire sécurisées supplémentaires : schéma de paramètres, champs traduits, point de terminaison de soumission public POST /contact-messages, comportement du navigateur CSRF requis, règles de validation du serveur, champ de vérification anti-spam caché appartenant au CMS, comportement de réussite du champ de vérification générique, notes de classification/quarantaine du spam, comportement de stockage avant notification, ordre de repli du destinataire, notification sécurisée enregistrement des échecs et comportement d'examen /webadmin/contact-messages. Le champ de vérification est généré par le moteur de rendu, ne fait pas partie de la saisie normale du visiteur et ne doit pas être créé manuellement par API ou par les outils d'IA/opérateur. Les outils de page de contact doivent utiliser ce bloc natif plutôt que les formulaires HTML de confiance, le balisage de formulaire brut ou les formulaires mailto:. L'ancien champ website n'est plus le contrat public du formulaire de contact.
Le guide de création de pages AI lisible par l'homme est fourni dans les installations natives du package à l'adresse vendor/fklavyenet/webblocks-cms/docs/ai-page-building-guide.md.
Surface De L’API
Endpoints de découverte
GET /webadmin/apiGET /webadmin/api/openapi.jsonGET /webadmin/api/ai-guideGET /webadmin/api/examplesGET /webadmin/api/examples/contact-pageGET /webadmin/api/examples/landing-pageGET /webadmin/api/sitesGET /webadmin/api/localesGET /webadmin/api/locale-optionsPOST /webadmin/api/localesPATCH /webadmin/api/locales/{locale}GET /webadmin/api/page-layoutsGET /webadmin/api/block-typesGET /webadmin/api/icon-catalogGET /webadmin/api/content-contract
Endpoints des pages
GET /webadmin/api/pagesGET /webadmin/api/pages/{page}GET /webadmin/api/pages/{page}/renderGET /webadmin/api/pages/{page}/translationsPOST /webadmin/api/pages/{page}/translations/{locale}PATCH /webadmin/api/pages/{page}/translations/{translation}POST /webadmin/api/pages/{page}/sync-layout-slotsPATCH /webadmin/api/pages/{page}/layoutPOST /webadmin/api/pages/{page}/slots/{slot}/shared-slotPUT /webadmin/api/pages/{page}/slots/{slot}/source
Endpoints des blocs
GET /webadmin/api/blocksGET /webadmin/api/blocks/{block}
Endpoints de navigation
GET /webadmin/api/navigation-menusGET /webadmin/api/navigation-menus/{navigationMenu}POST /webadmin/api/navigation-menusPOST /webadmin/api/navigation-menus/{navigationMenu}/itemsPATCH /webadmin/api/navigation-menus/{navigationMenu}/items/{item}PATCH /webadmin/api/navigation-menus/{navigationMenu}/items/reorderDELETE /webadmin/api/navigation-menus/{navigationMenu}/items/{item}
Les menus de navigation utilisent le modèle CMS navigation_items.menu_key existant. La phase 2A prend en charge les poignées de menu CMS fournies telles que primary, footer, mobile, legal et docs ; il n'ajoute pas de table de menu séparée. La création d'un menu de navigation est traitée comme la création d'un groupe de menus sécurisé à l'échelle du site avec des éléments initiaux facultatifs. Il refuse d'écraser un site/menu contenant déjà des éléments.
La création, la mise à jour, les modifications de visibilité et la réorganisation des éléments de navigation nécessitent navigation.write. La suppression nécessite la capacité destructrice explicite navigation.delete. Les mises à jour d'articles prennent en charge label/title, url, link_type, page_id, target, visibility, sort_order/position, parent_id et icon où ces champs sont valides pour le type de lien sélectionné. Les mises à jour sont partielles : les champs absents de la charge utile conservent leurs valeurs stockées sans revalidation, de sorte que les lignes héritées (un ordre de tri pré-éditeur d'arborescence de 0, un enfant imbriqué sous un parent de type page) restent modifiables ; les règles s'appliquent aux valeurs qu'une requête envoie réellement.
Item acceptent également une clé locale facultative (un code de paramètres régionaux activé pour le site de l'élément), reflétant les écritures de traduction de bloc. Sans locale, ou avec les paramètres régionaux par défaut du site, label/title écrit le titre canonique des paramètres régionaux par défaut. Avec un locale autre que celui par défaut, la valeur label/title est stockée en tant que ligne de traduction à clé locale pour cet élément et le titre canonique reste intact ; les autres champs de la même requête (visibilité, position, etc.) restent partagés et s'appliquent à l'élément lui-même. Le rendu public sélectionne le titre de navigation pour les paramètres régionaux demandés et revient au titre canonique des paramètres régionaux par défaut lorsqu'aucune ligne de traduction n'existe. Les charges utiles de lecture d'éléments exposent les titres stockés par langue sous la forme d'une carte title_translations saisie par code de langue. Les charges utiles de réorganisation doivent inclure chaque élément du site/menu sélectionné une seule fois. Supprimer rejette les éléments parents qui ont encore des éléments enfants, les outils doivent donc d'abord déplacer ou supprimer les enfants au lieu de s'appuyer sur des cascades.
Les URL des éléments de navigation peuvent être des chemins internes tels que /, /about, /contact et /#platform, ou des URL sécurisées http/https. Utilisez un chemin plus un fragment pour les ancres de même page ; Les valeurs brutes de fragment uniquement telles que #platform ne sont pas des URL de navigation. Le API rejette javascript:, data:, les URL relatives au protocole, la traversée, les URL mal formées, les cibles non prises en charge et les étiquettes vides. Les points de terminaison de navigation ne créent pas de pages, ne publient pas de pages, n'explorent pas de sites, ne récupèrent pas d'URL distantes et ne suppriment pas en cascade les éléments enfants.
La création de
Endpoints des Shared Slots
GET /webadmin/api/shared-slotsGET /webadmin/api/shared-slots/{sharedSlot}PATCH /webadmin/api/shared-slots/{sharedSlot}DELETE /webadmin/api/shared-slots/{sharedSlot}POST /webadmin/api/shared-slotsPOST /webadmin/api/shared-slots/{sharedSlot}/blocksPOST /webadmin/api/shared-slots/{sharedSlot}/publish-blocks
Shared Slot est limitée au site et refuse les descripteurs en double pour le même site. Les blocs Shared Slot réutilisent le même rédacteur de charge utile de bloc utilisé par les blocs appartenant à la page, de sorte que la copie appartenant aux paramètres régionaux reste dans les lignes de traduction et que les paramètres partagés restent sur le chemin d'enregistrement/paramètres du bloc. Les demandes d'ajout de bloc Shared Slot peuvent inclure parent_id ou parent_block_id pour ajouter un bloc sous un bloc existant dans la même arborescence source Shared Slot lorsque ce parent accepte le type d'enfant demandé. Les blocs Shared Slot sont créés en tant que brouillon de contenu et nécessitent un POST /webadmin/api/shared-slots/{sharedSlot}/publish-blocks explicite avec shared-slots.write plus content.publish avant d'être rendus publiquement. L'importation et l'affectation des médias restent en dehors de cette phase.
Affectation des slots de page
POST /webadmin/api/pages/{page}/slots/{slot}/shared-slot
PUT /webadmin/api/pages/{page}/slots/{slot}/source
Le point de terminaison shared-slot attribue un Shared Slot actif compatible existant sur le même site à un emplacement de page existant. Il ne publie pas la page. Il refuse le Shared Slots intersite, inactif et incompatible. Il refuse également de changer un emplacement contenant encore des blocs appartenant à une page, car la phase 2A ne supprime ni ne remplace ces blocs automatiquement.
PUT .../source écrit la source de contenu de l'emplacement et constitue le chemin de sortie : source_type accepte page, shared_slot ou disabled. Il nécessite content.apply, et shared_slot nécessite en outre shared-slots.write ainsi que les mêmes règles de compatibilité que le point de terminaison d'attribution auquel il délègue. Le détachement efface shared_slot_id et laisse les blocs appartenant à la page intacts, donc page les restitue à nouveau et disabled conserve le wrapper d'emplacement sans rien à l'intérieur. Avant que ce point de terminaison n'existe, le API pouvait créer une référence Shared Slot qu'il n'avait aucun moyen de supprimer : la seule sortie était l'écran d'administration authentifié par session.
Si la mise en page contient un emplacement tel que header mais que l'enregistrement de page a été créé avant que cet emplacement de page n'existe, appelez d'abord POST /webadmin/api/pages/{page}/sync-layout-slots. La synchronisation des emplacements est idempotente et crée uniquement les emplacements de page manquants à partir de la mise en page sélectionnée ; il ne supprime jamais les emplacements, blocs, états désactivés, affectations Shared Slot, traductions ou révisions existants. Pour un nouvel en-tête Shared Slot, publiez explicitement les blocs Shared Slot avant d'attendre une sortie publique.
Attribution de mise en page
PATCH /webadmin/api/pages/{page}/layout
Écrit la mise en page d'une page existante (public_shell). Le formulaire de modification de l'administrateur pourrait toujours changer cela ; le API ne pouvait auparavant le définir que lors de la création d'une page. content.apply le couvre. layout (ou handle) doit être l'un des handles actifs de GET /webadmin/api/page-layouts — l'ancien alias dashboard est toujours normalisé en docs. Correspond au propre contrat de PageController::update() : il ne mute pas les emplacements de page lors d'un simple changement de mise en page, donc ce point de terminaison ne le fait pas non plus. Appelez sync-layout-slots séparément si la nouvelle mise en page définit des emplacements que la page ne possède pas encore.
Point de terminaison de présentation du site
POST /webadmin/api/sites/{site}/public-theme
PATCH /webadmin/api/sites/{site}/branding
PATCH /webadmin/api/sites/{site}/timezone
GET /webadmin/api/sites/{site}/assets/{css|js}
PUT /webadmin/api/sites/{site}/assets/{css|js}
Ce point de terminaison met à jour uniquement le thème public prédéfini du site sécurisé utilisé par le rendu public. Envoyez public_theme_preset ou theme avec l'une des valeurs Site::PUBLIC_THEME_PRESETS prises en charge, telles que canvas, atlas, pulse, prism, graphite ou horizon. Utilisez-le lorsque la découverte API affiche un rendu de site avec le mauvais préréglage data-wb-public-theme ; n'essayez pas de remplacer le préréglage par des blocs de contenu.
PATCH /webadmin/api/sites/{site}/branding nécessite site-settings.write et met à jour les champs de marque de site public sécurisés qui sont également visibles dans Sites -> Edit Site -> Branding:
display_nametaglinefavicon_media_id- Le remplacement de
social_image_media_id- Media préserve l'identifiant du média et les références éditoriales, efface les transformations d'image obsolètes et dérive les variantes futures du binaire de remplacement.
Les champs de favicon et d'image sociale doivent faire référence aux enregistrements d'images de la bibliothèque multimédia du CMS, et null efface le média sélectionné. Les modifications apportées aux favicon du site public doivent utiliser ce point de terminaison afin que le résultat reste modifiable par l'administrateur. N'écrasez pas /cms/brand/* ; ces fichiers sont des actifs de produit/shell d'administrateur CMS, et non une marque publique au niveau du site.
PATCH /webadmin/api/sites/{site}/timezone nécessite site-settings.write et définit le propre fuseau horaire d'un site — un identifiant IANA standard tel que Europe/Berlin. Tout ce qui résout l'heure locale de ce site, comme les fenêtres de disponibilité de réservation d'un plugin, est interprété par rapport à cette valeur. Envoyez un timezone vide pour le rétablir dans le fuseau horaire du système à l'échelle de l'installation à partir de Admin -> System Settings.
.
GET /webadmin/api/sites/{site}/assets/{css|js} nécessite site-assets.read et lit le fichier de remplacement canonique au niveau du site physique. Il renvoie relative_path, public_path, exists, contents, checksum, size, updated_at, readiness, guidance et CSS. analysis sans exposer le chemin absolu du serveur. L'objet readiness indique si le répertoire du site, le répertoire des actifs et le fichier sont suffisamment accessibles en écriture pour que le CMS puisse créer ou mettre à jour l'actif. L'objet guidance indique aux outils d'IA/opérateur de conserver le jeton CSS en premier, le mode et le bloc natif en premier. Pour CSS, asset.analysis.mode_awareness signale status, les messages d'avertissement, les clés anti-modèle détectées, les signaux tels que le nombre littéral de couleurs et les jetons --wb-public-* recommandés. PUT /webadmin/api/sites/{site}/assets/{css|js} nécessite site-assets.write et accepte :
contentsexpected_checksum
Le point de terminaison d'écriture utilise le même magasin de fichiers physiques que Sites -> Edit Site -> Assets. Il écrit uniquement public/site/{site_handle}/css/site.css ou public/site/{site_handle}/js/site.js, crée les répertoires manquants lors de la première sauvegarde, rejette les valeurs expected_checksum obsolètes et stocke un instantané de révision avant écrasement avant de remplacer un fichier modifié existant. Il n’existe aucune route de secours de base de données ni aucun rédacteur de chemin /site/... arbitraire. Si les autorisations d'hébergement empêchent la création de répertoires ou l'écriture de fichiers, le point de terminaison renvoie JSON 422 avec errors.0.path = asset.write et les métadonnées de préparation actuelles au lieu d'une erreur de serveur HTML.
Pour les écritures CSS, utilisez la structure/les paramètres de blocs natifs, les champs d'arrière-plan de la bibliothèque multimédia, les jetons de thème publics et les styles de composants WebBlocks UI hérités avant d'ajouter des sélecteurs personnalisés. Si les couleurs personnalisées sont inévitables, définissez des propriétés sémantiques personnalisées avec des valeurs claires et sombres liées aux sélecteurs de mode actif ou aux jetons de thème public afin que les pages publiques restent cohérentes en mode Clair/Sombre/Auto. Évitez les arrière-plans clairs codés en dur sur toute la page, le texte sombre, les cartes blanches ou les palettes uniques en mode sombre lorsque les jetons de thème public peuvent exprimer le design. PUT ne rejette pas les avertissements de détection de mode, car certains systèmes de marque nécessitent des couleurs personnalisées intentionnelles, mais les outils doivent traiter asset.analysis.mode_awareness.status = warning comme un travail à examiner, signaler ou corriger avant d'envisager une migration ou une configuration de nouveau site terminée.
Les commentaires sont supprimés avant analyse : une feuille de style qui se documente en citant la règle qu'elle répare ne signale pas la couleur citée comme l'une des siennes, et une étendue en mode sombre nommée uniquement dans un commentaire ne compte pas comme présente.
Les contrôles anti_patterns concernent la peinture à l'échelle de la page, donc chacun nécessite que son jeton soit le dernier composé du sélecteur et se termine là où se termine le nom : body { background: #fff } est signalé, body .promo { background: #fff } et .wb-public-body { ... } ne le sont pas, et .wb-card-title n'est pas lu comme .wb-card. Une règle qui peint un élément est laissée aux signaux de couleur littérale plutôt que signalée comme un anti-motif à l'échelle de la page.
asset.analysis.mode_awareness est intentionnellement un contrat heuristique, pas un linter CSS. Il signale pass ou warning, warnings, anti_patterns détecté, signals simple tel que les déclarations de couleurs littérales, uses_public_theme_tokens et has_dark_mode_scope, ainsi que les rôles de jeton --wb-public-* recommandés. Les outils doivent utiliser ce signal pour détecter rapidement les régressions en mode mixte probables tout en s'appuyant sur l'assurance qualité visuelle pour la parité de conception finale.
Embedded Application Actifs API
Le code d'application ne doit pas être fusionné dans le code site.css ou site.js global d'un site. Un Embedded Application enregistré peut posséder un CSS physique, un JavaScript et une entrée index.html gérée dans son répertoire public à l'échelle du site :
.
GET /webadmin/api/sites/{site}/applications/{application}/assets
GET /webadmin/api/sites/{site}/applications/{application}/assets/{css|js|html}/{filename}
PUT /webadmin/api/sites/{site}/applications/{application}/assets/{css|js|html}/{filename}
DELETE /webadmin/api/sites/{site}/applications/{application}/assets/{css|js|html}/{filename}
POST /webadmin/api/sites/{site}/applications/{application}/package
CSS et JavaScript utilisent le chemin public déterministe /site/{site_handle}/applications/{application_handle}/{type}/{filename}. Le type HTML accepte uniquement index.html, le stocke à la racine de l'application et renvoie le chemin public stable sélectionné par l'hôte /webblocks-applications/{application_handle}/index.html. L'écriture de cette entrée gérée fait passer la définition en mode iframe et active cette URL. GET, PUT et DELETE nécessitent respectivement applications.read, applications.write et applications.delete. Les noms de fichiers sont uniquement des noms de base et doivent se terminer par l'extension .css, .js ou .html sélectionnée. HTML n'accepte aucun nom de fichier autre que index.html ; le parcours, les chemins imbriqués, les autres types de fichiers et les URL distantes sont rejetés.
PUT accepte contents et expected_checksum. Envoyez null uniquement lors de la création d'un fichier manquant ; lisez d'abord un fichier existant et envoyez sa somme de contrôle lors de son remplacement. Les remplacements et les suppressions préservent les copies de révision. La suppression est refusée alors que la définition Embedded Application fait toujours référence au chemin public de l'actif. Après avoir écrit un actif, utilisez son public_path renvoyé dans css_assets ou js_assets ; le bloc d'application le charge ensuite uniquement là où l'application est placée.
Les applications complètes doivent utiliser le point de terminaison du package au lieu d'écrire les fichiers un par un. Il nécessite applications.write et multipart/form-data avec un champ ZIP package (taille de téléchargement maximale de 50 Mo). Augmentez d'abord le version de l'application enregistrée avec PATCH /webadmin/api/applications/{application} ; puis téléchargez un ZIP contenant index.html à sa racine et utilisez les URL d'actifs relatives à l'intérieur. Une réponse réussie renvoie la version du package, l’immuable entry_url activé, le nombre de fichiers et la taille d’octet étendue, ainsi que la définition d’application actualisée. Les versions installées ne peuvent pas être écrasées. Les échecs de validation et de sécurité d'archivage renvoient des erreurs structurées JSON 422 sous errors[0].path = application_package (ou application_package.package pour le champ multipart).
Endpoints Content Validate / Apply
POST /webadmin/api/content/validatePOST /webadmin/api/content/apply
Content peuvent attribuer des enregistrements de bibliothèque multimédia CMS déjà téléchargés à des blocs sauvegardés sur des supports natifs. Utilisez media_id ou asset_id sur les blocs image, navbar-brand, sidebar-brand, file, download et video avec des supports du type correspondant. Utilisez media_id ou asset_id sur hero, section, card, cta et content_header lorsque le média est l'image d'arrière-plan du bloc, avec settings.background_position et settings.background_overlay en option. Utilisez gallery_items ou gallery_media_ids sur les blocs gallery avec des enregistrements multimédias d'images ; le API conserve l'ordre des éléments de la Galerie soumis lors de l'écriture de block_media.position. Pour les images de contenu de carte, créez la structure imbriquée normale, telle que card -> card_body -> image, et placez media_id sur le bloc enfant image. Les plans de contenu rejettent toujours remote_url et source_url ; téléchargez des fichiers via POST /webadmin/api/media ou importez d'abord une URL de fichier public approuvée via POST /webadmin/api/media/fetch, puis attribuez le media.id.
renvoyé.
Sécurité Des Plans De Contenu
Les plans utilisent des modes explicites de brouillon ou de mise à jour préparée. Validez avant application et gardez la publication comme opération autorisée séparément. Une page publique exige sa propre mise à jour préparée, sans remplacement direct.
Un plan peut référencer des médias approuvés. Récupérations distantes, téléversements et autres opérations ont leurs endpoints et capacités ; le plan n’accorde pas ces droits. Découvrez les endpoints actuels avant modification.
Les écritures JSON Bearer-token utilisent l’autorisation du token. La découverte minimale non authentifiée n’accorde aucun accès au contenu. Consultez Authentication et Capabilities pour le périmètre requis.
Forme des erreurs JSON
Les erreurs de l'API sont uniquement en JSON. Elles ne doivent pas rediriger vers la page de connexion, afficher des pages CSRF ni exposer de traces de pile. Champs courants :
{
"ok": false,
"code": "invalid_internal_api_token",
"message": "Invalid internal API token.",
"api_discovery_url": "/webadmin/api",
"openapi_url": "/webadmin/api/openapi.json",
"documentation_url": "/webadmin/api/ai-guide",
"example_url": "/webadmin/api/examples/contact-page",
"errors": []
}
Statuts attendus :
401 invalid_internal_api_tokenpour les jetons manquants, invalides, révoqués, expirés ou qui ne sont plus sauvegardés par l'utilisateur403 missing_internal_api_capabilitypour les fonctionnalités manquantes403 delegated_site_access_deniedlorsqu'un jeton personnel cible un site en dehors de sa portée active403 delegated_workflow_access_deniedlorsque le propriétaire ne peut pas modifier la page dans son état de flux de travail actuel403 delegated_operation_deniedpour les opérations au niveau de l'installation qui rejettent les tokens403 delegated_network_access_deniedlorsque l'adresse IP résolue se trouve en dehors de la liste d'autorisation des jetons personnels429 personal_api_token_rate_limit_exceededlorsque le plafond personnel est atteint ; les clients doivent honorerRetry-After422pour les erreurs de validation
Exemples de Resource API
Rendre l'instantané administrateur des mises à jour du système
GET /webadmin/api/admin-render/system-updates
GET /webadmin/api/admin-render/system-updates?format=html
Nécessite admin.render et un jeton créé par un utilisateur pouvant accéder à System. La réponse JSON inclut l'administrateur rendu HTML pour l'écran System Updates sur liste verte ; ?format=html renvoie directement text/html afin que les outils de l'opérateur puissent charger l'instantané dans un navigateur local et capturer des captures d'écran pour une comparaison visuelle. Le point de terminaison est en lecture seule et ne doit pas cliquer, installer, publier ou modifier l'état de mise à jour.
Lister les pages
GET /webadmin/api/pages
Lire le détail d'une page
GET /webadmin/api/pages/{page}
Lire les commentaires de mission
GET /webadmin/api/engagement/comments?status=pending&per_page=25
Nécessite engagement.read. Les filtres pris en charge sont status, site_id, page_id, block_id, search et per_page. Les réponses incluent le corps du commentaire, le statut, le score/les raisons du spam, les références de page source/de bloc et les horodatages, mais n'exposent pas les hachages des visiteurs, les hachages IP ou les valeurs de l'agent utilisateur.
Commentaire sur l’engagement modéré
PATCH /webadmin/api/engagement/comments/{comment}
Content-Type: application/json
{"status":"approved"}
Nécessite engagement.moderate. Les statuts pris en charge sont pending, approved, rejected, spam et hidden.
.
Lire les notes d'engagement
GET /webadmin/api/engagement/ratings?block_id=123
Nécessite engagement.read. Les filtres pris en charge sont status, site_id, page_id, block_id et per_page. Les réponses incluent des lignes d'évaluation ainsi que des résumés du total, de la moyenne et du nombre de valeurs, mais n'exposent pas les hachages des visiteurs, les hachages IP ou les valeurs de l'agent utilisateur.
Lister les blocs
GET /webadmin/api/blocks
Lire le détail d'un bloc
GET /webadmin/api/blocks/{block}
Exemple de Content Validate / Apply
Le même payload peut être envoyé à l'un ou l'autre endpoint :
POST /webadmin/api/content/validate
POST /webadmin/api/content/apply
Exemple de brouillon de page d'accueil marketing en anglais :
{
"plan": {
"site": "example-site",
"locale": "en",
"layout": "default",
"page": {
"title": "Acme Studio",
"path": "/",
"status": "draft"
},
"slots": {
"main": [
{
"type": "section",
"children": [
{
"type": "container",
"children": [
{
"type": "content_header",
"translations": {
"title": "Plan, build, and publish with confidence",
"subtitle": "Structured content for modern teams",
"content": "Create a draft homepage from a validated content plan."
}
},
{
"type": "cluster",
"children": [
{
"type": "button_link",
"translations": {
"title": "Start planning"
},
"settings": {
"url": "/contact",
"variant": "primary"
}
}
]
}
]
}
]
},
{
"type": "section",
"children": [
{
"type": "container",
"children": [
{
"type": "grid",
"settings": {
"columns": 3
},
"children": [
{
"type": "card",
"children": [
{
"type": "card_body",
"children": [
{
"type": "plain_text",
"translations": {
"content": "Validate the whole draft before anything is written."
}
}
]
}
]
}
]
}
]
}
]
},
{
"type": "section",
"children": [
{
"type": "container",
"children": [
{
"type": "cta",
"translations": {
"title": "Ready to shape the next page?",
"content": "Use structured plans for repeatable content creation."
}
},
{
"type": "cluster",
"children": [
{
"type": "button_link",
"translations": {
"title": "Contact us"
},
"settings": {
"url": "/contact",
"variant": "primary"
}
}
]
}
]
}
]
}
]
}
}
}
Règles de validation
- les champs du plan que le API ne comprend pas sont rejetés avec
422et le code stableunsupported_plan_fields, et le chemin d'erreur nomme chacun d'entre eux ; le jeu de clés accepté est limité au planmode, donc une clé significative dans un mode est toujours rejetée dans un autre - Le handle ou l'ID du site doit être résolu
- les paramètres régionaux doivent exister et être activés pour le site cible
- la mise en page doit exister
- un conflit de chemin bloque la création de pages
- le type de bloc doit être publié et utilisable
- la pension alimentaire pour enfants doit suivre les contrats groupés lorsqu'ils sont disponibles
- Les arborescences de blocs de plan de contenu doivent utiliser des éléments imbriqués
children; platid,parent_id,block_id,slot_type_id, etblock_type_idles champs de relation sont rejetés car le API possède les ID de base de données et l'affectation parent - bloc
translationsdoit contenir des clés de champ directes pour les paramètres régionaux du plan sélectionnés, telles quetitle,subtitle, etcontent; formes à clé locale telles quetranslations.en.titlesont rejetés au lieu d’être silencieusement ignorés - blocs d'emballage tels que
section,container,stack,split,cluster,grid,card,card_body,card_footer,sticky-navbar, etsidebar-navigationdoit inclure des blocs enfants afin qu'ils ne puissent pas être validés en tant que chrome public vide ;splitnécessite exactement deux enfants directs, et chaque côté peut être un groupe imbriquéstack - le texte destiné à l'utilisateur appartient aux lignes de traduction
- les paramètres partagés restent partagés
- Les paramètres de base nouveaux ou modifiés doivent correspondre au schéma de création par bloc découvert ; les champs inconnus et les valeurs invalides sont rejetés avec les chemins de champ
- les paramètres historiques inconnus restent lisibles et survivent aux mises à jour sans rapport ; une valeur exacte inchangée peut accompagner PATCH mais n'autorise pas la modification d'un champ non déclaré
- apply valide à nouveau avant d'écrire
- postuler est transactionnel
- L'application de contenu rejette toujours les opérations de publication, de création de site, d'importation de médias, de récupération à distance, d'écrasement non pris en charge, de remplacement et de suppression non pris en charge.
- La création de Shared Slot reste en création uniquement, à moins qu'une phase ultérieure n'ajoute des contrats de mutation explicites sans brouillon.
- les points de terminaison des ressources des éléments de navigation prennent en charge les opérations explicites de mise à jour, de visibilité, de réorganisation et de suppression en dehors du contenu s'appliquent avec des gardes de capacités
Forme de la réponse
Les réponses doivent être un JSON prévisible :
{
"ok": true,
"writes": [],
"data": {
"page": {
"id": 123,
"title": "Product Overview",
"status": "draft",
"edit_url": "/webadmin/pages/123/edit"
}
},
"normalized_plan": {},
"renderability": {
"root_blocks": 3,
"total_blocks": 12,
"html_blocks": 0,
"wrapper_blocks_without_children": 0,
"text_blocks_without_visible_content": 0,
"button_blocks_without_label_or_url": 0
},
"warnings": [],
"errors": []
}
Les erreurs de validation doivent inclure un chemin et un message :
{
"ok": false,
"writes": [],
"data": null,
"normalized_plan": {},
"renderability": {
"root_blocks": 2,
"total_blocks": 3,
"html_blocks": 0,
"wrapper_blocks_without_children": 1,
"text_blocks_without_visible_content": 0,
"button_blocks_without_label_or_url": 0
},
"warnings": [
{
"path": "plan.slots.main.1.settings.theme",
"message": "Unknown harmless setting ignored."
}
],
"errors": [
{
"path": "plan.page.path",
"message": "A page already exists at this path for the selected site and locale."
}
]
}
Inclure edit_url lorsque cela est utile pour les ressources CMS créées ou mises à jour.
renderability est un résumé de l'intégrité du plan pour les outils d'IA/opérateur. Un plan de page structuré réussi doit normalement avoir wrapper_blocks_without_children, text_blocks_without_visible_content et button_blocks_without_label_or_url à 0. html_blocks au-dessus de 0 signifie que le plan a utilisé la trappe d'évacuation de confiance HTML ; les outils ne doivent le faire qu'avec l'approbation explicite de l'opérateur et uniquement lorsque les types de blocs de première classe ne peuvent pas représenter le contenu.
Sections Supplémentaires Du Plan
Les plans de contenu peuvent inclure navigation_menus, shared_slots et page_slot_shared_slots aux côtés du plan pages/slots existant. validate n'écrit rien. apply écrit toutes les sections valides dans une seule transaction et annule l'ensemble du plan dès qu'une section ultérieure échoue.
{
"plan": {
"site": "default",
"locale": "en",
"layout": "default",
"page": {
"title": "Homepage Draft",
"path": "/",
"status": "draft"
},
"slots": {
"main": []
},
"navigation_menus": [
{
"handle": "primary",
"label": "Primary Navigation",
"items": [
{
"label": "Home",
"url": "/",
"target": "_self",
"sort_order": 10
},
{
"label": "About",
"link_type": "page",
"page_id": 9
},
{
"label": "Docs",
"link_type": "group",
"children": [
{ "label": "Intro", "url": "/docs/intro" },
{ "label": "Guide", "url": "/docs/guide" }
]
}
]
}
],
"shared_slots": [
{
"handle": "site-header",
"label": "Site Header",
"slot": "header",
"blocks": []
}
],
"page_slot_shared_slots": [
{
"page": "created",
"slot": "header",
"shared_slot": "site-header"
}
]
}
}
Les éléments de navigation portent link_type : custom_url (la valeur par défaut nécessite un chemin interne sécurisé ou une URL http(s)), page (nécessite page_id pour une page du même site ; l'étiquette revient au nom de la page) ou group (une étiquette qui ouvre ses enfants et ne porte aucune URL). Seul un group accepte les children, qui sont créés avec leur parent_id déjà lié, donc une liste déroulante est un plan plutôt qu'un POST plus un PATCH par article. Les plans de contenu s'imbriquent sur un niveau ; les arbres plus profonds utilisent POST /navigation-menus/{menu}/items. Un link_type non pris en charge est refusé nommément au lieu d'être contraint à custom_url.
page_slot_shared_slots[].page peut faire référence à la page créée par le même plan en utilisant created, ou à un ID de page existant. shared_slot peut faire référence à un Shared Slot créé précédemment dans le même plan ou à un handle Shared Slot existant sur le même site.
Les plans
Content enregistrent une version de page terminée après toutes les écritures de bloc et les affectations Shared Slot, ainsi qu'une version terminée par Shared Slot nouvellement créé. Les plans d’attribution de pages existantes enregistrent une version de sécurité avant modification par page concernée. Le remplacement des créneaux horaires et la promotion par étapes conservent leurs points de contrôle de sécurité explicites. Une capture consécutive inchangée réutilise le dernier instantané complet et enregistre un événement de capture distinct ; les requêtes HTTP indépendantes restent des opérations distinctes. Les lectures détaillées de la version incluent inspection.capture_history délimité contenant les événements de capture récents et un indicateur has_more. Voir Révisions.
Images mobiles facultatives (1.91.0)
slide, image, hero, section, card, cta, content_header et link-list-item acceptent un niveau supérieur en option. mobile_media_id contenant un identifiant de bibliothèque multimédia d'images dans les plans de contenu et PATCH /blocks/{block}. La relation est stockée dans block_media avec le rôle mobile_image et est partagée entre les paramètres régionaux. Omettez le champ dans PATCH pour le préserver ; envoyez null pour l'effacer.
APour des largeurs de fenêtre allant jusqu'à 768 px, une image mobile publique remplace l'image par défaut. S'il est absent, supprimé ou privé, le moteur de rendu conserve la valeur par défaut. Les images de premier plan utilisent une source picture réactive ; les blocs d'arrière-plan changent d'arrière-plan CSS. Utilisez un recadrage différent du même visuel, car le texte alternatif, la légende, la position, l'ajustement, la superposition et le lien restent partagés. La visionneuse de galerie du bloc Image ouvre toujours l'image pleine résolution par défaut. Les éléments de la galerie, les logos de marque, les vidéos et les fichiers audio n'acceptent pas ce champ.
{
"locale": "en",
"mobile_media_id": 456
}
Slide et Slider settings.content_position prennent en charge neuf valeurs de la version 1.91.1 : center, center-left, center-right, top-left, top-center, top-right, bottom-left, bottom-center et bottom-right.
Conseils d'utilisation avec l'IA
- découvrez d'abord les sites, les langues (locales), les layouts et les types de bloc
- validez avant d'appliquer
- créez du contenu en brouillon
- privilégiez les blocs structurés de
docs/public-block-render-markup.md - évitez Safe HTML, sauf comme solution de repli relue
- rédigez le texte public généré dans la langue cible, par exemple l'anglais pour une page d'accueil en anglais
Limites
- aucune intégration OpenAI ou LLM dans le cœur du CMS
- aucun crawl ni récupération de contenu
- aucun remplacement arbitraire de l'import/export
- aucune publication automatique
- aucune suppression destructrice en phase 1
- aucune hypothèse sur la route
/adminde l'hôte - aucun usage du préfixe de route
/cms - aucun code d'exécution propre à QuizTem ; la génération de la page d'accueil de QuizTem est un cas d'usage ultérieur de cette API CMS générique
État du système de toute l’installation
Depuis le CMS 1.98.0, GET /webadmin/api/system/health renvoie { "ok": true, "health": { ... } } via la fonctionnalité explicite system-health.read. Seul un jeton système sans restriction avec un créateur actif disposant actuellement d'un accès au système est accepté. Les jetons personnels, révoqués, expirés et limités au site sont exclus ; la fonctionnalité n'est pas incluse dans l'ensemble de création de contenu par défaut.
Facultatif site_id doit identifier un site existant. Il filtre les vérifications du site, de la recherche et du travail planifié tandis que les vérifications à l'échelle de l'installation restent dans la réponse. Le rapport comprend checked_at, scheduler_checked_at, des preuves en direct scheduler, cache_seconds (300), selected_site_id, site_options, sites, categories, counts, classés par gravité. issues, informations système information et operations récent. Les états de vérification sont healthy, warning, critical, unknown et not_applicable. Les contrôles exposent un code stable, une clé message à traduction contrôlée et un parameters, ainsi que les administrateurs route et route_parameters pour le suivi.
L'objet scheduler contient les horodatages status, scheduler_status, notification_status, UTC last_seen_at, last_completed_at et last_failed_at, stale_after_seconds (300) et required dérivés des sites filtrés. La lecture réutilise l'instantané de présentation de cinq minutes et lit en direct les preuves enregistrées du planificateur. Il ne contacte pas le serveur de versions et n'exécute pas de maintenance. Les preuves manquantes sont signalées comme inconnues ou sans objet selon que le site nécessite ou non une planification. La disponibilité des archives ne certifie pas l'intégrité de la restauration ; La couverture de recherche ne certifie pas la fraîcheur du texte indexé. Les résultats de l'opération omettent les journaux, les résumés bruts, les chemins d'archives et le texte d'exception. Voir Operations pour une présentation destinée à l'opérateur.
Mises à jour du système à l'échelle de l'installation
Depuis la version 1.90.0, explicitement accordé system-updates.read et
Les capacités system-updates.run exposent des contrôles de mise à jour, approuvés de manière synchrone
exécution et résultats d’exploitation durables. Les jetons personnels et à l'échelle du site sont
exclus. Suivre le contrat API System Updates
pour l'approbation exacte de la version/de la somme de contrôle, l'idempotence et la récupération en cas de perte de connexion.
Politique de notification des messages du site partagé (CMS 1.95.0)
GET /webadmin/api/sites/{site}/notifications nécessite content.read et renvoie le notification_settings résolu, regroupe delivery_status pour les événements de message des trente derniers jours et les derniers résultats summary_delivery_status. Chaque demande applique les restrictions du site de jetons ; les jetons délégués conservent également l’accès actuel au site de leur propriétaire.
PATCH /webadmin/api/sites/{site}/notifications nécessite site-settings.write. Il s'agit d'un paramètre de l'opérateur, indépendant de l'édition du contenu du bloc. Il fusionne les champs fournis, préserve les paramètres omis et rejette les champs inconnus, les valeurs nulles et les valeurs non prises en charge.
{
"notification_mode": "alert_only",
"notification_frequency": "batched",
"batch_minutes": 10,
"daily_summary": true,
"summary_hour": 9
}
Les valeurs prises en charge sont full/alert_only et immediate/batched/daily ; les intervalles de lots sont de 1 à 60 minutes et les heures quotidiennes sont de 0 à 23 dans le fuseau horaire du site. Les notifications d'alerte uniquement excluent le contenu, les adresses, les sujets, les en-têtes et les pièces jointes dérivés des visiteurs. Les résumés quotidiens contiennent toujours uniquement des décomptes et des liens de boîte de réception protégés. Le planificateur hôte Laravel traite les lots et les résumés toutes les minutes ; les notifications n'accordent pas l'accès à la boîte de réception.
Live Chat 0.7.0 expose la stratégie héritée en tant que notification_policy sur les paramètres de lecture et d'écriture. Configurez ses notify_offline_messages et notification_email via l'API des paramètres du plugin ; modifier la confidentialité et la fréquence via le point de terminaison du site partagé. Les tentatives visant à remplacer la politique partagée via le point de terminaison du plug-in sont rejetées. D'autres plugins activés peuvent s'intégrer via le contrat d'adaptateur SiteNotificationChannel appartenant au produit.
Santé du planificateur (CMS 1.95.1)
La réponse GET de stratégie de notification inclut également scheduler_health, avec status, scheduler_status, notification_status, last_seen_at, last_completed_at, last_failed_at, stale_after_seconds (300) et la stratégie de site dérivée. required booléen. Les États distinguent healthy, unverified, delayed, running, failed et unavailable. Les horodatages sont au format UTC et ne contiennent que des preuves d'exécution ; Les lectures d'API ne génèrent pas de battement de cœur et ne modifient pas les paramètres. Les contrôles de portée et de capacité restent inchangés.
Un rappel planifié récemment et une exécution de notification terminée sont requis pour vérifier l'état de santé. L'expédition manuelle est enregistrée séparément et ne peut certifier la planification. Les paramètres du tableau de bord/du site avertissent lorsque la politique de notification du site nécessite une planification mais que le temps d'exécution enregistré n'est pas vérifié, retardé, échoué ou indisponible. Les réponses aux paramètres de Live Chat 0.7.1 et l’état du plugin utilisent les mêmes preuves enregistrées. Les exigences générales de configuration et la propriété de l'administrateur du serveur sont décrites dans Installation.
Schémas de paramètres de création par bloc
Le catalogue complet, les responsabilités de stockage et les contrats de rendu figurent dans Contrats des types de blocs. Les schémas complètent l’Inventaire CMS ; ils n’accordent aucun accès et ne rendent pas modifiable par API un bloc réservé à l’édition humaine.
À partir de CMS 1.105.9, la découverte des types de blocs et les contrats de contenu incluent un objet supplémentaire authoring_settings_schema. Les anciens formats de réponse settings_schema sont conservés. La révision 1 couvre tous les blocs core publiés et expose mode, unknown_fields et fields. Chaque champ décrit son type, ses choix et limites de plage/longueur, son effacement par null ou valeur vide, la conservation des champs omis lors des mises à jour et les décisions distinctes writes.admin, writes.create et writes.patch, avec le motif closed_reason le cas échéant.
Lisez ces indicateurs d'opération avant d'écrire. Un champ accepté lors de la création d'un bloc n'est pas automatiquement accessible en écriture via PATCH. Les champs de livraison/confidentialité des contacts conservent leurs exclusions PATCH existantes, HTML reste uniquement humain et les références médiatiques utilisent leurs champs de relation dédiés. Les schémas de champ n'accordent aucune autorisation et n'interrogent pas les fournisseurs de contenu externes.
Les plans de contenu et le bloc d'emplacement POST rejettent les clés inconnues et les valeurs fournies non valides avant l'écriture. PATCH valide uniquement les modifications et les fusionne avec les paramètres actuels. Un aligment mal orthographié est rejeté au lieu d'accepter une valeur qui n'a aucun effet visible ; une valeur alignment non valide est rejetée au lieu d'effacer silencieusement le choix existant. Les valeurs manquantes n'insèrent pas les valeurs par défaut lors des mises à jour. Les alias de compatibilité déclarés restent pris en charge : le curseur fade se normalise en slide, la galerie masonary en masonry et les clés de copie du formulaire de contact existantes dans les paramètres de création sont utilisées par l'éditeur de traduction locale. PATCH utilise translations pour cette copie. Les valeurs entières ne sont pas bloquées silencieusement et le texte trop long n'est pas tronqué silencieusement. Les valeurs par défaut de création existantes telles que les colonnes plain et Split stack restent.
HLes valeurs historiques inconnues ou mal formées restent lisibles, s'affichent avec les solutions de secours existantes et survivent aux mises à jour non liées. Un client peut transporter un champ historique identique uniquement lorsque le serveur peut le comparer avec ce bloc existant exact ; cela n'autorise pas l'ajout ou la modification de paramètres inconnus. Les nouveaux blocs et les charges utiles de remplacement complet sont une nouvelle création, ils ne peuvent donc pas revendiquer une exception de valeur historique. Le clonage fiable, le transfert et la restauration de révision conservent leurs chemins de stockage sans perte.
Les plug-ins sans schéma conservent leur propre comportement de paramètres existant. Les plugins peuvent s'inscrire via la définition de bloc ou se manifester avec des règles scalaires ; une déclaration non valide bloque l'écriture pour ce schéma sans bloquer les blocs principaux non liés. Les paramètres d'application, les icônes actives et les liaisons Dynamic Content continuent d'utiliser leurs validateurs spécialisés après la vérification des champs communs.
Les opérateurs de serveur peuvent exécuter php artisan webblocks:blocks:audit-settings pour obtenir un rapport de compatibilité en lecture seule avant de créer du contenu existant. Il imprime les identités, les chemins de champ et les codes plutôt que les valeurs des paramètres, analyse sans réparation ni requête du fournisseur et quitte 1 si des paramètres incompatibles existent. --limit=100 limite les blocs signalés (maximum 1 000) ; le résumé compte toujours l'analyse complète. Cela vérifie la compatibilité du schéma scalaire, et non l’état du fournisseur externe ou de l’application. Les plugins sans schéma sont comptés séparément. Les nouveaux paramètres déclarés modifiés sont limités à 128 champs, 256 KiB, 32 niveaux imbriqués et 4 096 nœuds sans appliquer ces limites rétrospectivement aux données historiques inchangées.