Aller au contenu

Migration du contrat de réponse v2

Cette page documente une mise à jour du contrat de réponse des endpoints publics /v2. Elle corrige plusieurs incohérences entre le comportement réel de l’API et ce qui était documenté : type de certains champs, structure des erreurs, réponses d’authentification.

EndpointChangement
POST /v2/extractor[/:agentReference]Erreurs enveloppées avec code ; metadata.duration passe de string à nombre
POST /v2/extractor (global)data initialisé à [] (plus null) ; metadata.thread_id ajouté
POST /v2/extractor/async[/:agentReference]Réponse immédiate simplifiée à {status, extract_id} ; callback et webhook d’échec enveloppés avec code et detail.http_status numérique
POST /v2/documentalist/:agentReferenceDéprécié (sunset 2026-11-30) — reste un flux texte HTTP 200 ; remplacé par /v2/knowledge
POST /v2/knowledge/:agentReferenceNouveau — réponse JSON classique avec de vrais status HTTP d’erreur (mêmes paramètres que /v2/documentalist)
GET /v2/tokenLe 401 renvoie désormais une enveloppe d’erreur (au lieu d’un corps vide)
Toutes les routes protégéesLes rejets 401/403 renvoient une enveloppe d’erreur (au lieu de {message: "Unauthorized"})
Endpoints organisation (/v2/organization/webhooks, /v2/organization/usage)Le code d’erreur 404 d’organisation introuvable passe de agent_not_found à organization_not_found

Erreurs synchrones (/v2/extractor et /v2/extractor/:agentReference)

Section intitulée « Erreurs synchrones (/v2/extractor et /v2/extractor/:agentReference) »

Avant — un message générique, identique quelle que soit la cause réelle de l’échec :

{
"status": "error",
"error": "Error while processing the extraction"
}

Après

{
"status": "error",
"code": "extraction_failed",
"error": "Extraction stream failed",
"detail": { }
}

code est désormais un identifiant machine stable (voir tableau des codes) — error reste un message humain qui peut évoluer sans préavis. detail est optionnel et absent la plupart du temps.

Avant

{ "metadata": { "duration": "3.45", "tokens_consumed": 1 } }

Après

{ "metadata": { "duration": 3.45, "tokens_consumed": 1 } }

Si votre client parse déjà duration avec parseFloat/Number() par précaution, aucun changement requis. Si vous concaténez ou comparez la valeur comme une string, adaptez le typage.

Avant — en cas d’échec de lecture du flux, data pouvait valoir null et metadata n’incluait pas thread_id :

{ "data": null, "metadata": { "filename": "facture.pdf", "duration": "0.00", "tokens_consumed": 0 } }

Aprèsdata est toujours un tableau ([] si rien n’a été extrait), et metadata.thread_id est désormais présent (déjà le cas pour l’extracteur avec agent) :

{ "data": [], "metadata": { "filename": "facture.pdf", "duration": 0, "tokens_consumed": 0, "thread_id": "01J..." } }

Réponse immédiate asynchrone (/v2/extractor/async et /v2/extractor/async/:agentReference)

Section intitulée « Réponse immédiate asynchrone (/v2/extractor/async et /v2/extractor/async/:agentReference) »

Avant

{
"status": "started",
"extract_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"message": "Old extraction id is deprecated, use extract_id instead",
"extraction_id": "550e8400-e29b-41d4-a716-446655440000"
}
}

Après

{
"status": "started",
"extract_id": "550e8400-e29b-41d4-a716-446655440000"
}

Le champ data (et extraction_id) était un résidu de l’ancien identifiant — il n’a plus lieu d’être. Si votre code lisait data.extraction_id, basculez sur extract_id (c’était déjà la valeur recommandée).

Concerne le callback transmis par requête et l’événement extraction.completed en échec.

Avant

{
"extract_id": "550e8400-e29b-41d4-a716-446655440000",
"error": "Extraction failed: Unable to process the document",
"detail": "HTTP status: 500"
}

Après

{
"status": "error",
"extract_id": "550e8400-e29b-41d4-a716-446655440000",
"code": "agent_timeout",
"error": "Agent response timed out",
"detail": { "http_status": 504 }
}

Trois changements : un champ status: "error" explicite apparaît (avant, l’absence de status: "success" était le seul signal d’échec) ; code porte désormais le vrai code machine de l’erreur (avant : toujours un message générique, aucun code) ; detail devient un objet { http_status: <number> } (avant : une string "HTTP status: X").

POST /v2/documentalist/:agentReference est déprécié (sunset 30 novembre 2026) et reste un flux texte brut HTTP 200 — c’est POST /v2/knowledge/:agentReference qui prend le relais, avec une réponse JSON classique et de vrais status HTTP d’erreur. Les deux endpoints acceptent les mêmes paramètres d’entrée (query, instructions optionnel, thread_id optionnel, historic optionnel).

Avant / toujours sur /v2/documentalist — HTTP 200, réponse en stream (un seul chunk émis) :

Désolé, je ne peux pas vous donner de réponse pour le moment.

Ce même texte d’excuse est renvoyé pour la plupart des échecs internes — impossible de distinguer une erreur réelle d’une réponse normale sans inspecter le contenu. Seuls agent_not_found et thread_not_found court-circuitent le flux avec un vrai 404 (corps texte brut, sans enveloppe JSON).

Après / sur /v2/knowledge — succès :

{
"status": "success",
"data": { "answer": "Dimarc est une plateforme d'intelligence artificielle..." },
"metadata": { "thread_id": "01J..." }
}

Après / sur /v2/knowledge — erreurs, avec de vrais status HTTP :

StatusCodeCas
404agent_not_foundAgent introuvable, mauvais type, privé, ou hors de votre organisation
404thread_not_foundthread_id fourni ne correspond pas à un thread de cet agent
503agent_unavailableFile de traitement indisponible
504agent_timeoutTimeout de la réponse agent
502extraction_failedL’agent n’a pas pu répondre

GET /v2/token — le succès est inchangé. Le 401 renvoie désormais une enveloppe :

Avant

(corps vide)

Après

{
"status": "error",
"code": "invalid_client",
"error": "Invalid client credentials"
}

Rejets d’authentification (toutes les routes protégées)

Section intitulée « Rejets d’authentification (toutes les routes protégées) »

Avant

{ "message": "Unauthorized" }

Après

StatusCodeCas
401unauthorizedEn-tête x-api-key manquant ou invalide
403forbiddenAccès API désactivé pour votre organisation
{ "status": "error", "code": "unauthorized", "error": "Unauthorized" }

L’ensemble des codes machine (code) que l’API peut renvoyer dans une enveloppe d’erreur :

CodeSignification
agent_not_foundAgent introuvable, mauvais type, privé, ou organisation invalide
thread_not_foundthread_id fourni introuvable pour cet agent
infected_fileFichier rejeté par l’antivirus
antivirus_unavailableService antivirus indisponible
agent_unavailableAgent temporairement indisponible (file de traitement)
agent_timeoutTimeout de la réponse agent
extraction_failedÉchec du traitement (extraction ou réponse knowledge)
classification_failedÉchec du traitement de classification
invalid_requestRequête invalide (validation du body ou de l’URL)
internal_errorErreur interne inattendue
unsupported_file_typeType de fichier non supporté
file_too_largeFichier dépassant la taille maximale autorisée
document_already_existsDocument déjà existant
document_not_foundDocument introuvable
quota_exceededQuota d’utilisation dépassé
invalid_agent_typeType d’agent invalide pour cet endpoint
invalid_configConfiguration d’agent invalide
webhook_not_foundAucun webhook configuré pour cet événement
organization_not_foundOrganisation introuvable
unauthorizedAuthentification manquante ou invalide
invalid_clientIdentifiants client invalides (/v2/token)
forbiddenAccès API désactivé pour l’organisation

Pour toute question sur cette migration, contactez notre équipe de support à l’adresse contact@dimarc.fr