Doc Extract API¶
Port: 8000 | NodePort: 30002 | Repo: solyntek/djinn/services/djinn-doc-extract
Extraction of structured data from invoices, receipts, resumes and ID documents via OCR + LLM.
Endpoints¶
| Method | Route | Description |
|---|---|---|
GET |
/health |
Health check |
GET |
/v1/schemas |
Schemas of supported document types |
POST |
/v1/extract |
Extraction from a single file |
POST |
/v1/extract/batch |
Batch extraction from multiple files |
Document types¶
| Type | Extracted data |
|---|---|
invoice |
vendor, number, date, line items, totals, VAT, IBAN |
receipt |
vendor, date, line items, totals, payment method |
resume |
name, email, skills, work experience, degrees, certifications |
id_card |
name, date of birth, nationality, document number |
Example¶
{
"document_type": "resume",
"data": {
"firstname": "Jean",
"lastname": "Dupont",
"skills": ["Python", "Go", "Docker"],
"experiences": [{"company": "Acme", "title": "Senior Dev"}]
},
"confidence": 0.87
}
Interactive reference¶
Generated on every build from the versioned spec openapi/doc-extract-v1.json (ADR-011) — no route is documented by hand.
Djinn Document Extract 0.2.0¶
Extraction de données structurées depuis factures, reçus, CVs et IDs
Endpoints¶
GET /health¶
Health
Description
Health check endpoint.
Responses
GET /v1/schemas¶
Schemas
Description
List all supported document schemas with their fields.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
X-API-Key |
header | No | |||
X-Internal-Service |
header | No | |||
X-Tenant-ID |
header | No |
Responses
POST /v1/extract¶
Extract
Description
Extract structured data from a single uploaded file.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
document_type |
query | No | |||
X-API-Key |
header | No | |||
X-Internal-Service |
header | No | |||
X-Tenant-ID |
header | No |
Request body
Responses
{
"document_type": "invoice",
"data": null,
"text_source": null,
"raw_text": "string",
"confidence": 10.12,
"field_confidences": [
{
"field": "string",
"score": 10.12,
"reason": null
}
],
"pii_detected": null,
"error": null
}
Schema of the response body
{
"properties": {
"document_type": {
"$ref": "#/components/schemas/DocumentType"
},
"data": {
"anyOf": [
{
"$ref": "#/components/schemas/InvoiceData"
},
{
"$ref": "#/components/schemas/ReceiptData"
},
{
"$ref": "#/components/schemas/ResumeData"
},
{
"$ref": "#/components/schemas/IDCardData"
},
{
"type": "null"
}
],
"title": "Data"
},
"text_source": {
"anyOf": [
{
"$ref": "#/components/schemas/TextSource"
},
{
"type": "null"
}
]
},
"raw_text": {
"type": "string",
"title": "Raw Text"
},
"confidence": {
"type": "number",
"maximum": 1.0,
"minimum": 0.0,
"title": "Confidence"
},
"field_confidences": {
"items": {
"$ref": "#/components/schemas/FieldConfidence"
},
"type": "array",
"title": "Field Confidences"
},
"pii_detected": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Pii Detected"
},
"error": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Error"
}
},
"type": "object",
"required": [
"document_type",
"raw_text",
"confidence"
],
"title": "ExtractionResult"
}
POST /v1/extract/batch¶
Extract Batch
Description
Extract structured data from multiple uploaded files.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
document_type |
query | No | |||
X-API-Key |
header | No | |||
X-Internal-Service |
header | No | |||
X-Tenant-ID |
header | No |
Request body
Responses
[
{
"document_type": "invoice",
"data": null,
"text_source": null,
"raw_text": "string",
"confidence": 10.12,
"field_confidences": [
{
"field": "string",
"score": 10.12,
"reason": null
}
],
"pii_detected": null,
"error": null
}
]
GET /v1/receipt-policies¶
Get Receipt Policy V1
Description
Politique de dépenses du tenant authentifié, ou la politique par défaut.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
X-API-Key |
header | No | |||
X-Internal-Service |
header | No | |||
X-Tenant-ID |
header | No |
Responses
{
"currency": "string",
"default_max_amount": 10.12,
"caps": [
{
"category": "string",
"max_amount": 10.12
}
],
"require_vat_above": null,
"is_default": true
}
Schema of the response body
{
"properties": {
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3,
"title": "Currency",
"default": "EUR"
},
"default_max_amount": {
"type": "number",
"minimum": 0.0,
"title": "Default Max Amount",
"default": 1000.0
},
"caps": {
"items": {
"$ref": "#/components/schemas/ExpenseCap"
},
"type": "array",
"title": "Caps"
},
"require_vat_above": {
"anyOf": [
{
"type": "number",
"minimum": 0.0
},
{
"type": "null"
}
],
"title": "Require Vat Above"
},
"is_default": {
"type": "boolean",
"title": "Is Default",
"default": false
}
},
"type": "object",
"title": "ExpensePolicyOut",
"description": "Politique renvoyée par l'API, avec l'indication qu'aucune n'a été enregistrée."
}
PUT /v1/receipt-policies¶
Put Receipt Policy V1
Description
Remplace la politique du tenant authentifié.
Le tenant vient de l'authentification (ADR-001) ; un tenant_id présent
dans le corps est ignoré, jamais honoré.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
X-API-Key |
header | No | |||
X-Internal-Service |
header | No | |||
X-Tenant-ID |
header | No |
Request body
{
"currency": "string",
"default_max_amount": 10.12,
"caps": [
{
"category": "string",
"max_amount": 10.12
}
],
"require_vat_above": null
}
Schema of the request body
{
"properties": {
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3,
"title": "Currency",
"default": "EUR"
},
"default_max_amount": {
"type": "number",
"minimum": 0.0,
"title": "Default Max Amount",
"default": 1000.0
},
"caps": {
"items": {
"$ref": "#/components/schemas/ExpenseCap"
},
"type": "array",
"title": "Caps"
},
"require_vat_above": {
"anyOf": [
{
"type": "number",
"minimum": 0.0
},
{
"type": "null"
}
],
"title": "Require Vat Above"
}
},
"type": "object",
"title": "ExpensePolicy",
"description": "Politique de dépenses d'un tenant.\n\nLe verdict produit à partir de cette politique est une **évaluation**,\njamais une autorisation : doc-extract ne refuse aucun remboursement, il\nrapporte qu'un montant dépasse un plafond déclaré."
}
Responses
{
"currency": "string",
"default_max_amount": 10.12,
"caps": [
{
"category": "string",
"max_amount": 10.12
}
],
"require_vat_above": null,
"is_default": true
}
Schema of the response body
{
"properties": {
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3,
"title": "Currency",
"default": "EUR"
},
"default_max_amount": {
"type": "number",
"minimum": 0.0,
"title": "Default Max Amount",
"default": 1000.0
},
"caps": {
"items": {
"$ref": "#/components/schemas/ExpenseCap"
},
"type": "array",
"title": "Caps"
},
"require_vat_above": {
"anyOf": [
{
"type": "number",
"minimum": 0.0
},
{
"type": "null"
}
],
"title": "Require Vat Above"
},
"is_default": {
"type": "boolean",
"title": "Is Default",
"default": false
}
},
"type": "object",
"title": "ExpensePolicyOut",
"description": "Politique renvoyée par l'API, avec l'indication qu'aucune n'a été enregistrée."
}
POST /v1/extract/receipts/analyze¶
Analyze Receipts
Description
Analyse un lot de reçus : doublons, écarts de politique, cohérence, authenticité.
Pour chaque reçu : extraction (document_type="receipt"), empreinte
perceptuelle, contrôle de cohérence interne, confrontation à la
politique de dépenses du tenant, et signaux d'authenticité via
AuthenticityProvider (implémentation locale aujourd'hui ; doc-trust
dès sa v1 en T2, sans changement de contrat). Puis, sur l'ensemble du
lot, rapprochement des doublons.
findings et authenticity sont des évaluations, jamais des
autorisations : cette route ne bloque rien, ne rejette aucun reçu pour
cause de constat, et ne modifie aucune politique. Un fichier illisible,
trop volumineux, ou dont l'extraction échoue, produit un item avec
error renseigné et n'interrompt jamais le lot — même contrat que
/v1/extract/batch. Seul un problème de requête (lot vide, lot
au-delà de MAX_BATCH_RECEIPTS) fait échouer l'appel entier.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
X-API-Key |
header | No | |||
X-Internal-Service |
header | No | |||
X-Tenant-ID |
header | No |
Request body
Schema of the request body
{
"properties": {
"files": {
"items": {
"type": "string",
"contentMediaType": "application/octet-stream"
},
"type": "array",
"title": "Files"
},
"categories": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Categories"
}
},
"type": "object",
"required": [
"files"
],
"title": "Body_analyze_receipts_v1_extract_receipts_analyze_post"
}
Responses
{
"items": [
{
"index": 0,
"filename": "string",
"data": null,
"confidence": null,
"findings": [
{
"code": "string",
"message": "string",
"severity": "info"
}
],
"authenticity": null,
"error": null
}
],
"duplicate_groups": [
{
"indices": [
0
],
"rule": "fingerprint"
}
],
"analysed_at": "2022-04-13T15:42:05.901Z",
"policy_is_default": true
}
Schema of the response body
{
"properties": {
"items": {
"items": {
"$ref": "#/components/schemas/ReceiptAnalysisItem"
},
"type": "array",
"title": "Items"
},
"duplicate_groups": {
"items": {
"$ref": "#/components/schemas/DuplicateGroupOut"
},
"type": "array",
"title": "Duplicate Groups"
},
"analysed_at": {
"type": "string",
"format": "date-time",
"title": "Analysed At"
},
"policy_is_default": {
"type": "boolean",
"title": "Policy Is Default"
}
},
"type": "object",
"required": [
"items",
"analysed_at",
"policy_is_default"
],
"title": "ReceiptAnalysisResponse",
"description": "Réponse de l'analyse du lot.\n\nNe bloque rien, ne rejette aucun reçu pour cause de constat, et ne\nmodifie aucune politique de dépenses."
}
Schemas¶
AuthenticityOut¶
| Name | Type | Description |
|---|---|---|
explanation |
string | |
score |
number | |
signals |
Array<FindingOut> |
Body_analyze_receipts_v1_extract_receipts_analyze_post¶
| Name | Type | Description |
|---|---|---|
categories |
||
files |
Array<string> |
Body_extract_batch_v1_extract_batch_post¶
| Name | Type | Description |
|---|---|---|
files |
Array<string> |
Body_extract_v1_extract_post¶
| Name | Type | Description |
|---|---|---|
file |
string |
Certification¶
| Name | Type | Description |
|---|---|---|
name |
||
provider |
||
year |
Diploma¶
| Name | Type | Description |
|---|---|---|
degree |
||
end_date |
||
field_of_study |
||
school |
||
start_date |
DocumentType¶
Type: string
DuplicateGroupOut¶
| Name | Type | Description |
|---|---|---|
indices |
Array<integer> | |
rule |
string |
ExpenseCap¶
| Name | Type | Description |
|---|---|---|
category |
string | |
max_amount |
number |
ExpensePolicy¶
| Name | Type | Description |
|---|---|---|
caps |
Array<ExpenseCap> | |
currency |
string | |
default_max_amount |
number | |
require_vat_above |
ExpensePolicyOut¶
| Name | Type | Description |
|---|---|---|
caps |
Array<ExpenseCap> | |
currency |
string | |
default_max_amount |
number | |
is_default |
boolean | |
require_vat_above |
Experience¶
| Name | Type | Description |
|---|---|---|
company |
||
description |
||
end_date |
YYYY-MM, YYYY, or 'Present' | |
location |
||
start_date |
YYYY-MM or YYYY | |
title |
ExtractionResult¶
| Name | Type | Description |
|---|---|---|
confidence |
number | |
data |
||
document_type |
DocumentType | |
error |
||
field_confidences |
Array<FieldConfidence> | |
pii_detected |
||
raw_text |
string | |
text_source |
FieldConfidence¶
| Name | Type | Description |
|---|---|---|
field |
string | |
reason |
||
score |
number |
FindingOut¶
| Name | Type | Description |
|---|---|---|
code |
string | |
message |
string | |
severity |
string |
HealthResponse¶
| Name | Type | Description |
|---|---|---|
status |
string | |
version |
string |
HTTPValidationError¶
| Name | Type | Description |
|---|---|---|
detail |
Array<ValidationError> |
IDCardData¶
| Name | Type | Description |
|---|---|---|
birth_date |
||
birth_place |
||
document_number |
||
expiry_date |
||
first_name |
||
gender |
M or F | |
issue_date |
||
last_name |
||
nationality |
InvoiceData¶
| Name | Type | Description |
|---|---|---|
currency |
ISO 4217 code (EUR, USD, ...) | |
due_date |
||
invoice_date |
||
invoice_number |
||
line_items |
Array<LineItem> | |
payment_method |
||
payment_reference |
IBAN or payment reference | |
subtotal |
||
total_amount |
||
vat_amount |
||
vendor_address |
||
vendor_name |
||
vendor_tax_id |
SIRET / tax ID |
LineItem¶
| Name | Type | Description |
|---|---|---|
amount |
||
description |
||
quantity |
||
unit_price |
||
vat_rate |
ReceiptAnalysisItem¶
| Name | Type | Description |
|---|---|---|
authenticity |
Signaux d'authenticité faibles et contournables — une aide au tri humain, jamais une preuve ni un verdict. `null` signifie que l'authenticité n'a pas pu être évaluée (fichier rejeté avant analyse, ou échec du fournisseur de signaux), jamais qu'aucun signal n'a été trouvé : l'absence de signal se lit sur un objet présent dont `signals` est vide. | |
confidence |
||
data |
||
error |
||
filename |
string | |
findings |
Array<FindingOut> | Écarts de cohérence interne et de politique de dépenses. Une évaluation, jamais une autorisation : aucun reçu n'est rejeté. |
index |
integer |
ReceiptAnalysisResponse¶
| Name | Type | Description |
|---|---|---|
analysed_at |
string(date-time) | |
duplicate_groups |
Array<DuplicateGroupOut> | |
items |
Array<ReceiptAnalysisItem> | |
policy_is_default |
boolean |
ReceiptData¶
| Name | Type | Description |
|---|---|---|
currency |
||
line_items |
Array<LineItem> | |
payment_method |
||
receipt_date |
||
receipt_time |
Heure du ticket, si imprimée | |
subtotal |
||
total_amount |
||
vat_amount |
||
vat_breakdown |
Array<VatBreakdownEntry> | Ventilation par taux ; vat_amount reste le total |
vendor_address |
||
vendor_name |
ResumeData¶
| Name | Type | Description |
|---|---|---|
certifications |
Array<Certification> | |
diplomas |
Array<Diploma> | |
email |
||
experiences |
Array<Experience> | |
firstname |
||
languages |
Array<string> | |
lastname |
||
linkedin |
||
location |
||
phone |
||
skills |
Array<string> |
SchemaField¶
| Name | Type | Description |
|---|---|---|
description |
||
name |
string | |
type |
string |
SchemaInfo¶
| Name | Type | Description |
|---|---|---|
document_type |
string | |
fields |
Array<SchemaField> |
TextSource¶
Type: string
ValidationError¶
| Name | Type | Description |
|---|---|---|
ctx |
||
input |
||
loc |
Array<> | |
msg |
string | |
type |
string |
VatBreakdownEntry¶
| Name | Type | Description |
|---|---|---|
amount |
Montant de TVA pour ce taux | |
rate |
Taux en pourcentage, ex. 20.0 ou 5.5 | |
taxable_base |
Base imposable pour ce taux |