Documentation technique
Documentation API EditCaption
Référence complète de l'API REST et du serveur MCP : authentification, endpoints, statuts de job, erreurs, exemples de code, pilotage de l'espace agence. Pour les tarifs et la création de clé, voir la page API.
Vue d'ensemble
L'API EditCaption fonctionne toujours selon le même schéma en 3 étapes : tu uploades un média, tu lances un traitement (un endpoint par outil), puis tu interroges le job jusqu'à ce qu'il soit terminé et tu télécharges le résultat. Les outils coûteux (sous-titres, transcription, son, voix) consomment les crédits de ton espace, au même tarif que dans le logiciel, réservés au lancement et remboursés intégralement si le job échoue ; les autres sont gratuits. L'API REST est incluse dans les formules Pro et Scale ; le serveur MCP, lui, dans toutes les formules, et il pilote aussi ton espace agence (marques, posts, programmation, statistiques).
# 1. Uploader une vidéo (fichier ou URL publique)
curl -X POST https://editcaption.com/api/v1/uploads \
-H "Authorization: Bearer ecap_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{"url": "https://exemple.com/ma-video.mp4"}'
# → { "uploadId": "…", "durationSeconds": 53, "expiresIn": 10800 }
# 2. Lancer un traitement (ici : sous-titres automatiques)
curl -X POST https://editcaption.com/api/v1/subtitles \
-H "Authorization: Bearer ecap_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{"uploadId": "…"}'
# → { "jobId": "…", "status": "queued", "creditsUsed": 18,
# "creditsRemaining": 9982, "estimatedSeconds": 80 }
# 3. Interroger le job jusqu'à "completed", puis télécharger
curl https://editcaption.com/api/v1/jobs/JOB_ID \
-H "Authorization: Bearer ecap_live_VOTRE_CLE"
# → { "status": "completed", "result": { "url": "/api/download/…", "filename": "…" } }Authentification
Toutes les routes /api/v1/* et le serveur MCP utilisent la même clé API, envoyée en en-tête HTTP standard :
Authorization: Bearer ecap_live_...| Format de la clé | ecap_live_… |
| Création | Depuis Mon compte → Développeur (la clé complète n'est affichée qu'une seule fois, à sa création), ou automatiquement quand tu autorises un connecteur MCP (Claude, ChatGPT, Perplexity, voir Serveur MCP), auquel cas elle n'est jamais affichée en clair, seulement utilisable par ce connecteur. |
| Stockage côté serveur | Seule une empreinte (sha256) est conservée : la clé en clair n'est jamais récupérable après sa création. |
| Révocation | Depuis le dashboard, à tout moment. Une clé révoquée renvoie immédiatement 401 sur tous les endpoints (et le serveur MCP). |
| Formules | L'accès dépend de la porte, pas de la clé : /api/v1 est réservé aux formules Pro et Scale (sinon 403 plan_required) ; le serveur MCP est ouvert à toutes les formules, Solo gratuite comprise. Une même clé sert aux deux et consomme les crédits de l'espace. |
Crédits & formules
Une seule règle pour le logiciel, le MCP et l'API : chaque outil a un coût fixe en crédits (grille ci-dessous et dans chaque endpoint), débité sur le portefeuille de l'espace (titulaire), partagé par l'équipe. Les crédits du mois de la formule partent en premier (remis à niveau chaque mois, sans report), puis les crédits rechargés (sans expiration). Un traitement en échec est remboursé intégralement, chaque pot de sa part.
| Solo | 300 crédits par mois (après vérification de l'e-mail) · API REST non incluse · MCP inclus · 20 requêtes/min |
| Starter | 4 000 crédits par mois · API REST non incluse · MCP inclus · 60 requêtes/min |
| Pro | 9 000 crédits par mois · API REST incluse · MCP inclus · 120 requêtes/min |
| Scale | 20 000 crédits par mois · API REST incluse · MCP inclus · 240 requêtes/min |
Recharges (formules payantes) depuis Réglages → Espace : 3 000 crédits pour 9 €, 7 000 crédits pour 19 €, 15 000 crédits pour 39 €. Solde à tout moment : GET /api/v1/account ou l'outil MCP whoami.
Limites & formats de fichiers
| Taille max par fichier | 5 Go, en upload direct comme en ingestion par URL. |
| Durée max | Aucune limite de durée dédiée : seule la limite de taille de 5 Go s'applique. |
| Formats vidéo en entrée | Tout format vidéo courant (mp4, mov, avi, mkv, webm…). Aucune vérification de format à l'upload : une erreur n'apparaît qu'au traitement si le fichier est illisible. |
| Formats vidéo en sortie | mp4, webm, mov, avi, mkv (convert) ; mp4 (sous-titres, filigrane, découpe, changement de voix, fusion). |
| Formats audio en sortie | mp3, wav, aac (extraction) ; wav (texte vers voix). |
| Rétention des fichiers | 3 heures après l'upload ou la complétion du job. Un résultat est téléchargeable plusieurs fois pendant cette fenêtre (contrairement au site grand public, où le fichier est supprimé après le premier téléchargement). |
| Limite de débit (rate limit) | Par compte et par minute, API et MCP confondus : Solo 20, Starter 60, Pro 120, Scale 240. Au-delà : 429 rate_limited avec l'en-tête Retry-After. Un polling toutes les 3 secondes reste sous la limite de Pro. |
Statuts des jobs & polling
Chaque traitement passe par 4 statuts possibles, renvoyés par GET /api/v1/jobs/:id :
queued | Le job est en file d'attente, pas encore pris en charge par un worker. |
processing | Le traitement est en cours. |
completed | Terminé avec succès. La réponse contient result.url et result.filename. |
failed | Échoué. La réponse contient un champ error (message). Les crédits réservés sont automatiquement remboursés en intégralité, sans action de ta part. |
Pas de webhooks : fais du polling
L'API n'envoie pas de callback HTTP à la complétion d'un job : il faut interroger GET /api/v1/jobs/:id périodiquement. Chaque réponse de lancement (status: "queued") renvoie un estimatedSeconds indicatif : c'est une bonne base pour ton premier délai d'attente. Recommandation pratique : poll toutes les 2 à 5 secondes, sans backoff agressif nécessaire (pas de limite de débit à ce jour), jusqu'à completed ou failed.
Gestion des erreurs
Toute erreur renvoie un corps JSON de la forme { error: { code, message } } avec le status HTTP correspondant. Les codes possibles, tous endpoints confondus :
| Status | code | Quand |
|---|---|---|
| 400 | invalid_request | Paramètre manquant ou invalide (détaillé par endpoint dans les sections ci-dessous). |
| 401 | unauthorized | En-tête Authorization absent, clé invalide ou révoquée. |
| 402 | insufficient_credits | Solde insuffisant. La réponse ajoute balance, required, upgradeUrl et, pour une formule payante, topupUrl. |
| 403 | plan_required | Formule sans accès à l'API REST (Pro et Scale seulement), ou compte sans espace. La réponse ajoute upgradeUrl. |
| 403 | email_not_verified | Formule Solo dont l'adresse e-mail n'est pas vérifiée (ses crédits gratuits sont bloqués). La réponse ajoute verifyUrl. |
| 429 | rate_limited | Trop de requêtes par minute pour ta formule. Voir l'en-tête Retry-After. |
| 404 | not_found | Job introuvable, expiré, ou appartenant à une autre clé API. |
| 500 | internal_error | Erreur serveur imprévue. Réessaie ; contacte-nous si ça persiste. |
{
"error": {
"code": "insufficient_credits",
"message": "Il te reste 12 crédits, cette action en demande 60. Recharge ici : https://editcaption.com/espace/reglages#credits, ou passe à une formule supérieure : https://editcaption.com/prix",
"balance": 12,
"required": 60,
"topupUrl": "https://editcaption.com/espace/reglages#credits",
"upgradeUrl": "https://editcaption.com/prix"
}
}Référence
Endpoints
Toutes les routes ci-dessous acceptent un corps JSON (Content-Type: application/json), sauf /api/v1/uploads qui accepte aussi le multipart.
/api/v1/uploadsUploader un média
Ingère un fichier vidéo ou audio, soit par upload multipart direct (champ "file"), soit en JSON avec une URL publique à télécharger. Retourne un uploadId réutilisable pendant 3 heures par tous les autres endpoints. Toujours la première étape avant d'appeler un outil.
Paramètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
file | string | — | Fichier binaire (multipart/form-data). Exclusif avec url. |
url | string | — | URL http(s) publique du média à télécharger (JSON). Exclusif avec file. |
Exemple de requête
curl -X POST https://editcaption.com/api/v1/uploads \
-H "Authorization: Bearer ecap_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{"url":"https://exemple.com/ma-video.mp4"}'Réponse 200
{
"uploadId": "3f2a9c7e-...",
"durationSeconds": 53,
"expiresIn": 10800
}Erreurs possibles
| 400 invalid_request | Ni file ni url fourni, URL invalide/inaccessible, ou fichier au-delà de 5 Go. |
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
| 500 internal_error | Erreur serveur imprévue. |
- ·Taille max : 5 Go, que ce soit en upload direct ou via URL (la limite est appliquée pendant le téléchargement, pas seulement sur l'en-tête Content-Length).
- ·La durée du média est mesurée immédiatement (ffprobe) et renvoyée dans la réponse : elle sert de base au calcul du coût des outils qui suivent.
/api/v1/subtitles20 crédits / minSous-titres automatiques incrustés
Transcrit l'audio et incruste des sous-titres stylés directement dans la vidéo (rendu, pas un simple fichier .srt à part — voir /api/v1/transcribe pour ça).
Paramètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
uploadIdrequis | string | — | Renvoyé par POST /api/v1/uploads. |
style | string | classique | classique = ombre portée, impact = fond rectangulaire, contour = contour épais coloré. Valeurs : classique | impact | contour |
color | string | #FFFFFF | Couleur du texte, hex #RRGGBB. |
effectColor | string | #000000 | Couleur de l'ombre (classique), du fond (impact) ou du contour (contour). |
position | number | 82 | 0 = haut de l'écran, 100 = bas. Attention : inversé par rapport au slider affiché sur editcaption.com. |
size | string | normale | Taille du texte. Valeurs : petite | normale | grande |
captionWords | integer | 4 | Mots par groupe de sous-titres affiché (ignoré si srtContent est fourni avec un découpage déjà fixé). Valeurs : 1 | 2 | 4 |
srtContent | string | — | Contenu .srt fourni par toi (bypass la transcription automatique) — utile pour réutiliser une transcription déjà corrigée. |
fontId | string | inter | Police d'affichage. Valeurs : inter | montserrat | poppins | fredoka | archivo-black | anton |
karaokeMode | string | none | Mise en valeur mot par mot façon karaoké. Ignoré si captionWords = 1. Valeurs : none | couleur | taille | halo |
highlightColor | string | #FFD166 | Couleur du mot actif en mode karaoké. |
shadowIntensity | number | 60 | 0-100. Style classique uniquement. |
contourThickness | number | 50 | 0-100. Style contour uniquement. |
boxOpacity | number | 75 | 0-100. Style impact uniquement. |
Exemple de requête
curl -X POST https://editcaption.com/api/v1/subtitles \
-H "Authorization: Bearer ecap_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{"uploadId":"3f2a9c7e-...","style":"impact","color":"#FFFFFF","position":85,"captionWords":2}'Réponse 200
{
"jobId": "b91c...",
"status": "queued",
"creditsUsed": 18,
"creditsRemaining": 9982,
"estimatedSeconds": 80
}Erreurs possibles
| 400 invalid_request | uploadId manquant, captionWords hors de {1,2,4}, ou srtContent ne contient pas de "-->". |
| 402 insufficient_credits | Solde de crédits inférieur au coût du traitement. La réponse contient balance et required. |
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
| 500 internal_error | Erreur serveur imprévue. |
/api/v1/transcribe15 crédits / minTranscription (texte ou SRT)
Transcrit l'audio d'une vidéo en fichier texte brut ou en sous-titres .srt téléchargeables — sans les incruster dans la vidéo.
Paramètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
uploadIdrequis | string | — | Renvoyé par POST /api/v1/uploads. |
language | string | auto | Code ISO 639-1 (fr, en, es…) ou "auto" pour la détection automatique. Voir l'annexe des langues. |
format | string | txt | txt = texte continu avec retours à la ligne en fin de phrase. srt = sous-titres horodatés. Valeurs : txt | srt |
srtSplitMode | string | phrase | Uniquement si format=srt. "phrase" regroupe les mots en phrases complètes, une par entrée. "mot" produit une entrée par mot, avec son propre timecode de début et de fin. Les deux conservent le texte tel quel (ponctuation et majuscules) : pour des sous-titres mis en forme et incrustés, voir /api/v1/subtitles. Valeurs : "phrase" | "mot" |
Exemple de requête
curl -X POST https://editcaption.com/api/v1/transcribe \
-H "Authorization: Bearer ecap_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{"uploadId":"3f2a9c7e-...","format":"srt","srtSplitMode":"mot"}'Réponse 200
{
"jobId": "b91c...",
"status": "queued",
"creditsUsed": 14,
"creditsRemaining": 9968,
"estimatedSeconds": 16
}Erreurs possibles
| 400 invalid_request | uploadId manquant, format invalide, ou srtSplitMode invalide. |
| 402 insufficient_credits | Solde de crédits inférieur au coût du traitement. La réponse contient balance et required. |
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
| 500 internal_error | Erreur serveur imprévue. |
/api/v1/clean-audio10 crédits / minAmélioration du son
Nettoie le bruit de fond et clarifie la voix d'une vidéo. Aucun paramètre de réglage : traitement automatique.
Paramètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
uploadIdrequis | string | — | Renvoyé par POST /api/v1/uploads. |
Exemple de requête
curl -X POST https://editcaption.com/api/v1/clean-audio \
-H "Authorization: Bearer ecap_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{"uploadId":"3f2a9c7e-..."}'Réponse 200
{
"jobId": "b91c...",
"status": "queued",
"creditsUsed": 9,
"creditsRemaining": 9959,
"estimatedSeconds": 80
}Erreurs possibles
| 400 invalid_request | uploadId manquant. |
| 402 insufficient_credits | Solde de crédits inférieur au coût du traitement. La réponse contient balance et required. |
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
| 500 internal_error | Erreur serveur imprévue. |
/api/v1/extract-audioGratuitExtraction audio
Extrait la piste audio d'une vidéo dans le format demandé.
Paramètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
uploadIdrequis | string | — | Renvoyé par POST /api/v1/uploads. |
format | string | mp3 | Format du fichier audio de sortie. Valeurs : mp3 | wav | aac |
Exemple de requête
curl -X POST https://editcaption.com/api/v1/extract-audio \
-H "Authorization: Bearer ecap_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{"uploadId":"3f2a9c7e-...","format":"wav"}'Réponse 200
{
"jobId": "b91c...",
"status": "queued",
"creditsUsed": 3,
"creditsRemaining": 9956,
"estimatedSeconds": 16
}Erreurs possibles
| 400 invalid_request | uploadId manquant ou format non supporté. |
| 402 insufficient_credits | Solde de crédits inférieur au coût du traitement. La réponse contient balance et required. |
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
| 500 internal_error | Erreur serveur imprévue. |
/api/v1/convertGratuitConversion de format
Convertit une vidéo vers un autre format conteneur.
Paramètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
uploadIdrequis | string | — | Renvoyé par POST /api/v1/uploads. |
format | string | mp4 | Format vidéo de sortie. Valeurs : mp4 | webm | mov | avi | mkv |
Exemple de requête
curl -X POST https://editcaption.com/api/v1/convert \
-H "Authorization: Bearer ecap_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{"uploadId":"3f2a9c7e-...","format":"webm"}'Réponse 200
{
"jobId": "b91c...",
"status": "queued",
"creditsUsed": 5,
"creditsRemaining": 9951,
"estimatedSeconds": 80
}Erreurs possibles
| 400 invalid_request | uploadId manquant ou format non supporté. |
| 402 insufficient_credits | Solde de crédits inférieur au coût du traitement. La réponse contient balance et required. |
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
| 500 internal_error | Erreur serveur imprévue. |
/api/v1/mergeGratuitFusion de vidéos
Fusionne au moins 2 vidéos déjà uploadées en une seule, concaténées dans l'ordre du tableau fourni.
Paramètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
uploadIdsrequis | array | — | Au moins 2 uploadId, dans l'ordre de fusion souhaité. |
Exemple de requête
curl -X POST https://editcaption.com/api/v1/merge \
-H "Authorization: Bearer ecap_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{"uploadIds":["3f2a9c7e-...","a11b22cc-..."]}'Réponse 200
{
"jobId": "b91c...",
"status": "queued",
"creditsUsed": 10,
"creditsRemaining": 9941,
"estimatedSeconds": 160
}Erreurs possibles
| 400 invalid_request | uploadIds absent, moins de 2 éléments, ou un élément n'est pas un uploadId valide. |
| 402 insufficient_credits | Solde de crédits inférieur au coût du traitement. La réponse contient balance et required. |
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
| 500 internal_error | Erreur serveur imprévue. |
- ·Le résultat est un nouveau fichier indépendant : les uploadIds sources restent valides (et téléchargeables séparément) jusqu'à leur propre expiration à 3h.
/api/v1/watermarkGratuitFiligrane image ou texte
Ajoute un filigrane en mosaïque répétée ("fixe") ou en position flottante qui change toutes les 3/5/8 secondes ("flottant"). Le filigrane peut être une image déjà uploadée ou un texte (rendu automatiquement en logo).
Paramètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
uploadIdrequis | string | — | Vidéo à filigraner, renvoyé par POST /api/v1/uploads. |
watermarkUploadId | string | — | uploadId d'une image (uploadée au préalable via /api/v1/uploads). Requis si watermarkText absent. |
watermarkText | string | — | Texte à convertir en logo. Requis si watermarkUploadId absent. |
type | string | fixe | fixe = mosaïque inclinée répétée sur toute l'image. flottant = une seule occurrence qui change de position. Valeurs : fixe | flottant |
opacity | integer | 80 | Opacité du filigrane. Valeurs : 10-100 |
interval | integer | 5 | Secondes entre deux positions. Mode flottant uniquement. Valeurs : 3 | 5 | 8 |
Exemple de requête
curl -X POST https://editcaption.com/api/v1/watermark \
-H "Authorization: Bearer ecap_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{"uploadId":"3f2a9c7e-...","watermarkText":"@moncompte","type":"flottant","opacity":70}'Réponse 200
{
"jobId": "b91c...",
"status": "queued",
"creditsUsed": 5,
"creditsRemaining": 9936,
"estimatedSeconds": 80
}Erreurs possibles
| 400 invalid_request | uploadId manquant, ni watermarkUploadId ni watermarkText fourni, ou type invalide. |
| 402 insufficient_credits | Solde de crédits inférieur au coût du traitement. La réponse contient balance et required. |
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
| 500 internal_error | Erreur serveur imprévue. |
/api/v1/trimGratuitDécoupe d'un extrait
Extrait le segment [start, end] d'une vidéo, en secondes.
Paramètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
uploadIdrequis | string | — | Renvoyé par POST /api/v1/uploads. |
startrequis | number | — | Début de l'extrait en secondes, ≥ 0. |
endrequis | number | — | Fin de l'extrait en secondes, doit être > start. |
Exemple de requête
curl -X POST https://editcaption.com/api/v1/trim \
-H "Authorization: Bearer ecap_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{"uploadId":"3f2a9c7e-...","start":12.5,"end":45}'Réponse 200
{
"jobId": "b91c...",
"status": "queued",
"creditsUsed": 2,
"creditsRemaining": 9934,
"estimatedSeconds": 48
}Erreurs possibles
| 400 invalid_request | uploadId manquant, start < 0, ou end ≤ start. |
| 402 insufficient_credits | Solde de crédits inférieur au coût du traitement. La réponse contient balance et required. |
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
| 500 internal_error | Erreur serveur imprévue. |
- ·La vidéo source du découpage n'est pas consommée par cet appel : elle reste utilisable pour d'autres extraits jusqu'à son expiration à 3h.
/api/v1/text-to-speech15 crédits / 1 000 car. (40 en voix clonée)Texte vers voix
Génère un fichier audio (.wav) à partir d'un texte, avec une voix du catalogue ou la voix clonée du compte.
Paramètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
textrequis | string | — | Texte à synthétiser. |
voice | string | lea | "clone" utilise la voix clonée enregistrée sur le compte propriétaire de la clé — erreur 400 si aucune voix n'a été enregistrée sur editcaption.com. Valeurs : id from GET /api/v1/voices | clone |
Exemple de requête
curl -X POST https://editcaption.com/api/v1/text-to-speech \
-H "Authorization: Bearer ecap_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{"text":"Bienvenue dans cette vidéo générée automatiquement.","voice":"thomas"}'Réponse 200
{
"jobId": "b91c...",
"status": "queued",
"creditsUsed": 1,
"creditsRemaining": 9933,
"estimatedSeconds": 10
}Erreurs possibles
| 400 invalid_request | text manquant, voice invalide, ou voice="clone" sans voix clonée enregistrée sur le compte. |
| 402 insufficient_credits | Solde de crédits inférieur au coût du traitement. La réponse contient balance et required. |
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
| 500 internal_error | Erreur serveur imprévue. |
/api/v1/voice-change25 crédits / min (60 en voix clonée)Changement de voix
Retranscrit la parole d'une vidéo puis remplace entièrement sa piste audio par une nouvelle voix de synthèse.
Paramètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
uploadIdrequis | string | — | Renvoyé par POST /api/v1/uploads. |
voice | string | lea | Voix de remplacement. "clone" nécessite une voix clonée sur le compte. Valeurs : id from GET /api/v1/voices | clone |
language | string | fr | Langue parlée dans la vidéo source (code ISO 639-1), utilisée pour la transcription intermédiaire. |
Exemple de requête
curl -X POST https://editcaption.com/api/v1/voice-change \
-H "Authorization: Bearer ecap_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{"uploadId":"3f2a9c7e-...","voice":"camille"}'Réponse 200
{
"jobId": "b91c...",
"status": "queued",
"creditsUsed": 12,
"creditsRemaining": 9921,
"estimatedSeconds": 80
}Erreurs possibles
| 400 invalid_request | uploadId manquant, voice invalide, voice="clone" sans voix clonée, ou aucune parole détectée dans la vidéo. |
| 402 insufficient_credits | Solde de crédits inférieur au coût du traitement. La réponse contient balance et required. |
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
| 500 internal_error | Erreur serveur imprévue. |
/api/v1/jobs/{id}Statut d'un job
Interroge l'état d'un traitement lancé par un des 10 endpoints outils. Un job n'est visible que par la clé API qui l'a créé (une autre clé, même sur le même compte, reçoit 404).
Paramètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
idrequis | string | — | jobId renvoyé par l'endpoint outil (dans l'URL, pas dans le corps). |
Exemple de requête
curl -X GET https://editcaption.com/api/v1/jobs/JOB_ID \
-H "Authorization: Bearer ecap_live_VOTRE_CLE"Réponse 200
{
"jobId": "b91c...",
"status": "completed",
"result": {
"url": "/api/download/3f2a9c7e-...",
"filename": "video-sous-titres.mp4"
}
}Erreurs possibles
| 404 not_found | jobId inexistant, expiré (> 3h après complétion), ou appartenant à une autre clé. |
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
- ·result.url est un chemin relatif : préfixe-le avec https://editcaption.com pour obtenir un lien téléchargeable.
- ·Le fichier reste téléchargeable plusieurs fois pendant 3 heures après complétion — ce n'est pas un lien à usage unique.
/api/v1/accountSolde de crédits
Retourne le solde de crédits actuel (crédits inclus dans ta formule Agence + crédits achetés) et l'email du compte propriétaire de la clé API.
Exemple de requête
curl -X GET https://editcaption.com/api/v1/account \
-H "Authorization: Bearer ecap_live_VOTRE_CLE"Réponse 200
{
"balance": 12940,
"purchased": 9940,
"included": 3000,
"includedMonthly": 3000,
"includedRenewsAt": "2026-11-07T09:00:00.000Z",
"email": "toi@exemple.com"
}Erreurs possibles
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
/api/v1/voicesCatalogue des voix
Liste les voix utilisables avec text-to-speech et voice-change (plus de 100 voix en 8 langues). Passe l'id d'une voix dans le paramètre voice. Gratuit.
Paramètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
language | string | — | Filtre par langue (query string). Valeurs : fr | en | es | pt | de | it | ar | nl |
gender | string | — | Filtre par genre (query string). Valeurs : f | m |
lang | string | fr | Langue des descriptions renvoyées. Valeurs : fr | en |
Exemple de requête
curl -X GET https://editcaption.com/api/v1/voices \
-H "Authorization: Bearer ecap_live_VOTRE_CLE"Réponse 200
{
"voices": [
{
"id": "lea",
"name": "Léa",
"language": "fr",
"gender": "f",
"description": "Jeune, claire, pétillante",
"usages": [
"Réseaux",
"Dynamique"
]
}
],
"clone": "clone"
}Erreurs possibles
| 401 unauthorized | En-tête Authorization manquant, clé invalide ou révoquée. |
- ·"clone" n'apparaît pas dans la liste : c'est la voix clonée enregistrée sur ton compte editcaption.com.
Exemples de code complets
Un flux complet upload → traitement → attente → résultat, en JavaScript et en Python. Remplace l'URL d'exemple et la clé API par les tiennes.
// Node.js 18+ (fetch natif) ou navigateur. npm install non nécessaire.
const API_KEY = "ecap_live_VOTRE_CLE";
const BASE = "https://editcaption.com";
async function call(path, body) {
const res = await fetch(BASE + path, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? res.statusText);
return data;
}
async function waitForJob(jobId) {
while (true) {
const res = await fetch(`${BASE}/api/v1/jobs/${jobId}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
const data = await res.json();
if (data.status === "completed") return data.result;
if (data.status === "failed") throw new Error(data.error);
await new Promise((r) => setTimeout(r, 3000)); // pas de webhook : on poll toutes les 3s
}
}
async function main() {
const upload = await call("/api/v1/uploads", { url: "https://exemple.com/ma-video.mp4" });
const job = await call("/api/v1/subtitles", { uploadId: upload.uploadId, style: "impact" });
const result = await waitForJob(job.jobId);
console.log("Vidéo prête :", BASE + result.url);
}
main();Agents IA
Serveur MCP
EditCaption expose un serveur MCP distant (Streamable HTTP) à https://editcaption.com/api/mcp. Une fois branché, les outils vidéo ci-dessous et les outils de l'espace agence apparaissent directement dans ton agent, sans rien installer.
Connexion en un clic (recommandé)
EditCaption implémente un vrai serveur d'autorisation OAuth 2.1 (RFC 8414 + RFC 9728, Dynamic Client Registration RFC 7591) au-dessus du serveur MCP. Les connecteurs personnalisés natifs de Claude, ChatGPT et Perplexity le détectent automatiquement : colle l'URL ci-dessous dans leur écran « Ajouter un connecteur personnalisé », connecte-toi à ton compte EditCaption, clique « Autoriser ». Aucune clé à copier-coller : une clé API est créée et gérée automatiquement en coulisses (visible et révocable dans Mon compte → Développeur, sous le libellé « Connecteur MCP »). Le détail des clics exacts par plateforme est sur la page API.
https://editcaption.com/api/mcpAlternative manuelle (sans OAuth)
Pour un client MCP qui ne fait pas de découverte OAuth (script, environnement headless, ancienne config…), crée une clé depuis Mon compte → Développeur (formules Pro et Scale) et passe-la en en-tête statique :
{
"mcpServers": {
"editcaption": {
"url": "https://editcaption.com/api/mcp",
"headers": { "Authorization": "Bearer ecap_live_VOTRE_CLE" }
}
}
}Outils vidéo
| upload_media | Ingère un fichier depuis une URL publique. Retourne uploadId + durationSeconds. |
| generate_subtitles | Sous-titres automatiques incrustés.20 crédits / min. |
| transcribe_video | Transcription en texte ou SRT.15 crédits / min. |
| clean_audio | Amélioration du son.10 crédits / min. |
| extract_audio | Extraction audio (mp3/wav/aac).Gratuit. |
| convert_video | Conversion de format (mp4/webm/mov/avi/mkv).Gratuit. |
| merge_videos | Fusion de plusieurs vidéos.Gratuit. |
| add_watermark | Filigrane image ou texte, mosaïque ou flottant.Gratuit. |
| trim_video | Découpe d'un segment [start, end].Gratuit. |
| list_voices | Catalogue des voix (plus de 100, 8 langues) pour text_to_speech et change_voice. Gratuit. |
| text_to_speech | Texte vers voix.15 crédits / 1 000 car. (40 en voix clonée). |
| change_voice | Remplace la voix d'une vidéo.25 crédits / min (60 en voix clonée). |
| get_job_status | Statut d'un job (queued/processing/completed/failed). |
Exemples de prompts
- « Uploade cette vidéo https://exemple.com/interview.mp4 et ajoute-lui des sous-titres style impact, texte blanc. »
- « Prends cette vidéo, découpe les 30 premières secondes, puis convertis le résultat en webm. »
- « Extrais l'audio de cette vidéo en mp3, puis transcris-le en anglais. »
- « Fusionne ces trois vidéos dans cet ordre, puis ajoute un filigrane texte "@moncompte" en position flottante. »
Toutes les formules
Piloter ton espace agence avec Claude
Le même serveur MCP donne accès à ton espace agence : ton assistant lit la stratégie de chaque marque, crée les posts de ton planning, y ajoute les médias, les programme et te fait le point sur les statistiques, avec exactement les mêmes règles que dans le logiciel (accès par marque, validation client, délai de 30 minutes, options TikTok).
| Accès | Toutes les formules, Solo gratuite comprise, avec les limites de la formule (marques, membres, stockage). Un membre de l'équipe voit seulement ses marques. |
| Coût | Gratuit : gérer marques, posts, programmations et statistiques ne consomme aucun crédit. Seuls les outils vidéo coûteux en consomment, comme dans le logiciel (voir Crédits & formules). |
| Dates | ISO 8601. Sans fuseau (2026-10-12T18:00), l'heure est lue dans le fuseau de l'espace (outil whoami). |
| Publication automatique | Posts vidéo, comptes connectés, au moins 30 minutes d'avance. Si ton client exige de valider, le post doit être validé à l'heure prévue. Pour TikTok, l'assistant doit te demander qui peut voir la vidéo (privacyLevel) : il ne le choisit jamais seul. |
| Médias | attach_media accepte une URL publique, un uploadId (upload_media) ou le jobId d'un outil vidéo terminé : sous-titre une vidéo puis ajoute directement le résultat à un post. |
Outils de l'espace agence
| whoami | ()Compte connecté, espace, formule, fuseau horaire, soldes de crédits (inclus + achetés), réseaux en publication automatique, heure actuelle. |
| list_brands | ()Marques accessibles : id, validation client exigée ou non, langue du client, nombre de posts, comptes réseaux (id, réseau, pseudo). |
| get_brand | (brandId)Tout pour écrire pour une marque : stratégie, couleurs, sujets du moment, idées, à faire, veille, comptes (id, connexion, publication auto possible), étiquettes, formats possibles par réseau. |
| list_posts | (brandId, from?, to?, status?, includeUnscheduled?)Posts du planning sur une période (dates incluses) et/ou un statut ; includeUnscheduled ajoute les posts sans date. |
| get_post | (postId)Fiche complète : légende, script, statut, médias (versions de la vidéo, cover, images), comptes visés et état de publication, options TikTok, commentaires, chiffres des publications. |
| create_post | (brandId, title, type?, caption?, script?, scheduledAt?, accountIds?, labelIds?, status?)Crée un post (format par défaut VIDEO_VERTICALE, statut par défaut A_ECRIRE). Un compte incompatible avec le format est refusé. |
| update_post | (postId, title?, type?, caption?, script?, scheduledAt?, accountIds?, labelIds?, status?, correctionReason?)Ne change que les champs passés. accountIds remplace toute la liste. Changer la date déplace aussi une publication programmée (refusé si publié ou à moins de 30 min). scheduledAt: null retire la date. |
| delete_post | (postId, confirm: true)Supprime définitivement un post et ses fichiers, après confirmation de l'utilisateur. |
| attach_media | (postId, role, url | uploadId | jobId, accountId?, filename?)role : final (vidéo publiée, nouvelle version), cover (remplace), slide (image de carrousel, ajoutée à la suite), rush. Une seule source : URL publique, uploadId (upload_media) ou jobId d'un outil vidéo terminé. accountId = version propre à un compte. |
| add_comment | (postId, text, internal?)Commente un post. internal (par défaut true) = note d'équipe que le client ne voit jamais ; false = visible sur son portail. |
| get_publish_options | (postId, accountId)Pour un compte du post : ce qui bloque ou avertit pour programmer ou publier, et pour TikTok les niveaux de confidentialité autorisés et les réglages du créateur. |
| schedule_publication | (postId, accountId, tiktok?)Active la publication automatique du compte à la date du post (30 min d'avance minimum, posts vidéo, comptes connectés). tiktok = { privacyLevel (obligatoire, choisi par l'utilisateur), allowComments, allowDuet, allowStitch, discloseCommercial, yourBrand, brandedContent }. |
| publish_now | (postId, accountId, tiktok?)Publie tout de suite sur ce compte (remplace une programmation en attente). Mêmes options TikTok. |
| cancel_publication | (postId, accountId)Annule la publication programmée d'un compte ; le post reste au planning. |
| mark_published | (postId, accountId, permalink?, published?)Pour une publication faite à la main : marque le compte comme publié (avec le lien) ; published: false annule. |
| get_brand_stats | (brandId, range? (24h | 7d | 30d | 1y | all))Statistiques des comptes connectés : abonnés, vues, likes, publications gagnés sur la période, comparés à la période précédente, et chiffres par compte. Défaut 30d. |
| get_account_posts | (accountId, sort? (recent | best | worst), limit? (1-50))Publications d'un compte connecté avec leurs chiffres et la moyenne de vues du compte. accountId vient de get_brand_stats. |
| get_today | ()Toutes marques confondues : à faire (échecs de publication, posts à publier à la main ou en retard, reportings), retours clients récents, semaine en cours. |
Référence
| Statuts (status) | A_ECRIRE à écrireA_TOURNER à tournerA_MONTER à monterA_VALIDER envoyé au client pour validationA_CORRIGER modification demandée (correctionReason)VALIDE validéPUBLIE publié |
| Formats (type) | VIDEO_VERTICALE vidéo 9:16 (Reel, TikTok, Shorts)VIDEO_HORIZONTALE vidéo 16:9CARROUSEL carrousel d'imagesIMAGE image seuleSTORY storyTEXTE texte seul (LinkedIn, X, Threads…) |
| Deux sortes d'id de compte | Les comptes d'une marque (get_brand, list_brands) servent à create_post, update_post, attach_media et à la publication. Les comptes connectés renvoyés par get_brand_stats servent seulement à get_account_posts. |
| Erreurs | Un refus revient comme résultat d'outil en erreur (isError), avec un message qui explique quoi faire et donne le lien (recharger, changer de formule, vérifier l'e-mail…), dans la langue du compte : l'assistant le relaie tel quel. |
Exemples de demandes
- « Regarde la stratégie de Maison Fleur et prépare 5 posts pour la semaine prochaine, un par jour à 18 h, sur Instagram et TikTok. »
- « Sous-titre cette vidéo aux couleurs de la marque, ajoute-la au post de jeudi et programme-la sur TikTok. »
- « Envoie tous les posts prêts de la semaine en validation à mon client. »
- « Fais-moi le point sur les statistiques TikTok du mois et dis-moi quels formats marchent le mieux. »
Claude Code & agents IA
Pour utiliser EditCaption comme outil dans Claude Code (ou tout autre client MCP : Claude Desktop, Cursor, Codex…), ajoute un serveur MCP distant en HTTP. Le CLI gère l'autorisation OAuth automatiquement (ouvre ton navigateur, même flux que Claude.ai) :
# Le CLI ouvre ton navigateur pour te connecter et autoriser l'accès —
# aucune clé à saisir, même flux que Claude.ai / Claude Desktop.
claude mcp add --transport http editcaption https://editcaption.com/api/mcpSans navigateur disponible (headless, CI…), passe une clé statique en en-tête à la place :
# Si le navigateur n'est pas disponible (environnement headless/CI), utilise
# une clé statique créée depuis Mon compte → Développeur :
claude mcp add --transport http editcaption \
https://editcaption.com/api/mcp \
--header "Authorization: Bearer ecap_live_VOTRE_CLE"La syntaxe exacte des options peut varier selon ta version (claude mcp add --help). Pour Claude Desktop ou tout autre client à fichier de config, colle plutôt le bloc mcpServers vu dans la section Serveur MCP.
Une fois connecté, demande directement à l'agent ce que tu veux faire en langage naturel (voir les exemples ci-dessus) : il choisit lui-même les bons outils MCP, uploade le média, lance le traitement, attend le résultat et l'ajoute à ton planning.
OpenAPI / Swagger
Le schéma OpenAPI 3.1 complet (tous les endpoints REST, schémas de requête/réponse, erreurs) est disponible en téléchargement. Importe-le directement dans Postman, Insomnia, ou l'éditeur Swagger pour générer une collection de requêtes ou un client dans le langage de ton choix.
Télécharger openapi.jsonAnnexe : codes de langue
Codes ISO 639-1 acceptés par les paramètres language (transcription, changement de voix). Utilise auto pour laisser l'API détecter la langue automatiquement.
autoDétection automatiqueafAfrikaanssqAlbanaisamAmhariquearArabehyArménienasAssamaisazAzerbaïdjanaisbaBachkireuBasquebeBiélorussebnBengalibsBosnienbrBretonbgBulgaremyBirmancaCatalanzhChinoishrCroatecsTchèquedaDanoisnlNéerlandaisenAnglaisetEstonienfoFéroïenfiFinnoisfrFrançaisglGalicienkaGéorgiendeAllemandelGrecguGujaratihtCréole haïtienhaHaoussahawHawaïenheHébreuhiHindihuHongroisisIslandaisidIndonésienitItalienjaJaponaisjwJavanaisknKannadakkKazakhkmKhmerkoCoréenloLaotienlaLatinlvLettonlnLingalaltLituanienlbLuxembourgeoismkMacédonienmgMalgachemsMalaismlMalayalammtMaltaismiMaorimrMarathimnMongolneNépalaisnoNorvégiennnNorvégien (Nynorsk)ocOccitanpsPachtofaPersanplPolonaisptPortugaispaPendjabiroRoumainruRussesaSanskritsrSerbesnShonasdSindhisiCingalaisskSlovaqueslSlovènesoSomaliesEspagnolsuSoundanaisswSwahilisvSuédoistlTagalogtgTadjiktaTamoulttTatarteTélougouthThaïboTibétaintrTurctkTurkmèneukUkrainienurOurdouuzOuzbekviVietnamiencyGalloisyiYiddishyoYorubaUne question, un cas d'usage précis ?
contact@editcaption.com