Publication multi-réseaux
POST /v2/posts publie le même contenu sur plusieurs réseaux en un seul appel — immédiatement ou à une date programmée. L'appel rend la main tout de suite (202) : la publication se fait en tâche de fond, chaque réseau vous est notifié par webhook et consultable via GET /v2/posts/:id.
Principe
/v2/postsCréer une publication (immédiate ou programmée)
/v2/postsLister les publications récentes
/v2/posts/:idÉtat détaillé, réseau par réseau
/v2/posts/:idAnnuler une publication programmée
Scope requis : publish:posts (présent sur toute clé créée depuis le 19 juillet 2026 — les clés antérieures reçoivent 403 insufficient_scope, créez-en une nouvelle). Réseaux : facebook, instagram, linkedin, tiktok — le canal correspondant doit être connecté à votre espace de travail.
Si vous avez connecté plusieurs comptes d'un même réseau (deux pages Facebook, deux comptes TikTok…), une cible peut désigner le compte exact : { "platform": "facebook", "channelId": "…" }. Voir Comptes connectés pour obtenir ces identifiants.
Créer une publication
curl -X POST https://api.kreatoai.com/v2/posts \
-H "x-api-key: sk-kre-v1-votre_cle" \
-H "Content-Type: application/json" \
-d '{
"targets": ["facebook", "linkedin"],
"content": "Notre nouvelle offre est en ligne !",
"mediaUrls": ["https://media.kreatoai.com/abc.jpg"],
"idempotencyKey": "post-lancement-2026-07-19"
}'Champs : targets (1 à 20 cibles, sans doublon — un nom de réseau ou un objet { platform, channelId }), content (texte, jusqu'à 63 206 caractères — les bornes plus strictes de chaque réseau sont vérifiées par cible), mediaUrls (0 à 10 URLs https publiques — hébergez vos fichiers via /v1/media), scheduledAt (ISO 8601, optionnel — absent = publication immédiate), idempotencyKey (optionnel, voir plus bas).
// 202 Accepted
{
"id": "9f1c8b2e-…",
"status": "processing", // ou "scheduled" si scheduledAt est fourni
"scheduledAt": null,
"createdAt": "2026-07-19T14:30:00.000Z",
"targets": [
{ "platform": "facebook", "accountId": "a3f27c9e-…", "accountName": "Campus Plus",
"status": "pending", "externalPostId": null,
"postUrl": null, "failReason": null, "failType": null, "completedAt": null },
{ "platform": "linkedin", "accountId": "c04e91a7-…", "accountName": "Nafiou Tino",
"status": "pending", "externalPostId": null,
"postUrl": null, "failReason": null, "failType": null, "completedAt": null }
]
}accountId identifie le compte exact atteint par chaque cible — décisif quand plusieurs comptes du même réseau sont connectés. Il vaut null sur les publications antérieures au multi-comptes.
Statuts
| Statut global | Signification |
|---|---|
scheduled | Programmée, pas encore partie |
processing | Au moins un réseau en cours de publication |
completed | Tous les réseaux ont réussi |
partial | Au moins un succès ET au moins un échec |
failed | Tous les réseaux ont échoué |
cancelled | Annulée avant publication |
Par réseau : pending → publishing → succeeded ou failed (+ inbox_delivered pour un brouillon TikTok). TikTok est résolu en différé : la cible reste publishing jusqu'à confirmation réelle par TikTok (suivi automatique côté serveur), là où beaucoup d'outils annoncent « publié » dès l'acceptation de la demande.
Consulter et annuler
curl https://api.kreatoai.com/v2/posts/9f1c8b2e-... \
-H "x-api-key: sk-kre-v1-votre_cle"La réponse inclut, pour chaque réseau, l'identifiant du post publié (externalPostId), son lien (postUrl, quand le réseau l'expose) et en cas d'échec failReason + failType. DELETE /v2/posts/:id annule une publication programmée non partie (204) ; déjà partie → 409 post_not_cancellable. Si vous avez configuré un webhook, inutile de poller : un événement par réseau vous est envoyé.
Réglages TikTok — brouillon ou publication directe
Par défaut, TikTok publie immédiatement et publiquement. Si vous préférez déposer le contenu dans les brouillons du créateur — qui relira puis publiera lui-même depuis l'app — passez options.tiktok.postMode à MEDIA_UPLOAD.
{
"targets": ["tiktok"],
"content": "Ma légende",
"mediaUrls": ["https://media.kreatoai.com/1.jpg", "https://media.kreatoai.com/2.jpg"],
"options": {
"tiktok": {
"postMode": "MEDIA_UPLOAD", // brouillon ; défaut : DIRECT_POST
"privacyLevel": "PUBLIC_TO_EVERYONE", // DIRECT_POST uniquement
"disableComment": false, // DIRECT_POST uniquement
"disableDuet": false, // DIRECT_POST uniquement, vidéo
"disableStitch": false, // DIRECT_POST uniquement, vidéo
"autoAddMusic": true // DIRECT_POST uniquement, carrousel
}
}
}En MEDIA_UPLOAD, confidentialité et interactions ne sont pas transmises : TikTok les fait choisir au créateur au moment où il publie. Les envoyer quand même n'a aucun effet.
| En brouillon | Carrousel d’images | Vidéo |
|---|---|---|
| Texte de la publication | Titre et description conservés | Non transmis — saisi dans l’app |
| Limite TikTok | — | 5 brouillons en attente / 24 h |
Cette asymétrie vient de TikTok : un carrousel en brouillon passe par content/init, qui accepte un titre, tandis qu'une vidéo passe par inbox/video/init, qui n'accepte aucune métadonnée. Prévoyez donc de communiquer la légende autrement si vous déposez des vidéos en brouillon.
Le suivi ne change pas : la cible reste publishing jusqu'à confirmation réelle, puis passe à inbox_delivered pour un brouillon livré, ou succeeded pour une publication en ligne.
Idempotence — évitez les doubles publications
Si votre workflow réessaie après un timeout réseau, le même appel peut partir deux fois — et sans protection, publier deux fois. Fournissez un idempotencyKey stable (par exemple l'identifiant de votre tâche interne) : si une publication existe déjà avec cette clé, l'API renvoie la publication existante (200) au lieu d'en créer une seconde. Recommandé pour toute intégration automatisée.
Validation et erreurs
Tout est vérifié avant d'accepter la requête — échec rapide avec le détail par réseau, plutôt qu'un échec silencieux trente secondes plus tard :
// 400 Bad Request
{
"error": "invalid_targets",
"message": "Certains réseaux ne peuvent pas recevoir cette publication.",
"details": [
{ "platform": "instagram", "error": "media_required_for_target" },
{ "platform": "tiktok", "error": "channel_not_connected" }
]
}| Code | Cause |
|---|---|
invalid_target | Réseau inconnu (valides : facebook, instagram, linkedin, tiktok) |
duplicate_target | Le même compte est visé deux fois (deux comptes distincts d’un même réseau sont valides) |
channel_not_connected | Aucun canal actif pour ce réseau, ou channelId inconnu de votre espace |
content_too_long_for_target | Texte au-delà de la limite du réseau (LinkedIn 3 000, Instagram/TikTok 2 200) |
media_required_for_target | Instagram et TikTok exigent au moins un média |
title_too_long_for_target | Carrousel TikTok : le texte sert de titre, 90 caractères max |
scheduled_at_in_past | Date de programmation déjà passée |
media_unreadable | Média inaccessible ou type indéterminable |
En cas d'échec de publication, failType distingue retriable (indisponibilité passagère, limite de débit — réessayer plus tard peut réussir) et permanent (média refusé, canal à reconnecter — réessayer est inutile). Ne bouclez jamais sur un échec permanent.
Limites actuelles
Un seul média est utilisé pour Facebook, Instagram et LinkedIn (le premier de mediaUrls) ; TikTok reçoit toutes les images en carrousel. Les réglages propres aux autres réseaux (Reel ou Story côté Instagram, visibilité LinkedIn) arrivent dans une prochaine itération — seul TikTok est réglable aujourd'hui, via options.tiktok.