/api/v1/redact, but for whole files.file_id immediately, a
background worker processes the document, and you poll until it's ready,
then download.ready: KINDI re-extracts the output with a separate pipeline and checks
that no must-redact PII survived. If verification can't prove the file is
clean, the job fails closed (redaction_incomplete / verify_failed)
rather than handing back a file that might still contain PII.123curl -s -X POST https://api.kindi.me/api/v1/files/redact \ -H "Authorization: Bearer $KINDI_KEY" \ -F "file=@patient-notes.pdf;type=application/pdf"
201 Created):1234567{ "file_id": "f8a9b1c2-...", "state": "queued", "created_at": "2026-06-04T09:30:00Z", "expires_at": "2026-06-05T09:30:00Z", "poll_url": "/api/v1/files/f8a9b1c2-..." }
glossary (a comma-separated
list of inline terms) and/or glossary_id (a persisted glossary):12345curl -s -X POST https://api.kindi.me/api/v1/files/redact \ -H "Authorization: Bearer $KINDI_KEY" \ -F "file=@contract.pdf;type=application/pdf" \ -F "glossary=Project Falcon,Bluebird" \ -F "glossary_id=f8a9b1c2-..."
readypoll_url until state is ready or failed.12curl -s https://api.kindi.me/api/v1/files/$FILE_ID \ -H "Authorization: Bearer $KINDI_KEY"
12345678{ "file_id": "f8a9b1c2-...", "state": "ready", "word_count": 128, "entity_count": 6, "expires_at": "2026-06-05T09:30:00Z", "download_url": "/api/v1/files/f8a9b1c2-.../download" }
state moves through queued → processing → ready, and settles in one
of three terminal states:state | Meaning |
ready | Redacted and independently re-verified; download_url is live. |
failed | The job stopped; see error_code below. Nothing is returned. |
expired | The TTL elapsed. The redacted bytes are destroyed, but the row is kept for a while so you get a clear answer instead of a bare 404. Downloading returns 410 Gone with {"detail": "expired"}. Re-upload to get the file again. |
failed, an error_code explains why:error_code | Meaning |
unsupported_format | Not one of the supported types, or a corrupt / password-protected file. |
redaction_incomplete | PII survived and couldn't be safely re-masked; failed closed. |
verify_failed | The output couldn't be re-verified as clean; failed closed. |
image_redact_failed / embedded_image_failed | An image (standalone or embedded) couldn't be processed. |
too_many_pages / oversized_image / oversized_uncompressed | A per-job limit was exceeded. |
insufficient_tokens | Balance exhausted (the job is not charged). |
masker_unavailable / internal_error | Transient processing error; safe to retry. |
123curl -s -o redacted.pdf \ https://api.kindi.me/api/v1/files/$FILE_ID/download \ -H "Authorization: Bearer $KINDI_KEY"
200:| Status | Meaning |
404 not_ready | The job hasn't reached ready yet (or already failed). Keep polling. |
410 expired | The TTL elapsed and the bytes were destroyed. Re-upload. |
404 | The file id isn't yours, or was deleted. |
| Method | Path | Effect |
GET | /api/v1/files | List your files (newest first) |
POST | /api/v1/files/{id}/pin | Keep beyond the 24h TTL |
POST | /api/v1/files/{id}/unpin | Restore the TTL |
DELETE | /api/v1/files/{id} | Remove the file + its stored bytes now |
413 file_too_large)429 too_many_files_today
when exceeded). Every upload you made that day counts, including ones
that were cancelled, failed, or have since expired. Resets at Riyadh
midnight, the same boundary as the free-token quota./api/v1/mask and /api/v1/redact,
an identifier that fails its check digit is dropped (see
PII types).
Inside a file it is still redacted. OCR routinely mangles one digit
of a national ID or IBAN, and a mangled-but-obviously-an-ID number is
exactly the thing you don't want surviving into a shared document, so
the file path errs toward redacting./mask and /redact only. File jobs always run the full
entity set, so a document will have its ORGANIZATION, MRN,
MONETARY_AMOUNT, and every other extended type redacted even if those
types are switched off for your text calls.