Aller au contenu principal

API publique (plugin & intégrations)

Easy Content Flow expose une API publique qui permet à votre plugin WordPress — ou à n'importe quelle intégration — de générer du contenu, suivre vos cocons et récupérer vos articles par programmation.

Vous authentifiez vos requêtes avec une clé API que vous générez depuis votre tableau de bord, et l'API renvoie des données prêtes à publier (HTML, titre SEO, méta-description, image).

URL de base

https://easycontentflow.com/api/public/v1

Tous les chemins indiqués dans ce guide sont relatifs à cette URL.

Conventions

  • Identifiants (content_id, cocoon_id…) : chaînes opaques. Conservez-les tels quels, ne présumez pas de leur format.
  • Dates (created_at) : entier, en millisecondes depuis le 1ᵉʳ janvier 1970.
  • Corps des requêtes POST : champs en camelCase.
  • Corps des réponses : champs en snake_case.

Authentification

Chaque requête doit inclure votre clé API dans l'en-tête Authorization, au format Bearer :

Authorization: Bearer ecf_live_xxxxxxxx.xxxxxxxxxxxx

Obtenir une clé

  1. Dans votre tableau de bord Easy Content Flow, ouvrez Clés API plugin.
  2. Cliquez sur Créer une clé et donnez-lui un nom (ex. « Mon site WordPress »).
  3. La clé (ecf_live_…) s'affiche une seule fois. Copiez-la immédiatement et conservez-la en lieu sûr — elle n'est plus récupérable ensuite.
  4. Renseignez cette clé dans votre plugin WordPress.
attention

La clé n'est affichée qu'à sa création. Si vous la perdez, révoquez-la et créez-en une nouvelle.

Clé liée à un projet

À la création d'une clé, vous pouvez la lier à un projet (un projet = un site, gérés depuis votre tableau de bord). Une clé liée à un projet ne voit alors que les contenus et cocons de ce projet — c'est la configuration recommandée pour le plugin WordPress : le site ne liste que ses propres contenus, sans tri manuel. Les contenus créés via cette clé sont automatiquement rattachés au projet.

Une clé sans projet conserve le comportement historique : elle accède à tous vos contenus. Les clés existantes ne changent donc pas de comportement.

Révoquer une clé

Depuis la même page Clés API plugin, révoquez une clé à tout moment. Une clé révoquée cesse immédiatement de fonctionner (réponse 401). Vous pouvez créer autant de clés que nécessaire (une par site, par exemple).

Limite de débit

L'API est limitée à 60 requêtes par minute et par clé. Au-delà, elle répond avec un code 429 :

{ "detail": "Rate limit exceeded: 60 per 1 minute" }

L'API ne renvoie pas d'en-tête Retry-After : votre intégration doit gérer ce cas elle-même (attendre ~60 secondes avant de réessayer).

:::warning Débit de soumission ≠ débit de génération La limite de 60 requêtes/minute concerne la soumission de requêtes à l'API, pas le rythme auquel vos contenus sont réellement générés.

La génération de contenu est asynchrone : POST /contents place votre demande dans une file d'attente, et le contenu est produit en arrière-plan. La génération d'un contenu prend plusieurs minutes, et le débit réel est de l'ordre de quelques contenus par minute (traitement asynchrone partagé).

Ne dimensionnez pas votre intégration en supposant 60 contenus générés par minute. Soumettez vos demandes, puis interrogez GET /contents/{content_id} jusqu'à ce que job_status passe à done. :::

Codes d'erreur

CodeSignification
400contentType inconnu (sur la création de contenu)
401Clé API absente, invalide ou révoquée
402Crédits insuffisants pour générer le contenu
403En-tête Authorization manquant
429Limite de débit dépassée (voir ci-dessus)

Endpoints

Les 8 endpoints ci-dessous requièrent tous l'en-tête Authorization: Bearer ….

GET /me — Compte et crédits

curl https://easycontentflow.com/api/public/v1/me \
-H "Authorization: Bearer ecf_live_xxxx.xxxx"
{
"email": "client@example.com",
"credits_remaining": 42,
"credits": {
"content": 42,
"cocoon": 5
}
}
  • credits_remaining : crédits de contenu disponibles (identique à credits.content).
  • credits.content / credits.cocoon : détail par type de crédit.

GET /personas — Liste des personas

curl https://easycontentflow.com/api/public/v1/personas \
-H "Authorization: Bearer ecf_live_xxxx.xxxx"
[
{ "personna_id": "b3f1c2a4-8d7e-4a1b-9c2d-0e1f2a3b4c5d", "label": "Expert SEO" }
]

GET /projects — Liste des projets

Renvoie vos projets. Une clé liée à un projet ne renvoie que celui-ci.

curl https://easycontentflow.com/api/public/v1/projects \
-H "Authorization: Bearer ecf_live_xxxx.xxxx"
[
{
"project_id": "7f3a1b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
"name": "Mon site façades",
"website_url": "https://mon-site.fr"
}
]

GET /cocoons — Liste des cocons

Paramètres :

ParamètreTypeDéfautDescription
pageentier ≥ 11Numéro de page
per_pageentier 1–10020Taille de page
statustexteFiltre : pending | done | error
project_idtexteFiltre par projet (ignoré si la clé est liée à un projet)
curl "https://easycontentflow.com/api/public/v1/cocoons?page=1&per_page=20&status=done" \
-H "Authorization: Bearer ecf_live_xxxx.xxxx"
{
"items": [
{
"cocoon_id": "9a2e7b10-3c4d-5e6f-7a8b-9c0d1e2f3a4b",
"name": "Panneau solaire",
"main_keyword": "panneau solaire",
"website": "https://exemple.fr",
"job_status": "done",
"created_at": 1733300000000,
"error_message": null,
"project_id": "7f3a1b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c"
}
],
"total": 1,
"page": 1
}

GET /cocoons/{cocoon_id} — Détail d'un cocon

Renvoie le cocon et la liste de ses articles planifiés.

curl https://easycontentflow.com/api/public/v1/cocoons/9a2e7b10-3c4d-5e6f-7a8b-9c0d1e2f3a4b \
-H "Authorization: Bearer ecf_live_xxxx.xxxx"
{
"cocoon_id": "9a2e7b10-3c4d-5e6f-7a8b-9c0d1e2f3a4b",
"main_keyword": "panneau solaire",
"articles": [
{
"article_id": "1f0a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
"title": "Comment choisir ses panneaux solaires",
"keyword": "choisir panneau solaire",
"volume": 1300,
"content_id": "c4d5e6f7-8a9b-0c1d-2e3f-4a5b6c7d8e9f"
}
]
}
  • content_id vaut null tant qu'aucun contenu n'a été généré pour cet article.

POST /contents — Créer un contenu

Lance la génération d'un contenu. Cette opération consomme un crédit (402 si vous n'en avez plus).

Corps de requête (camelCase). Champs principaux :

ChampTypeDescription
contentTypetexteType de contenu (défaut agentic). Valeurs : agentic, news, product_card, ecommerce_category, affiliate, service, personna
keywordtexteMot-clé principal
toneOfVoicetexteTon de voix (ignoré si personnaId est fourni)
personnaIdtextePersona à utiliser comme ton
cocoonId / articleIdtexteRattachement à un cocon / un article
countrytextePays (défaut fr)
specificInstructionstexteInstructions ponctuelles
projectIdtexteProjet auquel rattacher le contenu. Ignoré si la clé est liée à un projet (le contenu est alors rattaché au projet de la clé)

Champs spécifiques au type service :

ChampTypeDescription
serviceNametexteNom du service (obligatoire pour ce type)
serviceDescriptiontexteDescription libre du service (obligatoire)
serviceWebsiteUrltexteURL du site client, analysée pour le ton et le positionnement
serviceCitytexteVille / zone. Renseignée → page locale (schema LocalBusiness) ; vide → page corporate
serviceTargetAudiencetexteCible client
serviceKeyBenefitsliste de textesArguments clés / USP
serviceTestimonialstexteTémoignages clients, cités tels quels
ctaTypetexteType de CTA : devis, rdv, contact, appel ou auto (défaut)
ctaUrltexteURL cible des 3 CTA. Vide → ancre #contact
ctaEnabledbooléenfalse = page générée sans aucun CTA (la FAQ et les données structurées sont conservées). Absent ou true = 3 CTA inclus (comportement par défaut)
curl -X POST https://easycontentflow.com/api/public/v1/contents \
-H "Authorization: Bearer ecf_live_xxxx.xxxx" \
-H "Content-Type: application/json" \
-d '{
"contentType": "agentic",
"keyword": "panneau solaire monocristallin",
"toneOfVoice": "Expert, pédagogue",
"country": "fr"
}'

Réponse (201) :

{
"content_id": "c4d5e6f7-8a9b-0c1d-2e3f-4a5b6c7d8e9f",
"job_status": "pending",
"created_at": 1733300000000
}

La génération est asynchrone : le contenu est créé avec le statut pending. Récupérez le résultat via GET /contents/{content_id} (voir Cycle d'intégration).

GET /contents — Liste des contenus

Paramètres :

ParamètreTypeDéfautDescription
pageentier ≥ 11Numéro de page
per_pageentier 1–10020Taille de page
statustexteFiltre : pending | done | error
workflow_typetexteFiltre par type (ex. agentic, news)
project_idtexteFiltre par projet (ignoré si la clé est liée à un projet)
curl "https://easycontentflow.com/api/public/v1/contents?status=done&workflow_type=agentic" \
-H "Authorization: Bearer ecf_live_xxxx.xxxx"
{
"items": [
{
"content_id": "c4d5e6f7-8a9b-0c1d-2e3f-4a5b6c7d8e9f",
"title": "Panneau solaire monocristallin : guide complet",
"workflow_type": "agentic",
"job_status": "done",
"created_at": 1733300000000,
"word_count": 1850,
"article_id": null,
"cocoon_id": null,
"error_message": null,
"project_id": null
}
],
"total": 1,
"page": 1
}

La liste ne contient pas le HTML de l'article : utilisez le détail (GET /contents/{content_id}) pour le récupérer.

GET /contents/{content_id} — Détail d'un contenu

Renvoie le contenu et, lorsqu'il est prêt, le résultat généré.

curl https://easycontentflow.com/api/public/v1/contents/c4d5e6f7-8a9b-0c1d-2e3f-4a5b6c7d8e9f \
-H "Authorization: Bearer ecf_live_xxxx.xxxx"

Contenu généré (job_status = done) :

{
"content_id": "c4d5e6f7-8a9b-0c1d-2e3f-4a5b6c7d8e9f",
"title": "Panneau solaire monocristallin : guide complet",
"workflow_type": "agentic",
"job_status": "done",
"created_at": 1733300000000,
"word_count": 1850,
"article_id": null,
"cocoon_id": null,
"error_message": null,
"result": {
"content_html": "<h1>Panneau solaire monocristallin</h1><p>...</p>",
"seo_title": "Panneau solaire monocristallin : guide complet",
"meta_description": "Découvrez comment choisir vos panneaux...",
"image_url": "https://easycontentflow.com/api/images/abc123"
}
}

Contenu pas encore prêt (pending ou error) — result vaut null :

{
"content_id": "c4d5e6f7-8a9b-0c1d-2e3f-4a5b6c7d8e9f",
"title": "",
"workflow_type": "agentic",
"job_status": "pending",
"created_at": 1733300000000,
"word_count": 0,
"article_id": null,
"cocoon_id": null,
"error_message": null,
"result": null
}

Le bloc result (présent uniquement quand job_status = done) :

ChampDescription
content_htmlCorps HTML de l'article, à insérer dans WordPress
seo_titleTitre SEO
meta_descriptionMéta-description
image_urlURL de l'image générée, téléchargeable directement (null s'il n'y en a pas)

À savoir

  • Identifiants opaques : content_id, cocoon_id, article_id, personna_id sont des clés à conserver telles quelles, sans en interpréter le format.
  • job_status prend trois valeurs : pending (en cours), done (prêt), error (échec).
  • Le résultat n'est disponible qu'une fois done. Tant que le contenu est pending, interrogez régulièrement GET /contents/{content_id} jusqu'à obtenir done (ou error).
  • error_message contient un message explicatif lorsque job_status = error ; sinon null.
  • image_url est une URL complète, téléchargeable sans authentification.
  • Pagination : total reflète le nombre d'éléments après filtres ; per_page est limité à 100.

Cycle d'intégration

Étapes typiques côté plugin :

  1. Créer le contenu avec POST /contents → récupérez le content_id (statut pending).
  2. Interroger GET /contents/{content_id} jusqu'à ce que job_status passe à done (ou error).
  3. Récupérer result.content_html, result.seo_title, result.meta_description et result.image_url, puis publier dans WordPress.

Avant de créer un contenu, vous pouvez vérifier vos crédits avec GET /me. Pour rattacher un contenu à un cocon existant, listez vos cocons avec GET /cocoons puis passez cocoonId / articleId à POST /contents.

:::tip Pensez « file d'attente », pas « temps réel » La génération est asynchrone et prend plusieurs minutes par contenu. Soumettez vos demandes au fil de l'eau, puis pollez GET /contents/{content_id} pour récupérer chaque résultat — n'attendez pas une réponse immédiate et ne comptez pas générer 60 contenus en une minute. Pour de gros volumes, espacez vos créations et laissez la file se vider. :::

Questions fréquentes

Où trouver ma clé API ? Dans votre tableau de bord, section Clés API plugin. La clé s'affiche une seule fois à sa création.

Que faire si j'ai perdu ma clé ? Révoquez-la depuis Clés API plugin et créez-en une nouvelle.

Pourquoi mon contenu reste-t-il en pending ? La génération est asynchrone et prend généralement quelques minutes. Interrogez le détail du contenu jusqu'à ce que job_status passe à done.

Combien de requêtes puis-je envoyer ? 60 par minute et par clé. Au-delà, l'API répond 429 ; attendez environ une minute avant de réessayer.