DEVELOPERS

API documentation

This documentation shows how to send an image of a vehicle registration document and get structured fields back — with a confidence value per field, optionally with authenticity checks. Processed in Germany; on the paid plans images are not stored.

Create an API key Full documentation in the dashboard

Endpoint

Authenticate with an API key in the Authorization header. Create keys in the dashboard under “API keys”; every call counts against your monthly quota. The version lives in the path — /v1/ is the current one.

curl -X POST https://api.fahrzeugschein24.de/v1/extract \
  -H "Authorization: Bearer <your-api-key>" \
  -F "file=@registration.jpg" \
  -F "services=extraction"

Formats and limits

  • JPEG, PNG, TIFF, BMP, WebP, HEIC/HEIF and PDF (page 1)
  • Max. 20 MB per file
  • Instead of a form upload you can send the image as the raw request body
  • Rotated or tilted shots are corrected automatically
  • Per-plan burst limit: 10 (Free) to 150 (Enterprise) requests per minute, on top of the monthly quota
  • Requests including the authenticity check have their own, tighter per-minute limit

Versioning

The API is versioned: within a version the response shape and error codes no longer change. New, backwards-incompatible capabilities ship under a new version — your existing integration keeps running unchanged.

  • Current path: /v1/extract — the version is always in the path
  • The path without a version segment (/extract) stays pinned to v1 permanently
  • Every response names the handling version in the X-API-Version header
  • Ahead of a retirement, the Deprecation and Sunset headers announce the schedule

Per-request options

Optional form fields next to “file”. When omitted, your saved dashboard settings apply.

  • services — “extraction” (default) or “extraction,fraud_detection” to add the authenticity check.
  • include_field_images — true/false — include the per-field image cutout (cutout_image).
  • include_document_image — true/false — include the cropped document image (noticeably enlarges the response).

Response

“fields” is an object mapping each field name to value, confidence (0–1), bbox and optionally cutout_image. Which fields are included is configured in your settings. “vin_valid” is not a field but the result of the VIN check-digit comparison — true, false or null when there was nothing to compare. If your account is set up for output as a filled PDF, your filled PDF form comes back instead of this response; add the form field “output=json” to get this response instead for an individual request. Errors stay JSON.

{
  "fields": {
    "registrationNumber": { "value": "K AU 8823",         "confidence": 0.98, "bbox": [502, 327, 814, 388] },
    "vin":                { "value": "WAUZZZ8W9MA004711", "confidence": 0.97, "bbox": [939, 624, 1573, 690] },
    "d1":                 { "value": "AUDI",              "confidence": 0.99, "bbox": [939, 736, 1231, 795] },
    "ez":                 { "value": "07.11.2021",        "confidence": 0.96, "bbox": [502, 736, 736, 795] }
  },
  "vin_valid": true,
  "image_width": 3024,
  "image_height": 2136,
  "services": ["extraction"]
}

Authenticity check (optional)

When fraud detection is enabled, the JSON response also carries a fraud_detection object: an overall_risk grade (A–F), separate scores for image manipulation and AI generation, plus one entry per individual check under tests: metadata and thumbnail, for JPEG files ela, jpeg_ghost only for files that allow an assessment, together with the extraction also field_consistency and, for JPEG photos, glyph_duplicates. The ai_generated score rests solely on the file’s provenance data. Over the API the check is included from the Business plan onwards; on the smaller plans you can evaluate it with 10 free analyses per month in the playground.

{
  "fraud_detection": {
    "overall_risk": "A",
    "verdict": "authentic",
    "fraud_score":  { "risk": "A", "score": 0.14 },
    "ai_generated": { "risk": "A", "score": 0.00 },
    "tests": {
      "metadata":          { "risk": "A", "score": 0.22, "findings": ["EXIF lacks camera/lens fields — possibly synthesised or stripped"] },
      "thumbnail":         { "risk": "A", "score": 0.00, "findings": ["No embedded thumbnail (cannot run thumbnail check)"] },
      "ela":               { "risk": "A", "score": 0.00, "findings": [] },
      "glyph_duplicates":  { "risk": "A", "score": 0.00, "findings": [] },
      "field_consistency": { "risk": "A", "score": 0.00, "status": "ok" }
    }
  }
}

Duplicate check (cross-document)

Every JSON response contains a cross_document object. Independently of the authenticity check — and only within your own account — it flags when the same document number or page template is submitted again with different data. The duplicate check stores no document, only a non-reversible fingerprint per submission made of salted hash values and coarse image characteristics — never plaintext.

{
  "cross_document": {
    "verdict": "review",
    "is_duplicate": true,
    "document_id": "K-M-4-072/23-00918",
    "matches": [
      {
        "type": "document_id_reuse",
        "severity": "review",
        "message": "Same document number already seen with different document data.",
        "prior_seen_at": "2026-07-08T14:32:00+00:00",
        "distinct_count": 3
      }
    ]
  }
}

Error codes

  • 400No image in the request (“file” field missing or empty body) or an invalid value in the “output” field (accounts with PDF output only).
  • 401API key missing, invalid or revoked.
  • 402Feature not included in your plan (e.g. the authenticity check below Business).
  • 409Output as a filled PDF is set for the account, but no form is set up.
  • 413File larger than 20 MB.
  • 415Unsupported file format.
  • 429Per-minute limit exceeded, service momentarily at capacity, or monthly quota exhausted (the “code” field tells them apart).
  • 500The filled PDF could not be created; does not count against the quota.
  • 502Processing temporarily unavailable.
  • 504Processing timed out.

More examples

The full documentation with cURL, Node.js and Python samples — plus your own keys — is in the dashboard after signing in.

Full documentation in the dashboard