Verify Barcode
Parse and verify a 2D-DOC barcode signature
Verify a 2D-DOC barcode value by parsing its structure, validating the cryptographic signature against the ANTS trust chain, and extracting the structured data fields.
Both formats are supported and auto-detected: 2D-DOC V1 (AFNOR XP Z42-105, DataMatrix) and 2D-DOC V2 / VDS (ISO 22376:2023).
Request
POST /2ddoc/verify
Authorization: Bearer oat_your_publishable_key
Content-Type: application/json{
"data": "DC04FR000001...",
"encoding": "ascii"
}| Field | Type | Required | Description |
|---|---|---|---|
data | string | Yes | The raw 2D-DOC barcode value |
encoding | string | No | base64, hex, or ascii. Auto-detected when omitted |
A missing data field returns HTTP 400 with { "error": "data is required" }.
Response
{
"status": "valid",
"verification": {
"SIGNATURE": [
{ "status": "✅", "check": "Signature is cryptographically valid" }
],
"CERTIFICATE": [
{ "status": "✅", "check": "Certificate found: Certigna" },
{ "status": "✅", "check": "Service: 2D-Doc" }
],
"DOCUMENT": [
{ "status": "✅", "check": "Document type: Facture" },
{ "status": "✅", "check": "Version: 04" },
{ "status": "✅", "check": "Signature date: 15/01/2026" }
],
"VALIDATION": [
{ "status": "✅", "check": "Document structure and field values are valid" }
]
},
"document": {
"header": {
"formatVersion": "v1",
"version": "04",
"caId": "FR04",
"certificateId": "0001",
"documentTypeCode": "01",
"documentEmissionDate": "2026-01-15T00:00:00.000Z",
"signatureDate": "2026-01-15T00:00:00.000Z",
"signatureDateFormatted": "15/01/2026",
"perimeter": "01",
"issuingCountry": "FR"
},
"documentType": "Facture",
"fields": {
"invoice": [
{
"id": "10",
"value": "MME/SPECIMEN/NATACHA",
"rawValue": "MME/SPECIMEN/NATACHA",
"truncated": false,
"label": "Nom du bénéficiaire",
"category": "invoice"
},
{
"id": "22",
"value": "145 AVENUE DES SPECIMENS",
"rawValue": "145 AVENUE DES SPECIMENS",
"truncated": false,
"label": "Ligne 4 adresse point de service",
"category": "invoice"
},
{
"id": "24",
"value": "75009",
"rawValue": "75009",
"truncated": false,
"label": "Code postal point de service",
"category": "invoice"
},
{
"id": "25",
"value": "PARIS",
"rawValue": "PARIS",
"truncated": false,
"label": "Localité point de service",
"category": "invoice"
}
]
},
"data": {
"beneficiary_name": "MME/SPECIMEN/NATACHA",
"ligne4_adresse_point_service": "145 AVENUE DES SPECIMENS",
"code_postal_point_service": "75009",
"localite_point_service": "PARIS"
}
},
"certificate": {
"providerName": "DHIMYOTIS",
"providerTradeName": "Certigna",
"subject": "2D-Doc",
"organization": "DHIMYOTIS",
"trusted": true
}
}Top-level fields
| Field | Type | Description |
|---|---|---|
status | string | valid or failed. Driven by signature validity only |
verification | object | Verification checks grouped by category |
document | object | Parsed document data |
certificate | object | Signing certificate info, when resolved (optional) |
error | string | Present only when parsing failed critically (optional) |
Verification checks
verification maps a category name to an array of { status, check } entries. status is one of:
| Status | Meaning |
|---|---|
✅ | Check passed |
⚠️ | Warning (does not affect status) |
🛑 | Check failed |
Common categories are SIGNATURE, CERTIFICATE, DOCUMENT, and VALIDATION. Additional WARNINGS and ERRORS categories appear when the parser reports them, and PARSING appears when the barcode could not be parsed at all.
Document validation findings (structure and field-value issues under VALIDATION) are reported as warnings only. They never change status: only the cryptographic signature validity determines whether status is valid or failed.
Document header
For V1 barcodes, document.header contains:
| Field | Type | Description |
|---|---|---|
formatVersion | string | v1 |
version | string | 2D-DOC version (01 to 04) |
caId | string | Certification authority ID (e.g. FR04) |
certificateId | string | Signing certificate ID |
documentTypeCode | string | Two-character document type (see Document Types) |
documentEmissionDate | string | null | Document emission date |
signatureDate | string | Signature date |
signatureDateFormatted | string | Signature date formatted as DD/MM/YYYY |
perimeter | string | Data perimeter code (optional, version 03+) |
issuingCountry | string | Issuing country code (optional, version 04) |
For V2 / VDS barcodes (ISO 22376), the header has formatVersion: "v2" with codeIAC, acId, certCN, manifestId, manifestName, signatureTimestamp, signatureDateFormatted, signatureAlgorithm, and an optional prefix object.
Fields
document.fields groups the extracted fields by category (for example invoice, identity, address; V2 payload fields are grouped under payload). Each field entry contains:
| Field | Type | Description |
|---|---|---|
id | string | Data identifier from the spec |
value | string | Formatted, human-readable value |
rawValue | string | Raw value before formatting (optional) |
truncated | boolean | Whether the value was truncated in the barcode |
label | string | Human-readable field label |
category | string | Field category |
document.data is a flat key-value map of the same values, keyed by snake_case field names, convenient for programmatic access.
Verification steps
The API performs these checks:
- Parse the barcode structure (header, message, signature zones), auto-detecting V1 vs V2
- Identify the document type and extract fields according to the spec
- Retrieve the signing certificate from the ANTS trust list
- Verify the ECDSA signature over the signed zones
- Validate the document structure and field values (reported as warnings)
Error handling
If the barcode is parsed but the signature is invalid, the API returns HTTP 200 with status: "failed" and a failing SIGNATURE check.
If the barcode cannot be parsed at all, the API returns HTTP 422:
{
"status": "failed",
"verification": {
"PARSING": [
{ "status": "🛑", "check": "Failed to parse 2D-DOC: Invalid header" }
]
},
"document": {
"header": {
"formatVersion": "v1",
"version": "",
"caId": "",
"certificateId": "",
"documentTypeCode": "",
"documentEmissionDate": null,
"signatureDate": "2026-01-15T10:30:00.000Z"
},
"documentType": "Unknown",
"fields": {},
"data": {}
},
"error": "Invalid header"
}