POST /v1/extract — exemples par langage
Périmètre : Factur-X (PDF/A-3 + CII embarqué) et CII XML autonome uniquement. L'extraction UBL n'est pas encore couverte — elle arrive avec Epic 6. Soumettre un fichier UBL à cet endpoint échoue avec un 422 (« CII invalide ou mal formé »), pas une extraction UBL déguisée.
Requête : le document (PDF Factur-X ou XML CII) brut en corps. Réponse :
JSON au même schéma que l'entrée de POST /v1/generate/facturx (aller-retour
symétrique, FR-6), enrichi de digitallySigned/signatureVerified.
Exemple complet — Factur-X (PDF)
curl
curl -X POST "https://api.example/v1/extract" \
-H "Authorization: Bearer $FACTURX_API_KEY" \
--data-binary @facture.pdf
Réponse :
{
"invoice": {
"invoiceNumber": "F-2026-001",
"issueDate": "2026-07-21",
"currencyCode": "EUR",
"invoiceTypeCode": "380",
"seller": { "name": "Vendeur SARL", "street": "", "city": "", "postalCode": "", "countryCode": "" },
"buyer": { "name": "Acheteur SAS", "street": "", "city": "", "postalCode": "", "countryCode": "" },
"lines": [{ "id": "1", "itemName": "Prestation", "quantity": 1, "unitPrice": 100, "vatRate": 20 }],
"vatBreakdown": [{ "category": "S", "taxableAmount": 100, "vatAmount": 20 }],
"totals": { "totalWithoutVat": 100, "totalVat": 20, "totalWithVat": 120, "amountDue": 120 }
},
"digitallySigned": false,
"signatureVerified": false
}
PHP
<?php
$ch = curl_init('https://api.example/v1/extract');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('FACTURX_API_KEY')],
CURLOPT_POSTFIELDS => file_get_contents('facture.pdf'),
CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);
echo $result['invoice']['invoiceNumber'] . "\n";
Python
import requests, os
with open("facture.pdf", "rb") as f:
resp = requests.post(
"https://api.example/v1/extract",
headers={"Authorization": f"Bearer {os.environ['FACTURX_API_KEY']}"},
data=f,
)
result = resp.json()
print(result["invoice"]["invoiceNumber"], "signé:", result["digitallySigned"])
JavaScript (Node.js)
import { readFile } from "node:fs/promises";
const pdf = await readFile("facture.pdf");
const resp = await fetch("https://api.example/v1/extract", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.FACTURX_API_KEY}` },
body: pdf,
});
const result = await resp.json();
console.log(result.invoice.invoiceNumber, "signé:", result.digitallySigned);
Go
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
f, _ := os.Open("facture.pdf")
defer f.Close()
req, _ := http.NewRequest(http.MethodPost, "https://api.example/v1/extract", f)
req.Header.Set("Authorization", "Bearer "+os.Getenv("FACTURX_API_KEY"))
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var result struct {
Invoice struct {
InvoiceNumber string `json:"invoiceNumber"`
} `json:"invoice"`
DigitallySigned bool `json:"digitallySigned"`
}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println(result.Invoice.InvoiceNumber, "signé:", result.DigitallySigned)
}
Exemple complet — CII XML autonome
Même endpoint, corps XML brut au lieu d'un PDF — utile si votre plateforme agréée vous livre déjà le CII sans l'emballage PDF/A-3 :
curl -X POST "https://api.example/v1/extract" \
-H "Authorization: Bearer $FACTURX_API_KEY" \
-H "Content-Type: application/xml" \
--data-binary @facture-cii.xml
La réponse suit exactement le même schéma que l'exemple PDF ci-dessus
(digitallySigned est toujours false pour un CII XML autonome — la
notion de signature électronique s'applique au PDF, pas au XML).
Erreurs
| Code | Cause | Exemple type (RFC 7807) |
|---|---|---|
| 422 | PDF chiffré ou corrompu | corrupted-pdf |
| 422 | PDF valide mais sans pièce jointe CII (pas un Factur-X) | no-cii-attachment |
| 422 | CII mal formé ou XML invalide | malformed-cii |
| 413 | Document > 20 Mo | — rejeté avant tout parsing |
{
"type": "no-cii-attachment",
"title": "Aucun CII embarqué trouvé",
"status": 422,
"detail": "ce PDF ne semble pas être un Factur-X (pièce jointe factur-x.xml absente)",
"instance": "01H..."
}
⚠️ Ces codes ne référencent PAS les règles BR-* officielles (schematron) :
contrairement à POST /v1/validate (qui exécute réellement le schematron
officiel FNFE-MPE depuis Story 3.7, schematronChecked: true),
l'extraction ne signale que des erreurs structurelles (PDF/XML illisible),
jamais une non-conformité BR-* — l'extraction décode, elle ne valide pas.
Pour vérifier la conformité BR-* d'un document avant de l'extraire,
utilisez POST /v1/validate.