Destroy the identity data. Keep the document.
Send a passport or ID scan. Get it back with the machine-readable zone, personal identification numbers, portrait and signature painted out of the pixels — the document's own number stays readable unless you ask otherwise — processed in the EU, stored nowhere.
A 200 means processed — the warnings say what was protected
Everything the detection finds is destroyed. What it did not find is reported,
never hidden: every response carries a warnings array and a
findings object, always present, empty when coverage is complete.
Branch on warnings before archiving output.
nothing_detected means the image came back unchanged.
mrz_not_found and country_detector_no_match mean specific
content may still be visible. Treat these as review queues, not success.
findings maps detector names to match counts — for example
{"NETHERLANDS_BSN_NUMBER": 1, "MRZ_TD3_LINE_2": 1}. Detected
values are never returned, logged, or stored.
Authentication & limits
Every request needs a bearer API key, provisioned by the IDBird team. Revocation is effective on the very next request.
Authorization: Bearer idb_…
- Rate limit — 30 requests/minute per key by default. Exceeding it returns
429 rate_limitedwith aRetry-Afterheader: back off and retry. - Daily allowance — each key has a daily budget of API calls, counted per UTC day.
One fully-processed request is one call — a multi-page PDF still counts once.
Exhausted budgets return
429 daily_quota_exceeded; itsRetry-Afterpoints at the next UTC midnight. Rejected and failed requests are never billed. New keys start with a modest allowance — ask to have it raised.
Multipart form upload. Returns the redacted document as base64-encoded PNG inside a JSON envelope.
Request fields
| FIELD | REQUIRED | MEANING |
|---|---|---|
document | yes | JPEG, PNG, BMP or PDF (max 5 pages), max 10 MiB. The type is detected from file content — filename and declared content type are ignored. |
country_hint | no | ISO 3166-1 alpha-2 of the issuing country
(EL accepted for Greece). With a hint, only that country's detectors run — most precise.
Without it, auto mode applies all fully supported countries' detectors and the
response carries no_country_hint. |
redact_photo | no | true (default) ·
false · both — see photo redaction modes. |
redact_documentnumber | no | false (default) ·
true — see document number. |
Example
curl https://api.idbird.eu/v1/redact \
-H "Authorization: Bearer idb_…" \
-F document=@scan.jpg \
-F country_hint=NL
Response — single page
{
"image": "<base64 PNG>",
"warnings": ["document_number_not_redacted"],
"findings": {
"MRZ_TD3_LINE_1": 1,
"MRZ_TD3_LINE_2": 1,
"NETHERLANDS_PASSPORT": 1,
"OBJECT_TYPE/PERSON/FACE": 2,
"OBJECT_TYPE/PERSON/SIGNATURE": 1
}
}
image is always the most-redacted artifact of the request.
Response — multi-page PDF
Multi-page PDFs return a pages array instead of the flat image,
with aggregate warnings and findings at the top level:
{
"pages": [
{ "page": 1, "image": "<base64 PNG>", "findings": { … } },
{ "page": 2, "image": "<base64 PNG>", "findings": { … } }
],
"warnings": [],
"findings": { … }
}
Same inputs, same detection — but returns only the detected information types
with match counts. No image, never any values. Use it as a dry run: empty
findings tells you a redaction of this document would find nothing.
Billed and rate-limited like a redaction.
{
"findings": { "NETHERLANDS_BSN_NUMBER": 1 },
"warnings": ["no_country_hint"]
}
Multi-page PDFs add a per-page pages findings array.
Photo redaction modes
The portrait is redacted by default; redact_photo changes that
per request. The MRZ, personal identification numbers and the signature are destroyed in
every returned copy regardless of mode.
| MODE | BEHAVIOUR |
|---|---|
true | Default. The portrait is destroyed like everything else. |
false | The single returned copy keeps the portrait visible; the response
carries the photo_not_redacted warning. |
both | Two copies per page: image stays fully redacted, and
image_photo_visible carries a sibling with the portrait intact. |
Document number redaction
The document's own number (passport or ID-card number) printed in the visual zone is
kept by default — it is typically needed by the receiving party.
redact_documentnumber changes that per request. Personal identification numbers
(BSN, NIR, DNI, PESEL, CPR, …) are always destroyed, and the MRZ — which also encodes the
document number — is always fully destroyed regardless of this flag.
| MODE | BEHAVIOUR |
|---|---|
false | Default. The visual-zone document number stays readable; when one
was detected the response carries the document_number_not_redacted warning. |
true | The document number is destroyed like everything else. |
For BE and DE the only country-specific detectors are
document-number detectors, so default requests there protect the MRZ, portrait and signature.
Warnings
Always present. An empty array means full expected coverage.
| CODE | MEANING | CALLER ACTION |
|---|---|---|
nothing_detected | Nothing recognizable found; the image is returned unchanged. | Do not archive as redacted without review. |
no_country_hint | Auto mode ran (no country_hint given). | Provide the hint for more precise detection. |
country_detectors_unavailable | No country-specific number detection exists for the hinted country; MRZ-level redaction only. | The printed national number may remain — review. |
country_detector_no_match | No national identifier was detected. | If the document visibly carries one, it may remain — review. |
mrz_not_found | No machine-readable zone detected (absent on this side, cropped, or unreadable). | Expected for ID-card fronts; otherwise try a better scan. |
missing_face_finding | No portrait detected. | Usually fine for text-only pages. |
missing_signature_finding | No signature detected. | Usually fine for pages without one. |
photo_not_redacted | redact_photo=false was requested; the copy keeps the portrait. | Handle the artifact accordingly. |
document_number_not_redacted | A document number was detected and left visible (the default). | Send redact_documentnumber=true if you need it destroyed. |
Errors
One envelope for every error, with a stable machine-readable code and a static message. On any backend failure, no image is ever returned.
{ "error": { "code": "…", "message": "…" } }
| STATUS | CODES |
|---|---|
| 401 | invalid_api_key |
| 404 / 405 | not_found · method_not_allowed |
| 413 | payload_too_large — over 10 MiB |
| 415 | unsupported_media_type — content-sniffed, not extension-based |
| 422 | country_hint_invalid · country_not_supported ·
file_required · redact_photo_invalid · redact_documentnumber_invalid ·
too_many_pages · pdf_encrypted · unreadable_image ·
image_normalization_failed |
| 429 | rate_limited (back off seconds) ·
daily_quota_exceeded (come back after UTC midnight, or raise the allowance) —
both carry Retry-After |
| 500 / 502 | internal_error · dlp_unavailable
(redaction backend temporarily unavailable — retry with backoff) |
Country support
| SUPPORT | COUNTRIES |
|---|---|
Country-specific detection — most have personal-number detectors;
BE and DE have document-number detectors only |
NL FR ES AT BE HR
CZ DK FI DE IE IT
PL PT SE |
MRZ-level only — responses carry country_detectors_unavailable |
BG CY EE GR (alias EL)
HU LV LT LU MT
RO SK SI |
Not supported — rejected with country_not_supported |
all other codes |
Input requirements
- Formats — JPEG, PNG, BMP, or PDF up to 5 pages (not password-protected). Each PDF page is processed individually.
- Size — 10 MiB maximum upload.
- Orientation — sideways or upside-down scans are corrected automatically when the orientation can be determined reliably; metadata is not trusted.
- Quality — sharp, well-lit, uncropped documents detect best. Very large photos are
downscaled before processing; extremely noisy input surfaces as
mrz_not_foundornothing_detectedwarnings. - Expect roughly 2–8 seconds per page end-to-end; set client timeouts of 30 s or more for multi-page PDFs.