API d'extraction de factures
Reference pour extraction texte, fichier, URL image et ZUGFeRD avec la structure de reponse actuelle.
Parsurai expose des endpoints d'extraction pour texte, uploads de fichiers, URLs distantes et PDFs ZUGFeRD niveau Pro. L'extraction standard utilise la meme enveloppe de reponse pour tous les formats d'entree.
Vue d'ensemble des endpoints
| Endpoint | Entree | Offre |
|---|---|---|
POST /v1/extract | Body JSON avec text | Free et plus |
POST /v1/extract/file | PDF ou image multipart | Free et plus |
POST /v1/extract/url | Body JSON avec url | Free et plus |
POST /v1/extract/zugferd | PDF multipart avec XML integre | Pro et Business |
Extraire depuis du texte
/v1/extractFree{
"text": "Facture de Supplier Inc. Numero INV-9812. Total: 1500 EUR. TVA: 19%.",
"locale": "auto"
}
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
text | string | Oui | Texte brut de facture, 1 a 8000 caracteres |
locale | string | Non | auto, en, de, fr, es ou nl; les locales explicites exigent Hobby ou superieur |
curl -X POST https://api.parsurai.com/v1/extract \
-H "X-API-Key: $PARSURAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "Facture de Supplier Inc. INV-9812. Total: 1500 EUR. TVA: 19%.", "locale": "auto"}'
Extraire depuis un fichier
/v1/extract/fileFreeEnvoyez un PDF ou une image en multipart. L'indice de locale est lu depuis la query.
curl -X POST "https://api.parsurai.com/v1/extract/file?locale=fr" \
-H "X-API-Key: $PARSURAI_API_KEY" \
-F "file=@invoice.pdf"
Extraire depuis une URL
/v1/extract/urlFree{
"url": "https://example.com/invoices/inv-01.jpg",
"locale": "auto"
}
Schema de reponse
{
"invoice_id": "2f7d7f8a-32fb-4a7c-a3b1-53b61b64252f",
"invoice": {
"document_type": "invoice",
"vendor": {
"name": "Supplier Inc.",
"address": "Main Street 1, 10115 Berlin",
"email": null,
"phone": null,
"tax_id": "DE123456789",
"iban": "DE89370400440532013000",
"bank_name": null
},
"buyer": {
"name": "Buyer GmbH",
"address": null,
"email": null,
"phone": null,
"tax_id": "DE987654321",
"iban": null,
"bank_name": null
},
"invoice_number": "INV-9812",
"issue_date": "2026-06-13",
"due_date": "2026-07-13",
"billing_period_start": null,
"billing_period_end": null,
"reference_numbers": [{ "type": "order", "value": "PO-7781" }],
"line_items": [
{
"description": "Consulting",
"quantity": 1,
"unit": "hour",
"unit_price": 1500.0,
"discount": null,
"total": 1500.0,
"tax_rate": 0.19
}
],
"subtotal": 1500.0,
"discount_total": null,
"tax_breakdown": [
{
"tax_type": "VAT",
"rate": 0.19,
"taxable_amount": 1500.0,
"tax_amount": 285.0
}
],
"tax_total": 285.0,
"total_amount": 1785.0,
"amount_paid": null,
"amount_due": 1785.0,
"currency": "EUR",
"payment_terms": "Net 30",
"payment_instructions": "Pay by bank transfer.",
"locale": "de",
"confidence": 0.97,
"field_confidence": {},
"notes": []
},
"duplicate_risk": null,
"anomalies": [],
"confidence_low": false,
"field_bboxes": null
}
Reference des champs
| Champ | Type | Description |
|---|---|---|
invoice_id | UUID string | Identifiant unique du resultat |
invoice.document_type | string | invoice, credit_note, pro_forma, receipt ou other |
invoice.vendor.* | object | Champs vendeur: name, address, email, phone, tax_id, iban, bank_name |
invoice.buyer.* | object | Champs acheteur avec la meme structure |
invoice.reference_numbers[] | array | References avec type et value |
invoice.line_items[].tax_rate | number ou null | Taux fiscal decimal |
invoice.tax_breakdown[] | array | Lignes de taxe avec tax_type, rate, taxable_amount et tax_amount requis |
invoice.total_amount | number | Montant total requis |
invoice.confidence | number | Confiance d'extraction de 0.0 a 1.0 |
duplicate_risk | object ou null | Signal de doublon pour Pro et Business |
anomalies | array | Flags d'anomalie pour Pro et Business |
field_bboxes | object ou null | Bounding boxes de champs pour uploads fichier Pro et Business si disponibles |
Locales supportees
| Code | Langue |
|---|---|
auto | Detection automatique |
en | Anglais |
de | Allemand |
fr | Francais |
es | Espagnol |
nl | Neerlandais |
Les valeurs explicites autres que auto exigent Hobby, Starter, Pro ou Business.
Champs de reponse limites par offre
La reponse top-level contient toujours duplicate_risk, anomalies, confidence_low et field_bboxes, mais leurs valeurs dependent de l'offre et du type d'entree.
| Champ | Quand il est renseigne |
|---|---|
duplicate_risk | Flows d'extraction Pro et Business apres execution du scoring de doublon |
anomalies | Flows d'extraction Pro et Business apres execution des controles d'anomalie |
field_bboxes | Uploads fichier Pro et Business quand les spans OCR sont disponibles |
confidence_low | Toujours present; actuellement false sauf si le backend marque une faible confiance |
accuracy | Offres Pro et Business pour rapporter les metadaten du mode standard et enhanced |
Mode de precision (Accuracy Mode)
Pour prendre en charge les workflows de haute precision, Parsurai propose un Mode de precision ameliore (Enhanced Accuracy Mode) accessible uniquement avec les offres Pro et Business.
Paramètres
accuracy_mode(string) : Defini surstandardouenhanced.- Valeur par defaut :
standard - Pris en charge sur : Le body JSON pour
POST /v1/extractandPOST /v1/extract/url; le parametre de requeteaccuracy_modepourPOST /v1/extract/file. - Restriktion d'offre :
enhancedest reserve aux offres Pro et Business. Les requetes avec le mode de precisionenhancedsur des offres inferieures echoueront avec une erreur402 feature_not_in_plan.
- Valeur par defaut :
Fonctionnement
Contrairement a l'extraction standard, le Mode de precision ameliore applique :
- Validateurs deterministes : Execution de regles de verification (par exemple, verifier que les postes correspondent aux sous-totaux, totaux, calculs de TVA/taxes, et dates).
- Une tentative de correction bornee : Si une validation echoue, le moteur effectue une unique tentative de correction a l'aide du LLM avec les details de l'erreur.
- Compromis : En raison du passage de validation et de correction, le mode ameliore entraine une latence plus elevee et un cout de modele supplementaire (jusqu'a deux appels de modele par extraction de facture).
Exemple d'objet accuracy
Lorsque accuracy_mode est demande (ou renvoye dans une reponse reservee aux plans superieurs), la reponse d'extraction contient un objet de metadaten accuracy avec des statistiques detaillees :
{
"invoice_id": "2f7d7f8a-32fb-4a7c-a3b1-53b61b64252f",
"invoice": {
"document_type": "invoice",
"vendor": {
"name": "Supplier Inc.",
"tax_id": "DE123456789",
"iban": "DE89370400440532013000"
},
"subtotal": 1500.0,
"tax_total": 285.0,
"total_amount": 1785.0,
"confidence": 0.97
},
"accuracy": {
"mode": "enhanced",
"correction_attempted": true,
"correction_used": true,
"validators_failed": [
"subtotal_tax_match"
],
"unresolved_warnings": [],
"findings": [],
"latency_ms": 1250,
"model_calls": 2,
"tokens_input": 1850,
"tokens_output": 450
}
}
Reference des champs de l'objet accuracy
| Champ | Type | Description |
|---|---|---|
mode | string | Soit standard soit enhanced |
correction_attempted | boolean | true si une regle de validation a echoue et qu'une correction a ete tentee |
correction_used | boolean | true si la correction a reussi et a ete appliquee au resultat final |
validators_failed | array of strings | Liste des identifiants des regles de validation ayant echoue lors du premier passage |
unresolved_warnings | array of objects | Avertissements non resolus |
findings | array of objects | Resultats de validation du moteur |
latency_ms | integer | Duree totale de l'extraction en millisecondes |
model_calls | integer | Nombre d'appels au LLM (1 pour standard, jusqu'a 2 pour enhanced) |
tokens_input | integer | Nombre de tokens d'entree consommes |
tokens_output | integer | Nombre de tokens de sortie consommes |
Limites des documents
Chaque upload est borne avant l'extraction. Un document au-dela d'une limite est rejete avec le code correspondant, et non traite partiellement.
| Limite | Valeur | Code en cas de depassement |
|---|---|---|
| Taille de l'upload, endpoints d'extraction | 25 MB | upload_too_large |
Taille de l'upload, /v1/documents/split | 25 MB | upload_too_large |
Taille de l'upload, /v1/documents/classify et /v1/documents/crop | 10 MB | upload_too_large |
| Taille de l'upload, artefact de workflow AP | 25 MB | artifact_too_large |
| Taille de l'upload, demonstration publique | 5 MB | upload_too_large |
| Pages PDF, extraction standard | 30 | pdf_too_many_pages |
| Pages PDF, endpoints AP | quota AP de votre offre (Pro 10, Business 100) | pdf_too_many_pages |
Taille de l'image decodee (/v1/documents/crop) | 100 megapixels | image_too_large_to_process |
| Piece jointe e-facture integree | 10 MB | einvoice_attachment_too_large |
| Duree d'extraction du texte PDF | 20 secondes | pdf_extraction_timeout |
100 pages constituent un plafond serveur absolu, pas un droit lie a l'offre. La limite de pages applicable a une requete est la plus basse entre ce plafond et le quota de votre offre pour l'endpoint appele. Aucun endpoint et aucune offre future ne peut envoyer plus de 100 pages.
Le texte extrait est plafonne a 400 000 caracteres. Ce plafond tronque au lieu d'echouer: un document plus long est extrait jusqu'a cette limite puis traite normalement.
PDF scannes et uniquement composes d'images
Un PDF issu d'un scan ne contient aucune couche de texte : la lecture du PDF ne renvoie donc rien. Parsurai le detecte et relit le meme fichier par OCR avant l'extraction, de sorte qu'un scan encapsule dans un PDF se comporte comme le meme scan importe en JPEG ou PNG.
Le repli OCR est borne independamment des limites de pages ci-dessus : il s'applique aux documents de 10 pages au maximum. Un scan plus long est rejete avec 422 pdf_no_extractable_text plutot qu'envoye a la reconnaissance. Si l'OCR ne parvient pas non plus a lire le fichier, ou s'il est momentanement indisponible, la requete echoue avec 422 pdf_no_extractable_text ou 503 ocr_unavailable -- la requete n'atteint jamais le modele avec un document vide.
Reponses d'erreur courantes
| Statut | Code | Cause typique |
|---|---|---|
401 | invalid_api_key | X-API-Key manquant, inactif ou inconnu |
402 | feature_not_in_plan | Locale explicite sur Free ou fonction d'extraction Pro-only sous Pro |
413 | upload_too_large | Fichier au-dela de la limite d'upload de ce point de terminaison |
413 | artifact_too_large | Artefact de workflow AP au-dela de la limite de 25 MB |
422 | upload_not_authorized | Envoi depuis le tableau de bord refuse avant transmission : type ou taille declare hors des limites du point de terminaison |
422 | validation_error | Texte vide, UUID mal forme ou structure de requete invalide |
422 | unsupported_einvoice_profile | XML bien forme dont le profil UBL/CII n'est pas encore pris en charge |
422 | pdf_too_many_pages | PDF au-dela de la limite de pages applicable a l'endpoint |
422 | pdf_unreadable | PDF corrompu, chiffre ou protege par mot de passe |
422 | pdf_no_extractable_text | PDF scanne sans couche de texte, illisible aussi par l'OCR |
422 | image_too_large_to_process | Image au-dela de la limite de decodage de 100 megapixels sur /v1/documents/crop |
422 | einvoice_attachment_too_large | Piece jointe e-facture integree superieure a 10 MB |
428 | legal_reacceptance_required | Conditions generales ou politique de confidentialite mises a jour pas encore acceptees sur le compte |
428 | email_verification_required | Adresse e-mail du titulaire du compte pas encore verifiee |
429 | rate_limit_exceeded | Limite de requetes par minute depassee |
429 | quota_exceeded | Quota mensuel d'extraction epuise |
503 | extraction_capacity_exhausted | Tous les emplacements d'extraction PDF sont occupes |
503 | ocr_unavailable | La reconnaissance de texte, requise pour un PDF scanne, est momentanement indisponible |
504 | pdf_extraction_timeout | L'extraction du texte a depasse le budget de 20 secondes |
428 est la seule erreur qu'un retry ne resout pas. Elle signifie que le titulaire du compte n'a pas encore accepte des conditions generales ou une politique de confidentialite mises a jour. Tout endpoint authentifie la renvoie tant que ce n'est pas fait, depuis le tableau de bord — une cle API ne peut pas accepter a sa place. Dans une integration non supervisee, cela releve de l'alerte, pas de la boucle de retry.
503 extraction_capacity_exhausted, 503 ocr_unavailable et 504 pdf_extraction_timeout decrivent le service, pas votre document. Reessayez les deux avec un backoff exponentiel, comme pour 429 rate_limit_exceeded. Tous les autres codes du tableau echoueront a nouveau sur la meme entree -- corrigez le document au lieu de reessayer.
Stockez l'objet invoice brut tel qu'il est renvoye si vous voulez de la compatibilite future. Les champs optionnels peuvent etre null, mais document_type, vendor, buyer, total_amount et confidence appartiennent au schema d'extraction.
Extraction de documents AP (Pro et Business)
La famille d'endpoints /v1/documents extrait des documents Accounts Payable au-dela des factures standard. Elle couvre les e-factures DACH ainsi que les documents d'achat, livraison, paiement et releves bancaires.
Apercu des endpoints
| Endpoint | Entree | Offre |
|---|---|---|
POST /v1/documents/extract | Body JSON avec text | Pro et Business |
POST /v1/documents/extract/file | Fichier multipart (PDF, image, XML) | Pro et Business |
POST /v1/documents/extract/url | Body JSON avec url | Pro et Business |
Types de documents et formats source
Les reponses AP utilisent une enveloppe document distincte avec document_type et source_format. document_type decrit le document metier, par exemple purchase_order, delivery_note, remittance_advice, payment_advice ou bank_statement. source_format decrit le format d'entree, par exemple pdf, image, xrechnung, zugferd, factur_x ou peppol_bis_billing.
XRechnung, ZUGFeRD/Factur-X et Peppol BIS Billing 3.0 sont parses de facon deterministe lorsque le profil est supporte. Les profils XML non supportes renvoient 422 unsupported_einvoice_profile.
{
"document_id": "3a1b2c4d-...",
"document_type": "invoice",
"source_format": "xrechnung",
"schema_version": "1.0",
"document": {},
"classification": {
"document_type": "invoice",
"confidence": 0.98,
"signals": ["xml_profile_xrechnung"]
},
"warnings": []
}