# `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

```bash
curl -X POST "https://api.example/v1/extract" \
  -H "Authorization: Bearer $FACTURX_API_KEY" \
  --data-binary @facture.pdf
```

Réponse :

```json
{
  "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
<?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

```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)

```javascript
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

```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 :

```bash
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 |

```json
{
  "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`.
