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é
- Dans votre tableau de bord Easy Content Flow, ouvrez Clés API plugin.
- Cliquez sur Créer une clé et donnez-lui un nom (ex. « Mon site WordPress »).
- 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. - Renseignez cette clé dans votre plugin WordPress.
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
| Code | Signification |
|---|---|
400 | contentType inconnu (sur la création de contenu) |
401 | Clé API absente, invalide ou révoquée |
402 | Crédits insuffisants pour générer le contenu |
403 | En-tête Authorization manquant |
429 | Limite 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ètre | Type | Défaut | Description |
|---|---|---|---|
page | entier ≥ 1 | 1 | Numéro de page |
per_page | entier 1–100 | 20 | Taille de page |
status | texte | — | Filtre : pending | done | error |
project_id | texte | — | Filtre 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_idvautnulltant 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 :
| Champ | Type | Description |
|---|---|---|
contentType | texte | Type de contenu (défaut agentic). Valeurs : agentic, news, product_card, ecommerce_category, affiliate, service, personna |
keyword | texte | Mot-clé principal |
toneOfVoice | texte | Ton de voix (ignoré si personnaId est fourni) |
personnaId | texte | Persona à utiliser comme ton |
cocoonId / articleId | texte | Rattachement à un cocon / un article |
country | texte | Pays (défaut fr) |
specificInstructions | texte | Instructions ponctuelles |
projectId | texte | Projet 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 :
| Champ | Type | Description |
|---|---|---|
serviceName | texte | Nom du service (obligatoire pour ce type) |
serviceDescription | texte | Description libre du service (obligatoire) |
serviceWebsiteUrl | texte | URL du site client, analysée pour le ton et le positionnement |
serviceCity | texte | Ville / zone. Renseignée → page locale (schema LocalBusiness) ; vide → page corporate |
serviceTargetAudience | texte | Cible client |
serviceKeyBenefits | liste de textes | Arguments clés / USP |
serviceTestimonials | texte | Témoignages clients, cités tels quels |
ctaType | texte | Type de CTA : devis, rdv, contact, appel ou auto (défaut) |
ctaUrl | texte | URL cible des 3 CTA. Vide → ancre #contact |
ctaEnabled | booléen | false = 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ètre | Type | Défaut | Description |
|---|---|---|---|
page | entier ≥ 1 | 1 | Numéro de page |
per_page | entier 1–100 | 20 | Taille de page |
status | texte | — | Filtre : pending | done | error |
workflow_type | texte | — | Filtre par type (ex. agentic, news) |
project_id | texte | — | Filtre 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) :
| Champ | Description |
|---|---|
content_html | Corps HTML de l'article, à insérer dans WordPress |
seo_title | Titre SEO |
meta_description | Méta-description |
image_url | URL 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_idsont des clés à conserver telles quelles, sans en interpréter le format. job_statusprend trois valeurs :pending(en cours),done(prêt),error(échec).- Le résultat n'est disponible qu'une fois
done. Tant que le contenu estpending, interrogez régulièrementGET /contents/{content_id}jusqu'à obtenirdone(ouerror). error_messagecontient un message explicatif lorsquejob_status=error; sinonnull.image_urlest une URL complète, téléchargeable sans authentification.- Pagination :
totalreflète le nombre d'éléments après filtres ;per_pageest limité à 100.
Cycle d'intégration
Étapes typiques côté plugin :
- Créer le contenu avec
POST /contents→ récupérez lecontent_id(statutpending). - Interroger
GET /contents/{content_id}jusqu'à ce quejob_statuspasse àdone(ouerror). - Récupérer
result.content_html,result.seo_title,result.meta_descriptionetresult.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.