Aller au contenu

Documentation développeurs · API REST v1

Développez sur Eyivo avec une API structurée.

Gérez pages, composants, blogs, produits, galeries, vidéos, menus, médias, formulaires et réglages du site via des outils et endpoints REST soumis aux autorisations.

URL de base

https://app.eyivo.com/api/v1

1. Aperçu

L’API REST d’Eyivo permet de gérer des sites structurés par programmation. Elle utilise HTTPS et JSON, est versionnée sous /api/v1 et applique les mêmes règles de propriété, limites de forfait, validation et audit que le tableau de bord.

JSON et multipart

Accept: application/json. Content-Type: application/json; file: multipart/form-data.

Réservé au propriétaire

Chaque opération du site est limitée aux sites appartenant à l'utilisateur authentifié.

D’abord en brouillon

Enregistrez un brouillon, vérifiez sa préparation puis publiez cet élément dans la langue souhaitée lorsque l’utilisateur veut le rendre public. Les autres brouillons restent inchangés.

Versionnement : toute modification incompatible du contrat nécessite une nouvelle version de base. De nouveaux champs peuvent apparaître dans les objets JSON existants ; les clients doivent ignorer ceux qu’ils ne reconnaissent pas.

2. Démarrage rapide

  1. 1
    Créez un jeton.

    Connectez-vous à l’application, ouvrez les jetons API, choisissez les portées minimales nécessaires et copiez le ey_ secret lorsqu’il apparaît.

  2. 2
    Listez vos sites.

    Confirmez l'authentification et obtenez l'ID de site numérique utilisé par les points de terminaison imbriqués.

  3. 3
    Envoyez des écritures idempotentes.

    Attribuez à chaque requête POST, PATCH et DELETE une clé Idempotency-Key.

curl --request GET \
  --url https://app.eyivo.com/api/v1/sites \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer ey_your_token'

Une réponse de collection réussie place les enregistrements dans data :

{
  "data": [
    {
      "id": 42,
      "platform_subdomain_key": "7kr9mp2x",
      "template_key": "corporate-01",
      "status": "active",
      "native_locale": "en",
      "english_enabled": false,
      "content_version": 1,
      "search_visibility": "platform_noindex"
    }
  ]
}

3. Authentification

Chaque requête vers /api/v1 nécessite un jeton d’accès :

Authorization: Bearer <token>

Jetons d'API personnels

Adaptés aux scripts, aux intégrations côté serveur et aux automatisations de compte. Les jetons commencent par ey_, sont stockés sous forme de hachage et ne sont affichés qu’une fois.

  • Créez-les et révoquez-les à https://app.eyivo.com/tokens.
  • Choisissez une ou plusieurs portées.
  • Vous pouvez limiter un jeton à un site dont vous êtes propriétaire.
  • Les jetons non expirés restent valides jusqu'à leur révocation.

OAuth 2.0 + PKCE

Adapté aux applications qui agissent au nom des utilisateurs d’Eyivo. Utilisez le flux de code d’autorisation avec PKCE, et non les flux par mot de passe ou implicite.

  • Autorisation : https://app.eyivo.com/oauth/authorize
  • Jeton et actualisation : https://app.eyivo.com/oauth/token
  • Les jetons d'accès expirent après 2 heures.
  • Les jetons d’actualisation expirent après 1 an.

Flux d'autorisation PKCE

  1. Créez un code_verifier à forte entropie et son code_challenge SHA-256.
  2. Redirigez l’utilisateur vers /oauth/authorize avec response_type=code, le client_id public, le redirect_uri enregistré exact, les portées demandées dans scope séparées par des espaces, state, code_challenge et code_challenge_method=S256.
  3. Vérifiez state après la redirection, puis échangez le code d’autorisation sur /oauth/token avec le code_verifier d’origine.
  4. Conservez les jetons d’accès et de rafraîchissement de façon sécurisée. Renouvelez-les avant expiration et remplacez les identifiants renouvelés de manière atomique.
N'exposez jamais les jetons : ne placez jamais les jetons d’accès dans les URL, les journaux du navigateur, le dépôt de code, les captures d’écran ni dans du code client incapable de protéger les secrets.

4. Portées

Chaque requête nécessite la portée exacte indiquée ci-dessous. Un jeton personnel contenant * passe tous les contrôles de portée, mais les applications doivent demander uniquement les permissions nécessaires.

PortéeFonction REST
sites:readLister les sites appartenant à l’utilisateur et consulter un site.
sites:writeCréer des sites avec un jeton valable pour tout le compte.
content:readLire contenus, schémas, menus, formulaires et réglages.
content:writeCréer, modifier, supprimer et publier explicitement ; exécuter les actions déclarées des panneaux.
media:readGET /sites/{site}/media, GET /sites/{site}/media/stock-photos
media:writePOST /sites/{site}/media, DELETE /sites/{site}/media/{media}
domains:readLister les domaines d’un site.
domains:writeDemander, activer et sélectionner des domaines personnalisés.

REST exige le scope de l’endpoint, pas mcp:use. Les médias utilisent media:read ou media:write.

5. Écritures idempotentes

Envoyez Idempotency-Key avec les modifications JSON pour répéter la même requête en sécurité. Les transferts multipart et l’émission de tickets sont exclus ; vérifiez le résultat avant de réessayer.

Idempotency-Key: site-42-page-create-01J7M6Y8RRF3ZE6WB4Z0Y9XJXC
SituationRésultat
Première requêteL’opération s’exécute ; son code de statut et son corps JSON sont enregistrés.
Même clé, méthode, chemin, paramètres de requête et corpsLa réponse enregistrée est renvoyée sans répéter l’opération.
Même clé pour une requête différente422 — la réutilisation de clé avec une charge utile différente est rejetée.
Même clé alors que la première requête est encore en cours409 — la requête est déjà en cours.
Aucune cléLa requête est exécutée, mais il est impossible de la retenter de façon sûre.

La comparaison prend en compte la méthode HTTP, le chemin et le corps brut exact de la requête. Lors d’une nouvelle tentative, réutilisez le JSON sérialisé d’origine.

6. Réponses et structure des ressources

Les opérations de contenu retournent une enveloppe data. MCP fournit structuredContent et une copie JSON textuelle ; REST retourne du JSON. Consultez les schémas pour les IDs, la préparation et la pagination. Suivez les informations de page des blogs, médias et soumissions.

Ressource unique

{ "data": { "id": 42, "status": "active" } }

Collection

{ "data": [{ "id": 42 }, { "id": 43 }] }

Les collections ont des formats différents. Suivez la pagination documentée de chaque endpoint ; toutes ne sont pas des listes simples ou non paginées.

7. Sites

GET/sites

Lister les sites dont vous êtes propriétaire · sites:read

POST/sites

Créer un site · sites:write

GET/sites/{site}

Consulter un site dont vous êtes propriétaire · sites:read

Créer un site

curl --request POST \
  --url https://app.eyivo.com/api/v1/sites \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer ey_your_token' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: site-create-01J7M6Y8' \
  --data '{
    "display_name": "Northstar Studio",
    "template_key": "corporate-01",
    "native_locale": "en"
  }'
ChampRègles
display_nameChaîne obligatoire, 200 caractères maximum.
template_keyClé de modèle intégré obligatoire. La liste complète des valeurs actuelles figure dans OpenAPI.
native_localeCode de langue pris en charge obligatoire.

Réponse : 201 Created avec une ressource de site. Le statut peut être initialement inactif pendant la répartition du site. Le dépassement des limites du site ou du forfait renvoie 422.

Champs de la ressource de site : id, platform_subdomain_key, template_key, status, native_locale, english_enabled, content_version, search_visibility, runtime facultatif et horodatages.

8. Pages

GET/sites/{site}/pages

Lister les pages · content:read

POST/sites/{site}/pages

Créer un brouillon · content:write

GET/sites/{site}/pages/{page}

Récupérer une page · content:read

PATCH/sites/{site}/pages/{page}

Mettre à jour un brouillon · content:write

DELETE/sites/{site}/pages/{page}

Supprimer une page · content:write

POST/sites/{site}/pages/{page}/publication

content:write · locale

Créer une page

{
  "type": "page",
  "sort_order": 300,
  "locale": "en",
  "slug": "our-story",
  "title": "Our story",
  "body": "<p>How the company began.</p>",
  "meta_title": "Our story | Northstar Studio",
  "meta_description": "Learn about Northstar Studio."
}
ChampRègles de création et de mise à jour
typeUtilisez page pour le contenu courant. Les types et schémas de composants figurent dans les capacités du site.
sort_orderEntier facultatif et nullable de 0 à 9999 ; valeur par défaut à la création : 0.
localeObligatoire à la création. À la mise à jour, requis si title, slug ou body change.
slugObligatoire à la création. Lettres ASCII, chiffres, tirets et traits de soulignement ; 160 caractères maximum.
titleChaîne obligatoire à la création ; 200 caractères maximum.
bodyChaîne ou valeur nulle ; 50 000 caractères maximum.
meta_titleChaîne ou valeur nulle ; 200 caractères maximum.
meta_descriptionChaîne ou valeur nulle ; 500 caractères maximum.

Réponse à la création : 201. Réponse à la mise à jour : 200. Réponse à la suppression : 204, sans corps.

Enregistrez un brouillon, vérifiez sa préparation puis publiez cet élément dans la langue souhaitée lorsque l’utilisateur veut le rendre public. Les autres brouillons restent inchangés.

9. Éléments du catalogue

GET/sites/{site}/catalog-items

Liste des éléments · content:read

POST/sites/{site}/catalog-items

Créer un brouillon · content:write

GET/sites/{site}/catalog-items/{catalogItem}

Récupérer un élément · content:read

DELETE/sites/{site}/catalog-items/{catalogItem}

Supprimer un élément · content:write

PUT/sites/{site}/catalog-items/{catalogItem}

content:write · locale, slug, title

POST/sites/{site}/catalog-items/{catalogItem}/publication

content:write · locale

Créer un élément de catalogue

{
  "sort_order": 100,
  "locale": "en",
  "slug": "strategy-advisory",
  "title": "Strategy advisory",
  "summary": "Focused advice for consequential decisions.",
  "body": "Talk to our senior advisory team."
}
ChampRègles
sort_orderEntier facultatif de 0 à 9999, ou valeur nulle ; 0 par défaut.
localeCode de langue pris en charge obligatoire.
slugSlug ASCII requis ; maximum 160.
titleChaîne obligatoire ; maximum 200.
summaryChaîne ou valeur nulle ; 1 000 caractères maximum.
bodyChaîne ou valeur nulle ; 50 000 caractères maximum.

Enregistrez un brouillon, vérifiez sa préparation puis publiez cet élément dans la langue souhaitée lorsque l’utilisateur veut le rendre public. Les autres brouillons restent inchangés.

Voici des exemples par famille de contenu. Découvrez tous les schémas et autorisations dans tools/list ou OpenAPI. Les chemins REST sont relatifs à /api/v1/sites/{site}.

Découverte des sites et capacités

GET /capabilities · GET /readiness

Pages, composants et liens internes

/pages · /pages/{page_id}/components · POST /pages/{page_id}/publication

Produits, galeries et vidéos

/catalog-items · /galleries · /videos · POST /{collection}/{id}/publication

Brouillons du blog, catégories et programmation

/blog/posts · /blog/categories · /blog/links · /blog/posts/{post_id}/publication · /blog/posts/{post_id}/schedule

Navigation principale et menus supplémentaires

/menus · /menus/destinations · /menu-assignments/{type}/{target_id} · /menus/{menu_key}/publication

Médiathèque et photos de stock

/media · /media/transfers · /media/stock-photos

Formulaires, soumissions et panneaux des plugins

/forms · /submissions · /plugins · /plugins/panel · /plugins/panel/actions

Entreprise, thème, langues et intégrations

/company · /theme · /theme/settings · /locales · /integrations · /demo · /demo/drafts · /cache/reset

Capacités et contrat de rédaction

Sélectionnez un site et lisez ses capacités : langues actives, champs du thème, schémas des composants, menus et panneaux des plugins. Lisez la ressource content-workflow avant toute modification. Sans ressources, utilisez get-site-capabilities-tool. Suivez nextCursor de tools/list jusqu’à la fin.

GET /api/v1/sites/{site}/capabilities
GET /api/v1/sites/{site}/pages/{page_id}/components/schema?locale=en

Utilisez la langue demandée et la version ou revision actuelle. Enregistrer un article remplace le document entier et annule sa programmation. Les menus utilisent une revision numérique ; les affectations utilisent un hash menu_revision distinct. Conservez les éléments des tableaux remplacés. En cas de conflit, relisez et fusionnez les modifications.

La navigation principale reste automatique. Les menus supplémentaires ont leurs propres brouillons et publications. Enregistrer un contenu prépare ses affectations ; publier cet élément les applique sans publier les autres menus. Publier un menu ne publie jamais ses contenus liés. source_hash rejette les traductions basées sur une source périmée.

Le corps des pages et les champs richtext acceptent du HTML assaini. list-page-links-tool fournit les liens stables /__eyivo/pages/{id}, résolus dans la langue du visiteur après publication. Les articles utilisent un document JSON structuré avec media_id du même site et des cibles page/article, pas body_html.

{
  "type": "doc",
  "content": [{
    "type": "paragraph",
    "content": [{ "type": "text", "text": "Our story" }]
  }]
}

Téléverser des images et vidéos

upload-media-tool ouvre un sélecteur de fichiers dans les clients MCP Apps comme Claude. ChatGPT peut aussi fournir sa référence de pièce jointe ; une pièce jointe Claude n’est pas une référence OpenAI. N’inventez pas d’URL et n’envoyez pas de fichiers base64 dans les arguments.

Codex et Claude Code peuvent appeler prepare-media-upload-tool puis envoyer le fichier multipart à upload_url avec son upload_token à usage unique sous cinq minutes. Gardez ce token secret. Les clients REST peuvent utiliser leur bearer media:write. Seul un transfert terminé retourne l’ID du média ; émettre un ticket ne téléverse rien.

POST /api/v1/sites/{site}/media
Authorization: Bearer <media:write token>
Content-Type: multipart/form-data; boundary=<generated by HTTP client>

file: <original file bytes>

10. Domaines personnalisés

GET/sites/{site}/domains

Liste des domaines · domains:read

POST/sites/{site}/domains

Demander un domaine · domains:write

POST/sites/{site}/domains/{domain}/activate

Activer après vérification · domains:write

POST/sites/{site}/domains/{domain}/primary

Choisir le nom d’hôte principal · domains:write

Demander un domaine

curl --request POST \
  --url https://app.eyivo.com/api/v1/sites/42/domains \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer ey_your_token' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: domain-request-example-com' \
  --data '{"domain":"www.example.com"}'

Un domaine en attente contient verification_token. Ajoutez l’enregistrement DNS demandé pour prouver la propriété, attendez sa propagation, puis appelez le point de terminaison d’activation. Une fois le domaine actif, choisissez-le comme nom d’hôte principal s’il doit devenir l’adresse publique canonique.

Champs de la ressource de domaine : id, domain, site_id, is_primary, status, verification_token si applicable et horodatages. Les limites du forfait et les erreurs de validation du domaine renvoient 422.

11. Erreurs

StatutSignificationAction typique
401Jeton d’accès manquant, invalide, expiré ou révoqué.Remplacez ou actualisez les informations d'identification.
403Permission manquante, restriction de site ou modification demandée par une personne qui ne possède pas le site.Utilisez une portée ou un site autorisé ; ne renvoyez pas la même requête sans modification.
404La ressource est manquante ou n'appartient pas à l'utilisateur.Vérifiez les ID et la propriété.
409Un conflit de version nécessite une relecture et une fusion. Ne renvoyez pas les mêmes données périmées.Lisez le brouillon de la langue choisie et sa révision actuelle avant toute modification.
422Erreur de validation, limite du forfait, règle de domaine ou requête différente avec la même clé d’idempotence.Lisez errors ou message, corrigez la requête et utilisez une nouvelle clé si son corps change.
5xxErreur inattendue de la plateforme ou d’un service en amont.Réessayez les lectures sans risque ; pour les écritures, réutilisez uniquement la même clé d’idempotence.

Réponse de validation

{
  "message": "The title field is required.",
  "errors": {
    "title": ["The title field is required."]
  }
}

Réponse d'authentification ou d'autorisation

{
  "message": "Missing required scope [content:write]."
}

12. Limites actuelles et liste de contrôle d'intégration

REST v1 expose délibérément un ensemble limité de fonctions Eyivo. L’absence de point de terminaison n’autorise pas l’appel d’API internes.

Disponible

  • Liste, consultation et création de sites
  • Pages, composants et liens internes
  • Gérez pages, composants, blogs, produits, galeries, vidéos, menus, médias, formulaires et réglages du site via des outils et endpoints REST soumis aux autorisations.
  • Liste, demande, activation et choix du domaine principal

Non exposé dans REST v1

  • Modification de facturation et abonnements
  • Mots de passe et gestion des tokens
  • Accès direct au stockage et APIs internes
  • Installation ou exécution arbitraire de code de thème

Avant la mise en production

  • Utilisez HTTPS et vérifiez que l’hôte attendu est app.eyivo.com.
  • Gardez les jetons d’accès côté serveur et masquez les en-têtes d’autorisation dans les journaux.
  • Demandez uniquement les portées nécessaires et privilégiez les jetons personnels limités à un site lorsque c’est possible.
  • Utilisez une clé d'idempotence unique pour chaque écriture logique et conservez-la lors des tentatives.
  • Considérez 401, 403, 404 et 422 comme des erreurs permanentes, sauf si la requête ou les identifiants changent.
  • Utilisez un délai de reprise exponentiel avec variation aléatoire pour les erreurs temporaires et respectez tout futur en-tête Retry-After.
  • Les collections ont des formats différents. Suivez la pagination documentée de chaque endpoint ; toutes ne sont pas des listes simples ou non paginées.