Documentation

API et pilotage par IA.

Un site JEIKO se conduit à la main depuis son administration, ou par programme. Cette page décrit la seconde voie : comment un agent travaille, ce qu'on lui confie, et les 65 routes dont il dispose.

Documentation généraleInstallation

Ce qu'est un agent, et ce qu'il n'est pas

Un agent n'a pas d'accès privilégié au site. Il reçoit un mandat — un jeton, des rôles, une échéance, un plafond d'appels — et passe par les mêmes contrôles que l'administrateur qui travaille à la main dans l'interface. Il ne touche jamais la base directement : il n'y a pas de porte dérobée à ouvrir, et rien à refermer si le mandat vous échappe.

Concrètement, cela veut dire trois choses.

  1. Le mandat est borné dans le temps. Une clé porte une date d'expiration. Passée cette date elle ne vaut plus rien, sans qu'on ait à penser à la révoquer.
  2. Le mandat est borné en portée. Huit rôles, accordés séparément. Un agent qui rédige des pages n'a aucune raison de lire les rendez-vous pris, et ne le peut pas.
  3. Le mandat est borné en débit. Un plafond horaire, réglé par agent. Une boucle qui s'emballe s'arrête d'elle-même.

Le mode d'emploi est généré

L'agent commence par lire GET /. Ce document n'est pas rédigé à la main : les routes sont lues dans le routeur, les permissions sur les vues, les types de blocs dans le modèle. Il ne peut donc pas décrire une API qui n'existe plus.

Tout est consigné

Chaque appel laisse une ligne dans le journal : l'agent, la route, l'objet touché, l'issue. On sait après coup qui a écrit quoi, et l'écran d'administration le montre sans qu'on ait à lire des fichiers sur le serveur.

Les refus sont explicites

Une clé inconnue dans un corps de requête est refusée, jamais avalée en silence. C'est la différence entre un appel qui échoue et qu'on corrige, et un appel qui réussit sans rien produire — le défaut le plus coûteux qui soit.

L'agent ne peut pas supprimer une page, ni en publier une sans un acte explicite. Ces deux limites ne sont pas des oublis : une page supprimée ne se retrouve pas, et une mise en ligne est une décision éditoriale.

Créer un agent depuis l'administration

Le premier appel

Le mode d'emploi vit à la racine de l'API. Il est généré depuis le code — les routes sont lues dans le routeur, les permissions sur les classes de vue, les options des blocs dans les constantes que le rendu applique. Il ne peut donc pas décrire une route qui n'existe pas, ni taire une permission.

GET https://votresite.fr/api/agent/v1/
Authorization: Bearer jk_ag_<préfixe>_<secret>

{
"version": { "numero": "1" },
"points_d_entree": [ … chaque route, avec sa permission … ],
"catalogue_des_blocs": { … chaque type de contenu … },
"champs_de_page": { … },
"interdits": [ … ]
}

Authentification

Un jeton porteur, et lui seul. Sept gardes s'empilent avant qu'un appel n'atteigne une vue.

  1. HTTPS obligatoire — un jeton ne circule pas en clair
  2. En-tête Authorization uniquement : jamais dans l'URL, où il finirait dans les journaux du serveur et l'historique du navigateur
  3. La session n'authentifie pas. Un administrateur connecté sans jeton est refusé comme un inconnu — c'est ce qui rend l'exemption CSRF de ces vues légitime au lieu d'être un trou
  4. Comparaison à temps constant, agent actif, expiration, liste d'adresses autorisées, plafond d'appels
  5. Le secret n'est jamais enregistré — seule son empreinte SHA-256 l'est. Une base lue ne livre aucun accès

Les refus ne s'expliquent pas : même message, même code, quelle que soit la cause. Le motif précis va au journal, qui est pour l'exploitant — le distinguer apprendrait à un appelant hostile où il en est.

Les routes

Chacune annonce la permission qu'elle exige : un agent sait avant d'appeler s'il en a le droit, plutôt que de le découvrir sur un refus.

MéthodeCheminRôlePermission
GET/Ce mode d'emploi. À lire en premier.aucune — un jeton valide suffit
GET/guide/Le même mode d'emploi, à une adresse qui se retient.aucune — un jeton valide suffit
GET/contrats/La forme exacte de chaque appel : description, schéma JSON du corps et des filtres, chaque champ décrit.aucune — un jeton valide suffit
GET/qui-suis-je/Qui je suis et ce que j'ai le droit de faire.aucune — un jeton valide suffit
GET/pages/La liste des pages du site.administration_pages.view_page
POST/pages/creer/Créer une page. Elle naît en brouillon.administration_pages.add_page
GET, PATCH/pages/<int:page_id>/L'arbre complet d'une page ; PATCH modifie ses champs.administration_pages.view_page
POST/pages/<int:page_id>/sections/Ajouter une section à une page.administration_pages.change_page
POST/pages/<int:page_id>/versions/Créer la version d'une page dans une langue, par duplication — brouillon, à traduire à la main.administration_pages.add_page
GET, PATCH/langues/Le site en plusieurs langues : l'option et les langues ajoutées. Retirer une langue DÉPUBLIE ses pages et ses fiches.administration.view_website
GET/pages/<int:page_id>/mesures/Scores PageSpeed, Core Web Vitals et audits ratés. Lecture seule ; mesure_obsolete signale une URL différente de l'URL actuelle.administration_pages.view_page
GET, PATCH, DELETE/sections/<int:section_id>/Une section et ses paramètres.administration_pages.change_page
POST/sections/<int:section_id>/lignes/Ajouter une ligne à une section.administration_pages.change_page
GET, PATCH, DELETE/lignes/<int:ligne_id>/Une ligne et ses paramètres.administration_pages.change_page
POST/lignes/<int:ligne_id>/blocs/Ajouter un bloc dans une colonne de la ligne.administration_pages.change_page
GET, PATCH, DELETE/blocs/<int:bloc_id>/Un bloc et ses paramètres.administration_pages.change_page
PUT/blocs/<int:bloc_id>/contenu/Poser ou remplacer le contenu d'un bloc.administration_pages.change_page
POST/deplacer/<str:niveau>/<int:element_id>/Monter ou descendre une section, une ligne ou un bloc ; ou envoyer une ligne dans une autre section (« vers_section »), un bloc dans une autre ligne (« vers_ligne », « colonne »).administration_pages.change_page
GET/images/La médiathèque, en lecture. Donne les identifiants à réutiliser.administration_pages.view_page
POST/images/creer/Envoyer une image dans la médiathèque : en JSON avec « fichier_base64 » (ce qu'utilise le serveur MCP), ou en multipart avec « fichier ». Plus titre, alt ou decorative.administration_pages.add_imagecontent
GET/rdv/types/Les types de rendez-vous. Leur durée découpe les disponibilités.calendars.view_appointmenttype
POST/rdv/types/creer/Créer un type de rendez-vous.calendars.add_appointmenttype
GET, PATCH/rdv/types/<int:type_id>/Un type : durée, capacité, prix, liste d'attente.calendars.view_appointmenttype
GET/rdv/disponibilites/Les plages déclarées disponibles.calendars.view_availability
POST/rdv/disponibilites/creer/Déclarer une plage — elle GÉNÈRE ses créneaux.calendars.add_availability
GET, PATCH, DELETE/rdv/disponibilites/<int:dispo_id>/Une plage. La suppression est refusée si des rendez-vous y sont pris.calendars.view_availability
GET/rdv/creneaux/Les créneaux générés — LECTURE SEULE. Filtres : type, depuis, jusqu_a, ouverts.calendars.view_availability
GET/rdv/Les rendez-vous pris. Lecture seule, permission à part : données personnelles.calendars.view_appointment
GET/menus/Les menus, leur arborescence et les catégories qu'ils servent.administration_menu.view_menu
POST/menus/creer/Créer un menu — « copie_de » duplique un existant, arborescence comprise.administration_menu.add_menu
GET, PATCH/menus/<int:menu_id>/Un menu ; envoyer « elements » REMPLACE son arborescence.administration_menu.view_menu
PATCH/categories/<int:categorie_id>/menus/Affecter les menus d'une catégorie — c'est ce qui fait les sous-sites.administration_menu.change_menu
GET, PATCH/identite/Les couleurs du thème et les polices du site. Modification partielle.administration.view_website
GET/emails/evenements/Les 67 événements d'e-mail et LEURS CLÉS. À lire avant d'écrire un e-mail.emailing.view_emailtemplate
GET/emails/Les e-mails configurés.emailing.view_emailtemplate
POST/emails/creer/Habiller un événement : sujet, page de corps (non publiée, ou déjà gabarit d'e-mail — une page en ligne est refusée : elle disparaîtrait du site). Naît INACTIF.emailing.add_emailtemplate
GET, PATCH/emails/<int:email_id>/Un e-mail : sujet, corps, expéditeur, activation.emailing.view_emailtemplate
GET/questionnaires/Les questionnaires experts.questionnaires_expert.view_experttest
POST/questionnaires/creer/Créer un questionnaire. Il naît INACTIF.questionnaires_expert.add_experttest
GET, PATCH/questionnaires/<int:test_id>/L'arbre complet : profils, questions, réponses, poids, combinaisons.questionnaires_expert.view_experttest
POST/questionnaires/<int:test_id>/profils/Ajouter un profil — un résultat possible, avec sa page.questionnaires_expert.change_experttest
POST/questionnaires/<int:test_id>/questions/Ajouter une question, ses réponses et leurs poids.questionnaires_expert.change_experttest
POST/questionnaires/<int:test_id>/combinaisons/Ajouter une combinaison — l'arbitrage entre deux profils proches.questionnaires_expert.change_experttest
POST/questionnaires/<int:test_id>/simuler/Mode « dimensions » : composer la page de résultat pour des scores donnés, sans rien enregistrer.questionnaires_expert.view_experttest
PATCH/profils/<int:profil_id>/Un profil. Son slug ne se modifie pas : il est dans l'URL du résultat.questionnaires_expert.change_experttest
PATCH, DELETE/questions/<int:question_id>/Une question ; envoyer « reponses » REMPLACE la liste, poids compris. Suppression refusée si le test a déjà été passé.questionnaires_expert.change_experttest
DELETE/reponses/<int:reponse_id>/Supprimer une réponse seule, sans réécrire les autres.questionnaires_expert.change_experttest
PATCH/combinaisons/<int:combinaison_id>/Une combinaison et ses critères.questionnaires_expert.change_experttest
GET/categories/Les catégories et sous-catégories, avec leurs slugs.administration_pages.view_page
POST/categories/creer/Créer une catégorie. « afficher_dans_l_url » la met dans l'adresse des pages.administration_pages.add_page
GET, PATCH, DELETE/categories/<int:categorie_id>/Corriger une catégorie. Le slug ne change pas : il est dans les adresses. La suppression n'accepte qu'une catégorie VIDE.administration_pages.change_page
GET/modeles/Les types de fiches et leurs champs. À lire avant d'en créer une.custom_objects.view_customobject
POST/modeles/creer/Créer un type de fiche avec ses champs, et marquer sa page gabarit.custom_objects.add_customobjectmodel
GET, PATCH/modeles/<int:modele_id>/Un type de fiche ; PATCH AJOUTE des champs, n'en renomme aucun.custom_objects.view_customobject
GET/types-de-produit/Les types de produit — la couche commerciale.shop.view_producttype
POST/types-de-produit/creer/Créer un type de produit. « expedition » décide s'il consomme du stock.shop.add_producttype
GET, PATCH/types-de-produit/<int:type_id>/Corriger un type de produit. Le code ne change pas : il est dans les URL.shop.view_producttype
GET/objets/Les fiches existantes. `?modele=<id-ou-slug>` pour filtrer, `?langue=en` pour les seules versions d'une langue.custom_objects.view_customobject
GET/fiches/Alias métier de `/objets/` : les fiches existantes, avec le même filtre `?modele=<id-ou-slug>`.custom_objects.view_customobject
POST/objets/creer/Créer une fiche. Elle naît non publiée.custom_objects.add_customobject
GET, PATCH/objets/<int:objet_id>/Une fiche et ses valeurs ; PATCH en modifie une partie.custom_objects.view_customobject
POST/objets/<int:objet_id>/versions/Créer la version d'une fiche dans une langue, par duplication — non publiée, à traduire à la main.custom_objects.add_customobject
GET/produits/Les produits.shop.view_product
POST/produits/creer/Créer un produit sur une fiche existante.shop.add_product
GET, PATCH/produits/<int:produit_id>/Un produit : référence, prix, TVA, stock.shop.view_product

Les huit rôles

Un mandat par domaine, accordé et retiré séparément. On ne donne pas à un agent qui rédige des pages le droit de lire les rendez-vous pris.

  1. Agent éditeur de pages — créer et modifier des pages. Jamais en supprimer
  2. Agent fiches et boutique — types de fiche, fiches, produits, types de produit
  3. Agent menus — navigation et affectation aux catégories, ce qui permet des sous-sites
  4. Agent design — couleurs et polices. Une erreur ici abîme toutes les pages à la fois : c'est un mandat à part
  5. Agent e-mails — sujet et corps des messages transactionnels. Aucun accès aux journaux d'envoi
  6. Agent questionnaires — construire un test. Aucun accès aux passages ni aux prospects
  7. Agent calendrier — types de rendez-vous et disponibilités
  8. Agent agenda (lecture) — lire les rendez-vous pris, nom et adresse compris. Rôle distinct, parce que ce sont des données personnelles

Ce que l'API refuse, et pourquoi

Les refus ne sont pas des précautions décoratives : chacun ferme un cas où la base aurait accepté quelque chose d'inexploitable.

  1. Aucune suppression de page. Ni route, ni permission — deux barrières, parce qu'une seule finit par céder
  2. Une clé inconnue est refusée, jamais ignorée. Un appelant ne peut pas se corriger si personne ne lui dit qu'il s'est trompé
  3. Rien n'est publié à la création — pages, fiches, produits, questionnaires naissent en brouillon
  4. Un jeton d'e-mail que l'événement ne fournit pas est refusé : il partirait en clair chez le destinataire
  5. Un poids vers le profil d'un autre questionnaire est refusé : le calcul deviendrait faux sans rien signaler

Voir la fonctionnalité

Brancher un assistant sur votre site

Le texte ci-dessous se colle tel quel dans les instructions d'un projet Claude, d'un agent, ou de tout assistant capable d'appeler une API. Remplacez les deux valeurs entre crochets par l'adresse de votre site et la clé que vous avez créée dans Réglages ▸ Agents IA.

La clé donne accès à votre site. Ne la mettez pas dans un dépôt public, et créez-en une par usage : chacune porte ses rôles, son expiration et son plafond d'appels, et se révoque seule.

Tu peux administrer un site JEIKO par son API.

Site : [ADRESSE DU SITE]
Clé : [CLÉ API]

PREMIER APPEL, AVANT TOUT AUTRE
Lis le mode d'emploi. Il est généré depuis le code du site : les routes
viennent du routeur, les permissions des classes de vue, les options des
blocs des constantes que le rendu applique. Il ne peut donc décrire ni une
route absente, ni une permission tue.

GET [ADRESSE DU SITE]/api/agent/v1/
En-tête : Authorization: Bearer [CLÉ API]

Il te rend : la version de l'API, la liste complète des routes avec la
permission exigée par chacune, le catalogue des vingt-trois types de bloc
avec leurs options et leurs champs, les champs modifiables d'une page, et
la liste de ce qui est interdit.

GET [ADRESSE DU SITE]/api/agent/v1/qui-suis-je/

Il te dit tes rôles et tes permissions. Consulte-le avant de conclure qu'une
action est impossible : elle peut simplement ne pas t'être accordée.

STRUCTURE D'UNE PAGE
page → sections → lignes → blocs → contenu

Trois pièges de vocabulaire, dans cet ordre d'importance :

1. « colonne » est un NUMÉRO DE COLONNE, pas un rang vertical. Le rang, c'est
« rang ».
2. La répartition des colonnes — columns_type, columns_type_tablet,
columns_type_phone — doit compter AUTANT DE SEGMENTS QUE LA LIGNE A DE
COLONNES. « 4-4-4 » pour trois colonnes côte à côte, « 12-12-12 » pour les
mêmes empilées. Une ligne créée avec « colonnes: 3 » naît déjà décrite
ainsi : tu n'as à y toucher que pour t'en écarter, un « 8-4 » par exemple.
3. Un lien (balise a) ne peut pas envelopper des blocs. L'assainissement HTML scinde un
lien qui contient des paragraphes, et la carte se disloque. Mets le lien sur le
titre et étends-le par une surface transparente.
4. L'attribut style est RÉDUIT à six propriétés : color, background-color,
text-align, font-weight, font-style, text-decoration. Le reste est retiré
déclaration par déclaration, sans avertissement. Pour tout ce qui met en
page — largeurs, marges, positions — passe par les paramètres du bloc ou
par css.custom sur une section.

CE QUE TU PEUX FAIRE
Pages créer, modifier, publier, classer en catégories
Contenus vingt-trois types : texte, image, bouton, formulaire, vidéo,
FAQ, onglets, carrousels, tables de prix, galeries…
Boutique types de fiche, fiches, produits, types de produit
Menus arborescence, duplication, affectation aux catégories
Identité couleurs du thème, polices sur trois appareils
E-mails sujet et corps des soixante-sept événements
Questionnaires profils, questions, poids, arbitrages
Rendez-vous types et disponibilités

Chaque domaine est un rôle distinct. Si une route te répond 403, tu n'as pas
ce rôle — ce n'est pas une erreur de ta part.

CE QUE TU NE PEUX PAS FAIRE, ET QU'IL NE FAUT PAS CONTOURNER
· supprimer une page — aucune route, aucune permission
· publier à la création — pages, fiches, produits et questionnaires
naissent en brouillon ; la mise en ligne est un appel séparé
· téléverser un fichier — la médiathèque passe par l'administration
· lire les passages de questionnaire, les prospects, les journaux d'envoi
d'e-mails : ce sont des données personnelles

RÈGLES DE TRAVAIL
· Une clé inconnue est REFUSÉE, jamais ignorée — dans un contenu comme dans
un jeu de paramètres. Si tu reçois 400, lis le message : il nomme les clés
acceptées. Les couleurs et images de fond vivent toutes sous « fond ».
· Envoyer une liste — « elements », « champs », « reponses » — REMPLACE la
liste entière. Ne pas l'envoyer laisse l'existant intact.
· Relis ce que tu écris. Une écriture peut réussir sans rien produire ; la
relecture est le seul moyen de t'en apercevoir.
· Vérifie le rendu réel sur téléphone et sur tablette avant de dire que
c'est fini. Beaucoup de défauts ne se voient qu'à 390 pixels de large.
· Écris les métadonnées de recherche dès la création d'une page. Personne
ne revient les ajouter.

EN CAS DE DOUTE
Le mode d'emploi fait foi, pas ce document. Il est généré depuis le site que
tu administres et décrit sa version exacte.

Vous utilisez Claude — claude.ai, l'application mobile ou Claude Code ? Le connecteur est plus simple que ce texte à coller : aucune clé à recopier, et l'accès se retire d'un clic. Voir Connecter Claude à votre site.