Docs
2D-DOC / VDS

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"
}
FieldTypeRequiredDescription
datastringYesThe raw 2D-DOC barcode value
encodingstringNobase64, 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

FieldTypeDescription
statusstringvalid or failed. Driven by signature validity only
verificationobjectVerification checks grouped by category
documentobjectParsed document data
certificateobjectSigning certificate info, when resolved (optional)
errorstringPresent only when parsing failed critically (optional)

Verification checks

verification maps a category name to an array of { status, check } entries. status is one of:

StatusMeaning
✅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:

FieldTypeDescription
formatVersionstringv1
versionstring2D-DOC version (01 to 04)
caIdstringCertification authority ID (e.g. FR04)
certificateIdstringSigning certificate ID
documentTypeCodestringTwo-character document type (see Document Types)
documentEmissionDatestring | nullDocument emission date
signatureDatestringSignature date
signatureDateFormattedstringSignature date formatted as DD/MM/YYYY
perimeterstringData perimeter code (optional, version 03+)
issuingCountrystringIssuing 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:

FieldTypeDescription
idstringData identifier from the spec
valuestringFormatted, human-readable value
rawValuestringRaw value before formatting (optional)
truncatedbooleanWhether the value was truncated in the barcode
labelstringHuman-readable field label
categorystringField 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:

  1. Parse the barcode structure (header, message, signature zones), auto-detecting V1 vs V2
  2. Identify the document type and extract fields according to the spec
  3. Retrieve the signing certificate from the ANTS trust list
  4. Verify the ECDSA signature over the signed zones
  5. 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"
}