Dernière mise à jour : 15 octobre 2026
Doc Trust API¶
Port local (Docker Compose) : 30008 | Repo : solyntek/djinn/services/djinn-doc-trust
Avis d'authenticité sur un justificatif (RIB, reçu, attestation) : la réponse est cohérent, à vérifier ou incohérent, avec les signaux qui la fondent et une explication.
Une évaluation, jamais une autorisation
L'avis est une indication qui appelle une vérification humaine. Il n'autorise ni ne refuse rien par lui-même : « à vérifier » et « incohérent » veulent dire « à contrôler », pas « faux ». Les fichiers sont analysés en mémoire et jamais conservés.
Endpoints¶
| Méthode | Route | Description |
|---|---|---|
GET |
/health |
Health check (version des règles, séquence de l'instantané de la liste de confiance) |
POST |
/v1/authenticity/analyze |
Analyser un document |
Analyser un document¶
POST /v1/authenticity/analyze, multipart/form-data, X-API-Key requise.
| Champ | Type | Règle |
|---|---|---|
file |
fichier | PDF, PNG, JPEG, TIFF ou WEBP, jusqu'à 50 Mio ; le type réel est lu dans la signature du fichier, pas dans l'extension |
document_type |
rib, receipt, attestation, resume, id_card, other |
Obligatoire ; choisit le profil de règles |
fields |
chaîne JSON (objet) | Facultatif, jusqu'à 16 Kio : champs déjà extraits du document (par exemple par Doc Extract), pour recouper le contenu. Les valeurs ne sont jamais journalisées |
curl -X POST https://api.dev.djinn.solyntek.io/v1/authenticity/analyze \
-H "X-API-Key: your-api-key" \
-F "file=@rib.pdf" \
-F "document_type=rib"
{
"verdict": "suspicious",
"score": 0.35,
"signals": [
{
"code": "pdf_online_editor",
"family": "metadata",
"strength": "strong",
"message": "Le document a été produit par un éditeur en ligne (Canva).",
"detail": {"producer": "Canva"}
}
],
"explanation": "…",
"rules_version": "2026.10.1",
"document_sha256": "…",
"document_type": "rib",
"analysed_at": "2026-10-05T09:12:44Z"
}
Verdict¶
| Verdict | Signification |
|---|---|
consistent |
Aucun signal n'appelle un contrôle |
suspicious |
Au moins un signal fort, ou au moins deux signaux faibles : à vérifier |
inconsistent |
Au moins deux signaux forts de familles différentes : à vérifier en priorité |
score va de 0 à 1. C'est un indicateur de tri (plus il est haut, plus il y a à vérifier), pas une probabilité. Un signal a une famille (metadata, structure, fonts, image, content, 2ddoc) et une force (strong, weak, info) ; deux signaux de familles différentes sont indépendants. Les messages des signaux sont en français et ne contiennent jamais de donnée métier (IBAN, montant, nom).
Erreurs¶
Les erreurs métier ont la forme {"detail": {"code": "...", "message": "..."}}.
| Statut | Cause |
|---|---|
401 |
Clé API absente ou invalide |
413 |
Fichier de plus de 50 Mio (file_too_large) |
422 |
empty_file, unsupported_type, unreadable_file (chiffré, corrompu ou tronqué), invalid_fields, ou document_type invalide (validation de la requête) |
500 |
L'événement d'audit n'a pas pu être écrit : pas de trace, pas d'action |
Un service qui appelle Doc Trust doit traiter toute réponse autre que 200 comme « non évalué », jamais comme « aucun signal ».
Référence interactive¶
Générée à chaque build depuis la spec versionnée openapi/doc-trust-v1.json (ADR-011) — aucune route documentée à la main.
Djinn Doc Trust 0.1.0¶
Avis d'authenticité documentaire par règles (évaluation, jamais autorisation)
Endpoints¶
GET /health¶
Health
Description
Health check, sans authentification.
Responses
{
"status": "string",
"service": "string",
"version": "string",
"rules_version": "string",
"tsl_sequence": 0,
"tsl_issued": "string"
}
Schema of the response body
{
"properties": {
"status": {
"type": "string",
"title": "Status"
},
"service": {
"type": "string",
"title": "Service"
},
"version": {
"type": "string",
"title": "Version"
},
"rules_version": {
"type": "string",
"title": "Rules Version"
},
"tsl_sequence": {
"type": "integer",
"title": "Tsl Sequence"
},
"tsl_issued": {
"type": "string",
"title": "Tsl Issued",
"description": "Date d'émission de la TSL embarquée (AAAA-MM-JJ)."
}
},
"type": "object",
"required": [
"status",
"service",
"version",
"rules_version",
"tsl_sequence",
"tsl_issued"
],
"title": "HealthResponse",
"description": "Response for the health check endpoint."
}
POST /v1/authenticity/analyze¶
Analyze
Description
Avis d'authenticité d'un justificatif (PDF ou image) : évaluation, jamais autorisation.
Le type réel du fichier est lu dans ses octets, pas dans son nom. fields est un objet JSON
facultatif (16 Kio max) des champs déjà extraits ; ses valeurs ne sont jamais journalisées.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
X-API-Key |
header | No |
Request body
Schema of the request body
{
"properties": {
"file": {
"type": "string",
"contentMediaType": "application/octet-stream",
"title": "File"
},
"document_type": {
"type": "string",
"enum": [
"rib",
"receipt",
"attestation",
"resume",
"id_card",
"other"
],
"title": "Document Type"
},
"fields": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Fields"
}
},
"type": "object",
"required": [
"file",
"document_type"
],
"title": "Body_analyze_v1_authenticity_analyze_post"
}
Responses
{
"verdict": "consistent",
"score": 10.12,
"signals": [
{
"code": "string",
"family": "metadata",
"strength": "info",
"message": "string",
"detail": {}
}
],
"explanation": "string",
"rules_version": "string",
"document_sha256": "string",
"document_type": "rib",
"analysed_at": "2022-04-13T15:42:05.901Z"
}
Schema of the response body
{
"properties": {
"verdict": {
"type": "string",
"enum": [
"consistent",
"suspicious",
"inconsistent"
],
"title": "Verdict",
"description": "`consistent` (aucun signal notable), `suspicious` (à vérifier), `inconsistent` (au moins deux signaux forts de familles différentes)."
},
"score": {
"type": "number",
"maximum": 1.0,
"minimum": 0.0,
"title": "Score",
"description": "Indicateur de tri, pas une probabilité : min(1, 0,35 x signaux forts + 0,1 x signaux faibles). Plus il est haut, plus il y a à vérifier."
},
"signals": {
"items": {
"$ref": "#/components/schemas/SignalOut"
},
"type": "array",
"title": "Signals"
},
"explanation": {
"type": "string",
"title": "Explanation"
},
"rules_version": {
"type": "string",
"title": "Rules Version"
},
"document_sha256": {
"type": "string",
"title": "Document Sha256"
},
"document_type": {
"type": "string",
"enum": [
"rib",
"receipt",
"attestation",
"resume",
"id_card",
"other"
],
"title": "Document Type"
},
"analysed_at": {
"type": "string",
"format": "date-time",
"title": "Analysed At"
}
},
"type": "object",
"required": [
"verdict",
"score",
"signals",
"explanation",
"rules_version",
"document_sha256",
"document_type",
"analysed_at"
],
"title": "AnalyzeResponse",
"description": "Avis d'authenticité : une évaluation, jamais une autorisation."
}
Schemas¶
AnalyzeResponse¶
| Name | Type | Description |
|---|---|---|
analysed_at |
string(date-time) | |
document_sha256 |
string | |
document_type |
string | |
explanation |
string | |
rules_version |
string | |
score |
number | Indicateur de tri, pas une probabilité : min(1, 0,35 x signaux forts + 0,1 x signaux faibles). Plus il est haut, plus il y a à vérifier. |
signals |
Array<SignalOut> | |
verdict |
string | `consistent` (aucun signal notable), `suspicious` (à vérifier), `inconsistent` (au moins deux signaux forts de familles différentes). |
Body_analyze_v1_authenticity_analyze_post¶
| Name | Type | Description |
|---|---|---|
document_type |
string | |
fields |
||
file |
string |
ErrorBody¶
| Name | Type | Description |
|---|---|---|
code |
string | `empty_file`, `file_too_large`, `unsupported_type`, `unreadable_file` ou `invalid_fields`. |
message |
string |
ErrorDetail¶
| Name | Type | Description |
|---|---|---|
detail |
ErrorBody |
HealthResponse¶
| Name | Type | Description |
|---|---|---|
rules_version |
string | |
service |
string | |
status |
string | |
tsl_issued |
string | Date d'émission de la TSL embarquée (AAAA-MM-JJ). |
tsl_sequence |
integer | |
version |
string |
SignalOut¶
| Name | Type | Description |
|---|---|---|
code |
string | |
detail |
Métadonnées techniques seulement (producteur, nombre de révisions...). Jamais une valeur métier (IBAN, montant, nom). | |
family |
string | |
message |
string | Message en français, sans donnée métier. |
strength |
string |