Documentation de l'API DocSolved
DocSolved fournit une API REST pour extraire des données structurées de documents téléversés ou de pièces jointes d’e-mails normalisées. Les tâches persistantes, l’approbation humaine, les webhooks signés et les exports comptables prennent en charge les automatisations dans Make, n8n, Zapier ou des intégrations personnalisées.
Extrayez votre premier document en moins de 3 minutes
- Créez une clé API dans les Paramètres développeur. La portée
extractsuffit pour cette boucle ; la clé n'est affichée qu'une fois. - Soumettez le document comme tâche asynchrone, interrogez l'état jusqu'à la fin, récupérez le résultat.
- Chaque champ de
result.extracted_fields[]possède les mêmes clés :confidence,page,evidence(le texte source),match_statusetbounding_box. Sur la voie OCR, elles sont renseignées lorsque la valeur a pu être localisée sur la page (match_statusexact,fuzzyoullm_located) ; une valeur que l'OCR n'a pas pu ancrer estnot_foundavec un cadre nul. Les e-factures structurées sont analysées depuis leur XML : leurs champs ne portent ni page ni cadre.
cURL
export DOCAI_API_KEY="sk_docai_YOUR_KEY" # 1. submit (a retried submit with the same Idempotency-Key returns the same job) JOB_ID=$(curl -s -X POST https://docsolved.ai/api/v1/jobs \ -H "Authorization: Bearer $DOCAI_API_KEY" \ -H "Idempotency-Key: invoice-2026-0847" \ -F "[email protected]" | python3 -c 'import json,sys; print(json.load(sys.stdin)["job_id"])') # 2. poll until status is completed / review_required / failed until curl -s https://docsolved.ai/api/v1/jobs/$JOB_ID \ -H "Authorization: Bearer $DOCAI_API_KEY" | grep -qE '"status": ?"(completed|review_required|failed)"'; do sleep 2; done # 3. result curl -s https://docsolved.ai/api/v1/jobs/$JOB_ID/result \ -H "Authorization: Bearer $DOCAI_API_KEY"
Python
import os, time, requests
BASE = "https://docsolved.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['DOCAI_API_KEY']}"}
with open("invoice.pdf", "rb") as f:
submit = requests.post(f"{BASE}/jobs", headers={**HEADERS, "Idempotency-Key": "invoice-2026-0847"},
files={"file": ("invoice.pdf", f, "application/pdf")}, timeout=60)
submit.raise_for_status()
job_id = submit.json()["job_id"]
while True:
status = requests.get(f"{BASE}/jobs/{job_id}", headers=HEADERS, timeout=30).json()["status"]
if status in ("completed", "review_required", "failed"):
break
time.sleep(2)
result = requests.get(f"{BASE}/jobs/{job_id}/result", headers=HEADERS, timeout=30).json()["result"]
for field in result["extracted_fields"]:
print(field["field"], field["value"], field["confidence"], field.get("page"), field.get("evidence"))
JavaScript / Node.js 20+
import { readFile } from "node:fs/promises";
const BASE = "https://docsolved.ai/api/v1";
const headers = { Authorization: `Bearer ${process.env.DOCAI_API_KEY}` };
const form = new FormData();
form.append("file", new Blob([await readFile("invoice.pdf")], { type: "application/pdf" }), "invoice.pdf");
const submit = await fetch(`${BASE}/jobs`, { method: "POST", headers: { ...headers, "Idempotency-Key": "invoice-2026-0847" }, body: form });
const { job_id } = await submit.json();
let status;
do {
await new Promise((r) => setTimeout(r, 2000));
({ status } = await (await fetch(`${BASE}/jobs/${job_id}`, { headers })).json());
} while (!["completed", "review_required", "failed"].includes(status));
const { result } = await (await fetch(`${BASE}/jobs/${job_id}/result`, { headers })).json();
for (const f of result.extracted_fields) console.log(f.field, f.value, f.confidence, f.page, f.evidence);
Ensuite : webhooks au lieu du polling, envois idempotents, revue et approbation, exports, ingestion d'e-mails, ou la même API depuis un agent de codage via MCP.
Authentification
Créez et gérez vos clés API sur la page Paramètres développeur. Envoyez la clé comme jeton bearer ; les scopes et le quota mensuel de pages de la clé sont appliqués à chaque requête.
Authorization: Bearer sk_docai_<your_key>
Les clés API commencent par sk_docai_. Gardez-les secrètes. Elles ne sont affichées qu'une seule fois lors de leur création.
Utilisez la portée extract pour soumettre des tâches et lire leurs résultats. Ajoutez la portée history pour lister les enregistrements sauvegardés et télécharger les exports comptables, et la portée webhooks pour gérer les points de terminaison webhook. Ce sont les seules portées de clé API prises en charge. Les clés n'expirent pas ; révoquez une clé depuis les Paramètres développeur dès qu'elle n'est plus nécessaire.
Limites de débit
L'utilisation des analyses est régie par le quota de pages et de stockage de votre forfait. Il n'existe pas de plafond distinct par requête ou par jour.
Les clés API décomptent en outre les pages OCR du quota mensuel de pages de la clé.
Les requêtes à court de pages ou de stockage renvoient HTTP 402 ; une clé API ayant dépassé son quota mensuel de pages renvoie HTTP 429 avec un indice Retry-After.
Les points de terminaison auxiliaires (aides à la validation, création/test/relecture de webhooks, liens de partage publics) ont un garde-fou de 60 requêtes par minute et par IP, 600 pour les appelants authentifiés ; chaque 429 porte Retry-After en secondes. Les valeurs en vigueur sont publiées par GET /api/v1/capabilities sous rate_limits.
Format des erreurs
{
"detail": "File too large. Maximum upload size is 15 MB.",
"request_id": "3f1c9d2e8b4a4c0e9a7d1b2c3d4e5f60",
"error": {
"code": "FILE_TOO_LARGE",
"message": "File too large. Maximum upload size is 15 MB.",
"retryable": false,
"request_id": "3f1c9d2e8b4a4c0e9a7d1b2c3d4e5f60"
}
}
Testez error.code, jamais le texte. Codes : INVALID_REQUEST, AUTHENTICATION_REQUIRED, PERMISSION_DENIED, NOT_FOUND, FILE_TOO_LARGE, UNSUPPORTED_DOCUMENT, RATE_LIMITED, QUOTA_EXCEEDED, IDEMPOTENCY_KEY_CONFLICT, PROCESSING_TIMEOUT, INTERNAL_ERROR. Ne réessayez que si retryable est vrai, en respectant Retry-After, et renvoyez la même Idempotency-Key. Citez request_id (aussi envoyé dans l'en-tête X-Request-ID) quand vous contactez le support.
Compatibilité
Dans /api/v1, les changements sont uniquement additifs : chemins, champs, codes d'erreur et états de tâche ne sont jamais supprimés ni retypés. Les changements incompatibles sortent en /api/v2 avec au moins 12 mois de chevauchement, annoncés dans le journal des modifications et avec les en-têtes Deprecation et Sunset. Lisez GET /api/v1/capabilities au démarrage plutôt que de coder en dur formats et limites.
Extraction de document synchrone
POST/api/v1/analyze
Téléversez un document et obtenez les résultats d'extraction de manière synchrone. Idéal pour les petits documents (< 2 pages).
Requête
Données de formulaire multipart :
| Champ | Type | Description | |
|---|---|---|---|
file | file | obligatoire | PDF, PNG, JPG, HEIC, AVIF, TIFF, BMP ou WEBP (15 Mo max) |
filename | string | facultatif | Remplacer le nom de fichier affiché |
Exemple
curl -X POST https://docsolved.ai/api/v1/analyze \ -H "Authorization: Bearer sk_docai_..." \ -F "file=@purchase_order.pdf"
Réponse
{
"request_id": "3fa8...",
"filename": "purchase_order.pdf",
"document_type": "purchase_order",
"document_type_confidence": 0.94,
"summary": "Purchase order from Acme Corp to Widget Co.",
"language": "en",
"extracted_fields": [
{
"field": "po_number",
"value": "PO-2026-0042",
"confidence": 0.97,
"page": 1,
"evidence": "PO-2026-0042"
}
],
"warnings": [],
"ocr": { "pages": 1, "tokens": 312, "language": "eng+pol" },
"llm": { "status": "success", "provider": "openai", "model": "gpt-4o-mini" }
}
Extraction en flux (SSE)
POST/api/v1/analyze/stream
Identique à l'extraction synchrone, mais diffuse des Server-Sent Events indiquant la progression du traitement. Idéal pour les interfaces en temps réel.
Créer une tâche asynchrone
POST/api/v1/jobs
Téléversez un document et obtenez un identifiant de tâche. Le traitement s'effectue en arrière-plan.
curl -X POST https://docsolved.ai/api/v1/jobs \ -H "Authorization: Bearer sk_docai_..." \ -F "[email protected]"
{ "job_id": "abc123", "status": "queued", "request_id": "xyz..." }
Ingérer des pièces jointes par e-mail
POST/api/v1/ingest/email
Passerelle d'e-mails entrants indépendante du fournisseur. Postmark, Mailgun, SendGrid, Amazon SES, Make, n8n ou un autre adaptateur doit analyser la charge utile du fournisseur et envoyer les pièces jointes acceptées sous forme de données de formulaire multipart. DocSolved n'héberge pas de boîte aux lettres et n'effectue pas d'analyse MIME propre au fournisseur.
| Champ | Type | Description | |
|---|---|---|---|
message_id | string | obligatoire | Identifiant de message stable provenant du fournisseur |
source_namespace | string | obligatoire | Portée fournisseur/compte stable, telle que postmark:server-123 |
files | file[] | obligatoire | Répétez pour chaque pièce jointe prise en charge |
organization_id | string | facultatif | Espace de travail cible ; l'appelant doit disposer de l'autorisation d'importer |
curl -X POST https://docsolved.ai/api/v1/ingest/email \ -H "Authorization: Bearer sk_docai_..." \ -F "message_id=provider-message-42" \ -F "source_namespace=postmark:server-123" \ -F "organization_id=org_..." \ -F "[email protected];type=application/pdf" \ -F "[email protected];type=image/jpeg"
{
"message_id": "provider-message-42",
"source_namespace": "postmark:server-123",
"accepted_count": 1,
"duplicate_count": 1,
"jobs": [
{"job_id": "job-new", "status": "queued", "filename": "invoice.pdf", "duplicate": false},
{"job_id": "job-old", "status": "completed", "filename": "receipt.jpg", "duplicate": true}
]
}
L'idempotence comprend le propriétaire authentifié, l'espace de noms fournisseur/compte, la destination, l'identifiant du message, le nom de fichier normalisé, le contenu du fichier et l'occurrence parmi les pièces jointes identiques. Les nouvelles tentatives réordonnées du fournisseur renvoient les identifiants de tâche d'origine. Une ingestion échouée peut remettre en file la même tâche avec de nouveaux octets pour un maximum de trois tentatives au total ; les tâches actives et terminées ne sont jamais traitées deux fois.
Obtenir le statut de la tâche
GET/api/v1/jobs/{job_id}
curl https://docsolved.ai/api/v1/jobs/abc123 \ -H "Authorization: Bearer sk_docai_..."
{
"id": "abc123",
"status": "completed",
"progress_pct": 100,
"document_type": "invoice",
"pages_processed": 2
}
Statuts possibles : queued, processing, review_required, completed, failed, cancelled.
Obtenir le résultat de la tâche
GET/api/v1/jobs/{job_id}/result
Renvoie le résultat d'extraction complet une fois l'état de la tâche completed ou review_required. Accepte la portée extract ou history, si bien qu'une clé limitée à extract couvre toute la boucle envoi, interrogation, résultat.
curl https://docsolved.ai/api/v1/jobs/abc123/result \ -H "Authorization: Bearer sk_docai_..."
Exporter en JSON
POST/api/v1/export/json
Envoyez le résultat d'extraction dans le corps JSON et obtenez un fichier d'export propre.
curl -X POST https://docsolved.ai/api/v1/export/json \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_docai_..." \
-d '{"request_id":"...","extracted_fields":[...]}' \
-o export.json
Exporter en CSV
POST/api/v1/export/csv
curl -X POST https://docsolved.ai/api/v1/export/csv \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_docai_..." \
-d '{"request_id":"...","extracted_fields":[...]}' \
-o fields.csv
Exporter en XLSX
POST/api/v1/export/xlsx
Renvoie un classeur Excel avec des feuilles Résumé, Champs, Lignes d'articles, Avertissements et Métadonnées.
Lister l'historique
GET/api/v1/history
curl https://docsolved.ai/api/v1/history \ -H "Authorization: Bearer sk_docai_..."
Flux de révision et d’approbation
POST/api/v1/history/{record_id}/workflow
Appliquez une transition de flux contrôlée à un enregistrement sauvegardé. Cette route nécessite une session Clerk interactive : les clés API ne peuvent pas approuver de documents. Les membres d'un espace de travail peuvent réviser ; ses administrateurs peuvent approuver, demander des modifications ou rejeter. Le propriétaire d'un enregistrement personnel assume les deux rôles.
{
"action": "approve",
"comment": "Ready to post"
}
Actions : start_review, complete_review, reopen_review, submit_for_approval, approve, request_changes, reject et accept_partial_analysis. L'approbation valide ensemble l'événement d'audit du flux et l'événement de boîte d'envoi document.approved.
Supprimer tout l'historique
DELETE/api/v1/history
Supprime définitivement toutes les analyses enregistrées de votre compte.
Lister les clés API
GET/api/v1/keys
Créer une clé API
POST/api/v1/keys
curl -X POST https://docsolved.ai/api/v1/keys \
-H "Authorization: Bearer <clerk_session_token>" \
-H "Content-Type: application/json" \
-d '{"name": "My automation key", "scopes": "extract,history"}'
{
"id": "...",
"name": "My automation key",
"key": "sk_docai_...", // shown ONCE - save it now
"prefix": "sk_docai_abc",
"scopes": "extract,history",
"created_at": "2026-06-10T12:00:00Z"
}
Révoquer une clé API
DELETE/api/v1/keys/{key_id}
Créer un webhook
POST/api/v1/webhooks
curl -X POST https://docsolved.ai/api/v1/webhooks \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name": "My webhook", "endpoint_url": "https://my.app/hook", "event_types": ["document.completed", "document.review_required", "document.approved", "document.failed"]}'
La réponse inclut un secret pour la vérification de la signature. Enregistrez-le maintenant, il ne sera plus affiché.
Types d’événements webhook
| Événement | Lorsqu'il se déclenche |
|---|---|
document.completed | L'extraction est terminée et le résultat a été enregistré |
document.review_required | La validation ou le routage selon la confiance nécessite une révision humaine ; se déclenche également avec document.completed |
document.approved | Un approbateur autorisé a validé la décision d'approbation ; utilisez cet événement pour les écritures comptables |
document.failed | Le traitement a échoué ; les tâches ingérées par e-mail incluent des métadonnées sur la possibilité de nouvelle tentative et le nombre de tentatives |
document.approved, et non document.completed, comme point de contrôle pour enregistrer des données dans un système comptable. L'extraction peut être terminée alors que des champs nécessitent encore une correction.
Tester un webhook
POST/api/v1/webhooks/{webhook_id}/test
Vérifier la signature du webhook
Chaque livraison inclut ces en-têtes :
X-DocAI-Event. Type d'événement (par ex.document.completed)X-DocAI-Timestamp. Horodatage UTC au format ISO 8601X-DocAI-Signature.sha256=<hmac>
import hashlib, hmac
def verify(secret, body_str, timestamp, signature_header):
msg = f"{timestamp}.{body_str}"
digest = hmac.new(secret.encode(), msg.encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(f"sha256={digest}", signature_header)
Événements durables échoués
DocSolved réessaie automatiquement les livraisons sortantes. Si un événement durable de boîte d'envoi ne peut pas être développé après cinq tentatives, il devient un message non distribuable. Le propriétaire peut examiner les métadonnées sans exposer la charge utile stockée et relancer l'événement après avoir corrigé la cause.
GET/api/v1/webhook-outbox/failed
curl https://docsolved.ai/api/v1/webhook-outbox/failed \ -H "Authorization: Bearer sk_docai_..."
POST/api/v1/webhook-outbox/{event_id}/replay
curl -X POST https://docsolved.ai/api/v1/webhook-outbox/EVENT_ID/replay \ -H "Authorization: Bearer sk_docai_..."
Les mêmes contrôles sont disponibles dans Paramètres développeur → Événements nécessitant une attention. Les enregistrements de livraison et de boîte d'envoi terminaux sont conservés pendant 30 jours.
Utilisation avec Make / n8n / Zapier
Pour les importations directes, appelez /api/v1/jobs. Pour les e-mails entrants, laissez le fournisseur analyser les pièces jointes et appelez /api/v1/ingest/email avec un identifiant de message et un espace de noms source stables. Les deux routes créent les mêmes tâches persistantes et utilisent le même flux de révision.
Abonnez-vous aux événements de fin et de révision pour connaître l'état, puis utilisez document.approved pour déclencher des actions comptables aval contrôlées. Les webhooks signés éliminent la nécessité d'interroger le service.
Questions fréquentes
Comment m'authentifier auprès de l'API DocSolved ?
Créez une clé API sur /developer — elle n'est affichée qu'une seule fois — puis envoyez-la comme jeton Bearer dans l'en-tête Authorization : Authorization: Bearer sk_docai_your_key.
Quelle est la différence entre /api/v1/analyze et /api/v1/jobs ?
/api/v1/analyze renvoie le résultat dans la même requête, ce qui convient à une utilisation interactive. /api/v1/jobs met le document en file d'attente : vous interrogez le job ou recevez un webhook signé à la fin — préférable pour les lots et les documents volumineux.
Comment suis-je averti lorsqu'un document est terminé ?
Enregistrez un webhook. DocSolved envoie en POST un événement signé HMAC-SHA256 sur document.completed, document.review_required, document.failed et document.approved. Vérifiez l'en-tête X-DocAI-Signature et renvoyez un code HTTP 2xx dans les cinq secondes.
L'API fournit-elle des preuves de provenance pour les valeurs extraites ?
Pour les documents numérisés, chaque champ porte le texte dont il provient et, lorsque l'OCR a localisé la valeur, sa page et son cadre de délimitation. Les factures électroniques structurées sont analysées à partir de leur XML et n'ont volontairement aucun cadre de délimitation.