Endpoint reference
Every route an API key can call, and nothing else: this page is generated from the same list the service enforces. Send Authorization: Bearer <key> on each. The schema is at /docs/api/openapi.json.
Every route can also answer invalid_api_key, not_available_to_api_keys, too_many_requests, busy, invalid_request, account_suspended, internal_error. See Errors.
GET /healthz
Whether the service is up.
Response 200.
POST /v1/attestations
State that you are authorised to correct this document. Every correction carries one.
| Parameter | In | Required | Type |
|---|---|---|---|
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"document_id": "\u2026",
"statement_version": "\u2026"
}
Response 201:
{
"attestation_id": "\u2026",
"statement_version": "\u2026",
"statement_text": "\u2026",
"created_at": "\u2026"
}
Can also answer: not_found.
GET /v1/audit
This account's record of what was done, newest first.
| Parameter | In | Required | Type |
|---|---|---|---|
subject_id | query | no | string or null |
limit | query | no | integer |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
[
{
"seq": 0,
"ts": "\u2026",
"actor_user_id": "\u2026",
"actor_kind": "\u2026",
"action": "\u2026",
"subject_type": "\u2026",
"subject_id": "\u2026",
"payload": {},
"entry_hash": "\u2026"
}
]
GET /v1/audit/export
The whole record as a file, with the chain's verdict inside it.
| Parameter | In | Required | Type |
|---|---|---|---|
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: business_plan_required.
GET /v1/audit/verify-chain
Recompute the record's hash chain and say where it breaks, if anywhere.
| Parameter | In | Required | Type |
|---|---|---|---|
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
POST /v1/certificates/verify
Check a certificate file's exact bytes. No key needed.
Request body: multipart/form-data.
Response 200:
{
"status": "\u2026",
"valid": true,
"reason": "\u2026",
"algorithm": "\u2026",
"certificate_id": "\u2026",
"issued_at": "\u2026",
"original_sha256": "\u2026",
"corrected_sha256": "\u2026",
"certificate_sha256": "\u2026",
"corrections": 0,
"key_id": "\u2026",
"statement": {}
}
GET /v1/certificates/{certificate_id}
Check a certificate by id: valid or not, its hashes and date. No key needed.
| Parameter | In | Required | Type |
|---|---|---|---|
certificate_id | path | yes | string |
Response 200:
{
"status": "\u2026",
"valid": true,
"reason": "\u2026",
"algorithm": "\u2026",
"certificate_id": "\u2026",
"issued_at": "\u2026",
"original_sha256": "\u2026",
"corrected_sha256": "\u2026",
"certificate_sha256": "\u2026",
"corrections": 0,
"key_id": "\u2026",
"statement": {}
}
Can also answer: not_found.
GET /v1/certificates/{certificate_id}/pdf
Download a certificate this account holds.
| Parameter | In | Required | Type |
|---|---|---|---|
certificate_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found, certificate_file_deleted.
GET /v1/compare/{job_id}
A comparison as it stands: its progress, then record -- the pages paired in order (an inserted or removed page shown as that), the numbered changes with their boxes in pixels at dpi, the words that changed, form fields, comments and links, and the file properties that differ -- or why it was not made, in refusal.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"job_id": "\u2026",
"status": "\u2026",
"progress": 0.0,
"stage": "\u2026",
"before_document_id": "\u2026",
"after_document_id": "\u2026",
"before_revision": "\u2026",
"after_revision": "\u2026",
"changed_since": [
"\u2026"
],
"record": {},
"refusal": {},
"message": "\u2026"
}
Can also answer: not_found, compare_too_many_pages, page_too_large, source_not_verified.
DELETE /v1/compare/{job_id}
Delete a comparison now, and the words it holds with it. It is deleted by itself when either document is.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 204.
Can also answer: not_found.
GET /v1/compare/{job_id}/changes.csv
Every run of words that changed, one a row, with where it was and a few words of context. No cell can start a spreadsheet formula. Paid, as the report is.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found, compare_not_ready, compare_report_paid, email_required.
GET /v1/compare/{job_id}/report.pdf
The comparison as a PDF: both files' fingerprints, how it was measured, every page and every change, a map of where each is and the words as a redline. No page of either document is in it. For a subscription, or a pack bought in the last thirty days.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found, compare_not_ready, compare_report_paid, email_required.
POST /v1/compress
Compress a PDF into up to four smaller files to choose from. Send it as multipart field file (up to 100 MB, for every plan; add password for a document that will not open without one). Answers 202 with a job_id to poll.
| Parameter | In | Required | Type |
|---|---|---|---|
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body: multipart/form-data.
Response 202:
{
"job_id": "\u2026",
"status": "\u2026"
}
Can also answer: compress_too_large, not_a_pdf, unreadable_pdf, password_protected, password_incorrect, no_pages, page_too_large, too_many_pages, image_too_large.
GET /v1/compress/{job_id}
A compression as it stands: its progress, then up to four options, each with its exact size in bytes (the length of the file you get), what it gives up and a preview; or why there are none, in refusal. Then what was asked under a size, and the documents made.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"job_id": "\u2026",
"status": "\u2026",
"progress": 0.0,
"stage": "\u2026",
"original": {
"bytes": null,
"size": null,
"pages": null,
"budget": null,
"summary": null
},
"options": [
null
],
"preview": {
"page": null,
"original_url": null
},
"under": {
"max_bytes": null,
"option": null,
"refusal": null
},
"refusal": {},
"choice_refusal": {},
"source_document_id": "\u2026",
"corrected_source": true
}
Can also answer: not_found.
DELETE /v1/compress/{job_id}
Delete a compression's options now; they are otherwise kept an hour, or until one is chosen.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 204.
Can also answer: not_found, compress_busy.
POST /v1/compress/{job_id}/choose
Make one option a document, then download it with the export route. Its one revision is verified by every page being checked still readable in the file as written.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"option": 0
}
Response 202:
{
"job_id": "\u2026",
"status": "\u2026"
}
Can also answer: not_found, compress_expired, compress_busy, compress_not_ready, compress_no_such_option, daily_limit_reached.
GET /v1/compress/{job_id}/options/{number}/preview.png
The same region of one option (5 is the file under a size), at 100% zoom, as a PNG.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
number | path | yes | integer |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found, compress_expired.
GET /v1/compress/{job_id}/original/preview.png
The densest small text in the file, at 100% zoom, as a PNG: what the options are compared on.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found, compress_expired.
POST /v1/compress/{job_id}/split
Split into documents each under max_bytes: of the smallest readable option when compress is true, else of the file as it was.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"max_bytes": 0,
"compress": true
}
Response 202:
{
"job_id": "\u2026",
"status": "\u2026"
}
Can also answer: not_found, compress_expired, compress_busy, compress_not_ready, daily_limit_reached.
POST /v1/compress/{job_id}/under
The best-looking file under max_bytes that still reads, as option 5 in under; or, when even the smallest readable one is over it, the refusal with both numbers and the offer to split.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"max_bytes": 0
}
Response 202:
{
"job_id": "\u2026",
"status": "\u2026"
}
Can also answer: not_found, compress_expired, compress_busy, compress_not_ready.
POST /v1/convert
Make one PDF of photos (JPEG, PNG, TIFF, HEIC, WebP, AVIF), plain text, Markdown, web pages and Office files (Word, Excel, PowerPoint, OpenDocument). Multipart: one part named files for each file, in the order their pages should come, and optionally paper (a4, letter, or fit: each page the size of its picture), orientation (auto, portrait, landscape), margin_mm (0 to 50) and markdown (true or false). Each file within this plan's upload limit, and all of them together within 32 MB; an empty file is refused at once. Answers 202 with a job_id to poll.
| Parameter | In | Required | Type |
|---|---|---|---|
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body: multipart/form-data.
Response 202:
{
"job_id": "\u2026",
"status": "\u2026",
"progress": 0.0,
"stage": "\u2026",
"files": 0,
"options": {},
"document_id": "\u2026",
"document": {
"document_id": null,
"tenant_id": null,
"state": null,
"page_count": null,
"original_sha256": null,
"head_revision_id": null,
"filename_hint": null,
"pages": null,
"issued_signals": null,
"concerns": null,
"protected": null,
"unlocked": null
},
"description": "\u2026",
"pages": 0,
"sources": [
null
],
"record": {}
}
Can also answer: convert_invalid, convert_unreadable, convert_too_large, file_too_large, daily_limit_reached.
GET /v1/convert-from-pdf/{job_id}
The export's progress, then its content-free fidelity record, or why it was refused. Simple Word prose is editable; complex Word pages are labelled pictures. Excel accepts measured tables only and keeps cells as literal text. PDF/A-2b is a raster copy, delivered only after local validation. The record states what was lost and any OCR confidence; it never promises the original Office layout.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found, source_not_verified, convert_invalid, convert_too_large, convert_unsupported, ocr_not_tabular, ocr_unreadable, ocr_language_unknown, provider_unavailable.
DELETE /v1/convert-from-pdf/{job_id}
Forget an export and remove its files now. A pending or running export cannot publish after it is forgotten. Deleting its source document also removes its exports.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 204.
Can also answer: not_found, missing_capability.
GET /v1/convert-from-pdf/{job_id}/download
Download the exported files and record.json together as a ZIP, with source/output hashes, format, fidelity and changes. Download permission is required. Free when the version read holds no corrections made here; otherwise the corrected document's existing payment or email gate applies.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found, missing_capability, convert_not_ready, payment_required, email_required.
GET /v1/convert/{job_id}
A conversion as it stands: queued, running, then done -- the new document in document_id, and what each file became and how close it is in sources -- or refused, with the reason in refusal. The PDF downloads through the export route, free: nothing in it was corrected here.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"job_id": "\u2026",
"status": "\u2026",
"progress": 0.0,
"stage": "\u2026",
"files": 0,
"options": {},
"document_id": "\u2026",
"document": {
"document_id": null,
"tenant_id": null,
"state": null,
"page_count": null,
"original_sha256": null,
"head_revision_id": null,
"filename_hint": null,
"pages": null,
"issued_signals": null,
"concerns": null,
"protected": null,
"unlocked": null
},
"description": "\u2026",
"pages": 0,
"sources": [
null
],
"record": {}
}
Can also answer: not_found, convert_unsupported, convert_too_large, convert_unreadable, convert_characters_missing, convert_runaway_layout, convert_password_needed, convert_timed_out, convert_office_unavailable, convert_invalid, convert_failed, identity_document_refused.
POST /v1/documents
Upload a PDF. Send it as multipart field file; add password for a document that will not open without one. Add tool (a tool's name, such as merge) to put it in that tool's list rather than correction's. An identity document (a passport, an identity card or a driving licence) is refused, and its file deleted.
| Parameter | In | Required | Type |
|---|---|---|---|
tool | query | no | string or null |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body: multipart/form-data.
Response 201:
{
"document_id": "\u2026",
"tenant_id": "\u2026",
"state": "\u2026",
"page_count": 0,
"original_sha256": "\u2026",
"head_revision_id": "\u2026",
"filename_hint": "\u2026",
"pages": [
null
],
"issued_signals": {},
"concerns": [
"\u2026"
],
"protected": true,
"unlocked": true
}
Can also answer: file_too_large, too_many_pages, page_too_large, not_a_pdf, unreadable_pdf, no_pages, password_protected, password_required, password_incorrect, not_protected, identity_document_refused, unknown_tool, tool_mismatch.
GET /v1/documents
List this account's documents, newest first. Add ?tool= to list only one tool's: the files sent to it and the documents it made. correct lists correction's.
| Parameter | In | Required | Type |
|---|---|---|---|
limit | query | no | integer |
tool | query | no | string or null |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
[
{
"document_id": "\u2026",
"tenant_id": "\u2026",
"state": "\u2026",
"page_count": 0,
"original_sha256": "\u2026",
"head_revision_id": "\u2026",
"filename_hint": "\u2026",
"pages": [
null
],
"issued_signals": {},
"concerns": [
null
],
"protected": true,
"unlocked": true
}
]
Can also answer: unknown_tool.
POST /v1/documents/bates
Bates-number document_ids, in that order: prefix, the number zero-padded to digits from start, and suffix, on every page, running on from document to document. One new document each; the record gives each one's first and last number.
| Parameter | In | Required | Type |
|---|---|---|---|
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"document_ids": [
"\u2026"
],
"prefix": "\u2026",
"start": 0,
"digits": 0,
"suffix": "\u2026",
"position": "top-left",
"face": "helvetica",
"size": 0.0,
"color": [
0.0
],
"margin": 0.0
}
Response 201:
{
"operation": "\u2026",
"description": "\u2026",
"documents": [
null
],
"record": {}
}
Can also answer: not_found, marks_invalid, marks_would_cover, marks_do_not_fit, source_not_verified, identity_document_refused.
POST /v1/documents/compare
Compare two of your documents: what changed from before_document_id to after_document_id, each as it stands (current, the default) or as uploaded (original) in before_version and after_version, pinned now. Answers 202 with a job_id to poll. Nothing is changed and no document is made.
| Parameter | In | Required | Type |
|---|---|---|---|
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"before_document_id": "\u2026",
"after_document_id": "\u2026",
"before_version": "current",
"after_version": "current"
}
Response 202:
{
"job_id": "\u2026",
"status": "\u2026",
"progress": 0.0,
"stage": "\u2026",
"before_document_id": "\u2026",
"after_document_id": "\u2026",
"before_revision": "\u2026",
"after_revision": "\u2026",
"changed_since": [
"\u2026"
],
"record": {},
"refusal": {},
"message": "\u2026"
}
Can also answer: not_found, daily_limit_reached.
POST /v1/documents/merge
Merge documents into a new one: send document_ids, two to twenty, in the order their pages should come. The documents merged are left as they were. Every page is carried as stored; outlines, form fields, internal links, attachments and the first document's metadata come across, and the new document's record says which pages of which documents it holds.
| Parameter | In | Required | Type |
|---|---|---|---|
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"document_ids": [
"\u2026"
]
}
Response 201:
{
"operation": "\u2026",
"description": "\u2026",
"documents": [
null
],
"record": {}
}
Can also answer: not_found, page_op_memory_ceiling, too_many_pages, source_not_verified, page_op_invalid, identity_document_refused.
GET /v1/documents/{document_id}
One document, with its pages, its class and state.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"document_id": "\u2026",
"tenant_id": "\u2026",
"state": "\u2026",
"page_count": 0,
"original_sha256": "\u2026",
"head_revision_id": "\u2026",
"filename_hint": "\u2026",
"pages": [
null
],
"issued_signals": {},
"concerns": [
"\u2026"
],
"protected": true,
"unlocked": true
}
Can also answer: not_found.
DELETE /v1/documents/{document_id}
Delete a document, its corrections and every file made from it. The record keeps that it existed. With ?tool=, take it out of that tool's list instead, and delete it only when no other tool lists it.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
tool | query | no | string or null |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 204.
Can also answer: not_found, missing_capability, unknown_tool.
POST /v1/documents/{document_id}/certificate
Issue a signed verification certificate for the document as it now stands.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"name": "\u2026"
}
Response 201:
{
"certificate_id": "\u2026",
"document_id": "\u2026",
"revision_id": "\u2026",
"issued_at": "\u2026",
"original_sha256": "\u2026",
"corrected_sha256": "\u2026",
"certificate_sha256": "\u2026",
"corrections": 0,
"key_id": "\u2026",
"pdf_available": true
}
Can also answer: business_plan_required, not_found, nothing_to_export, not_verified, verification_failed, nothing_to_certify, correction_not_verified, record_does_not_verify.
GET /v1/documents/{document_id}/certificates
The certificates issued for a document, newest first.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
[
{
"certificate_id": "\u2026",
"document_id": "\u2026",
"revision_id": "\u2026",
"issued_at": "\u2026",
"original_sha256": "\u2026",
"corrected_sha256": "\u2026",
"certificate_sha256": "\u2026",
"corrections": 0,
"key_id": "\u2026",
"pdf_available": true
}
]
Can also answer: not_found.
POST /v1/documents/{document_id}/classify
Re-examine the pages: which carry text and which are scans, and what kind of document this is. An identity document (a passport, an identity card or a driving licence) is refused and deleted when the caller could delete it; for anyone else it is kept, with a warning among its concerns.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
[
{
"index": 0,
"width_pt": 0.0,
"height_pt": 0.0,
"rotation": 0,
"kind": "\u2026",
"char_count": 0,
"image_count": 0,
"image_coverage": 0.0,
"confidence": 0.0,
"natural_dpi": 0
}
]
Can also answer: not_found, identity_document_refused.
POST /v1/documents/{document_id}/compress
Compress a document as it stands, its latest correction included. Answers 202 with a job_id. A compressed copy is a new document: the verification and certificate of this one do not carry over.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 202:
{
"job_id": "\u2026",
"status": "\u2026"
}
Can also answer: not_found, source_not_verified.
POST /v1/documents/{document_id}/convert-from-pdf
Export the document's current verified version. target is png (the default), jpeg, text, layout, docx, xlsx or pdfa; raster resolution is dpi (72–600, default 150), JPEG quality is 1–100 (default 90), and OCR lang defaults to eng. Answers 202 with a job_id. The source document stays as it was.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"target": "png",
"dpi": 0,
"quality": 0,
"lang": "\u2026"
}
Response 202.
Can also answer: not_found, daily_limit_reached.
GET /v1/documents/{document_id}/corrections
Every correction standing on the document, oldest first.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
[
{
"seq": 0,
"page_index": 0,
"box_render": [
null
],
"box_dpi": 0,
"changed_render": [
null
],
"changed_dpi": 0,
"declared_render": [
null
],
"declared_dpi": 0,
"text_before": "\u2026",
"text_after": "\u2026",
"visibility_cost": "\u2026",
"verified": true
}
]
Can also answer: not_found.
POST /v1/documents/{document_id}/crop
Crop pages ("all", or indexes from 0) to box_render at render_dpi, read on the first page named, or by margins_pt (top, right, bottom, left, in points) from each edge; or put a crop made here back with restore. The crop box moves and nothing is discarded: every content stream is checked unchanged. Not charged.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"pages": "\u2026",
"box_render": [
0.0
],
"margins_pt": {
"top": null,
"right": null,
"bottom": null,
"left": null
},
"render_dpi": 0,
"restore": true
}
Response 200:
{
"document": {
"document_id": null,
"tenant_id": null,
"state": null,
"page_count": null,
"original_sha256": null,
"head_revision_id": null,
"filename_hint": null,
"pages": null,
"issued_signals": null,
"concerns": null,
"protected": null,
"unlocked": null
},
"revision_id": "\u2026",
"operation": "overlays",
"description": "\u2026",
"record": {},
"verification": {},
"warnings": [
"\u2026"
],
"report": {}
}
Can also answer: not_found, page_out_of_range, source_not_verified, off_page, nothing_to_uncrop, signed_document, bad_request, page_op_memory_ceiling, editor_failed.
POST /v1/documents/{document_id}/edits
Apply a proposed correction. The answer is its verification.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"request": {
"page_index": null,
"target": null,
"replacement": null,
"attestation_id": null,
"font_attempt": null
},
"apply": {
"proposal_id": null,
"confirm_token": null
}
}
Response 200:
{
"verification_id": "\u2026",
"revision_id": "\u2026",
"output_sha256": "\u2026",
"dpi": 0,
"passed": true,
"failure_reason": "\u2026",
"pages": [
null
],
"guards": [
{}
],
"stream_changes": {},
"self_attack": {
"outcome": null,
"kind": null,
"change": null,
"covered": null,
"reason": null,
"detector": null,
"score": null,
"strength": null,
"lines": null,
"attempts": null,
"tried": null,
"version": null
},
"quality": {
"version": null,
"level": null,
"headline": null,
"components": null,
"advice": null
}
}
Can also answer: not_found, attestation_required, stale_or_invalid_confirmation, edit_refused, edit_failed, daily_limit_reached.
POST /v1/documents/{document_id}/edits:propose
Propose a correction and read what the engine would do, or why it refuses. Changes nothing.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"page_index": 0,
"target": {
"method": null,
"box_render": null,
"render_dpi": null,
"original_text": null
},
"replacement": "\u2026",
"attestation_id": "\u2026",
"font_attempt": 0
}
Response 200:
{
"proposal_id": "\u2026",
"confirm_token": "\u2026",
"document_id": "\u2026",
"page_index": 0,
"tier": 0,
"tier_name": "\u2026",
"visibility_cost": "\u2026",
"explanation": "\u2026",
"measurements": {},
"warnings": [
"\u2026"
],
"refusal": "\u2026",
"advice": {
"code": null,
"what": null,
"why": null,
"do": null,
"worth_reporting": null
}
}
Can also answer: not_found, attestation_required, page_out_of_range.
POST /v1/documents/{document_id}/export
Pass the export gate: the document is released only if its latest verification is of these exact bytes and passed.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"revision_id": "\u2026",
"output_sha256": "\u2026",
"verification_id": "\u2026",
"marking_applied": "\u2026",
"bytes_available": true
}
Can also answer: not_found, nothing_to_export, not_verified, verification_hash_mismatch, verification_failed, diff_outside_expected_region.
GET /v1/documents/{document_id}/export/download
Download the corrected PDF, through the same gate.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found, nothing_to_export, not_verified, verification_hash_mismatch, verification_failed, diff_outside_expected_region, payment_required, email_required.
POST /v1/documents/{document_id}/fill
Fill or sign a form, as one correction per saved filled/signed copy. Empty fillable copies use no allowance. output finished sets the answers or own marks on the page; fillable adds real form fields, with any answers as their values, and with pages and no fields makes every field found on those pages fillable. Name fields by the ids …/fields gave, or draw one with rect_render and kind. The answer is the new revision and its verification; a field that could not be filled is listed in refused with its reason. A signature field accepts an explicitly owned typed, drawn or uploaded signature; existing ink is refused. Answers are written into the file and nowhere else.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"attestation_id": "\u2026",
"output": "finished",
"render_dpi": 0,
"pages": [
0
],
"fields": [
null
]
}
Response 200:
{
"revision_id": "\u2026",
"output": "finished",
"filled_count": 0,
"filled": [
"\u2026"
],
"added_count": 0,
"added": [
"\u2026"
],
"refused": [
null
],
"outside_pixels": 0,
"changed_pixels": 0,
"verified": true,
"empty_identical": true,
"incremental": true
}
Can also answer: not_found, attestation_required, page_out_of_range, nothing_to_fill, nothing_filled, duplicate_field, field_outside_page, issued_document, xfa_form, no_fields, fill_refused, fill_failed, daily_limit_reached.
POST /v1/documents/{document_id}/flatten
Bake annotations, form fields or both into the pages, for a final copy. The one step that changes a page's own content streams, and its record and verification say so; the page's own streams stay in front of what was baked in. Not charged.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"annotations": true,
"fields": true
}
Response 200:
{
"document": {
"document_id": null,
"tenant_id": null,
"state": null,
"page_count": null,
"original_sha256": null,
"head_revision_id": null,
"filename_hint": null,
"pages": null,
"issued_signals": null,
"concerns": null,
"protected": null,
"unlocked": null
},
"revision_id": "\u2026",
"operation": "overlays",
"description": "\u2026",
"record": {},
"verification": {},
"warnings": [
"\u2026"
],
"report": {}
}
Can also answer: not_found, source_not_verified, nothing_to_flatten, signed_document, bad_request, page_op_memory_ceiling, editor_failed.
GET /v1/documents/{document_id}/manifest
The provenance record embedded in the corrected file.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found, no_revision, no_manifest.
POST /v1/documents/{document_id}/ocr
Read a document's scanned pages, as it stands now. lang is auto (the script is found first, then the best of a short list of languages for it) or a language from /v1/ocr/languages; outputs is any of pdf (a searchable copy, a new document), text, layout and csv. Either may be left out, as may the whole body: lang is then auto, and outputs all four. Answers 202 with a job_id to poll. The document read is left as it was.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"lang": "\u2026",
"outputs": [
"pdf"
]
}
Response 202:
{
"job_id": "\u2026",
"status": "\u2026",
"progress": 0.0,
"stage": "\u2026",
"document_id": "\u2026",
"revision": "\u2026",
"changed_since": true,
"lang": "\u2026",
"outputs": [
"\u2026"
],
"description": "\u2026",
"pages": [
null
],
"documents": [
null
]
}
Can also answer: not_found, ocr_language_unknown, daily_limit_reached.
POST /v1/documents/{document_id}/overlays
Lay text boxes, images, shapes, freehand strokes, highlights, underlines, strike-throughs and notes over the pages, as one step of at most 50: items, each with its kind, page_index (from 0) and box_render -- or points_render for a line or a stroke -- in pixels at render_dpi of the page as it is seen, with text, font (sans, serif, mono), size_pt, colour, fill, opacity, stroke_pt or image_data (a PNG or JPEG in base64, at most 2 MB). Each is a real annotation above the page, named in record so it can be taken off again; the page's own content is unchanged, and that is checked on the stored file. An opaque box, text box or image over the page's own ink is refused: changing a word is a correction. Not charged, and a document with only overlays on it downloads free.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"items": [
null
],
"render_dpi": 0
}
Response 200:
{
"document": {
"document_id": null,
"tenant_id": null,
"state": null,
"page_count": null,
"original_sha256": null,
"head_revision_id": null,
"filename_hint": null,
"pages": null,
"issued_signals": null,
"concerns": null,
"protected": null,
"unlocked": null
},
"revision_id": "\u2026",
"operation": "overlays",
"description": "\u2026",
"record": {},
"verification": {},
"warnings": [
"\u2026"
],
"report": {}
}
Can also answer: not_found, page_out_of_range, source_not_verified, ink_edit_refused, off_page, too_many_overlays, image_unreadable, image_too_large, text_too_long, font_cannot_draw, overlay_invisible, signed_document, protected_feature, bad_request, page_op_memory_ceiling, password_required, unreadable_pdf, editor_failed.
POST /v1/documents/{document_id}/overlays:remove
Take overlays off again: names, as the step that added them recorded them (ceco-…). A new revision, like adding them; undo steps back over it. A watermark is never taken off. Not charged.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"names": [
"\u2026"
]
}
Response 200:
{
"document": {
"document_id": null,
"tenant_id": null,
"state": null,
"page_count": null,
"original_sha256": null,
"head_revision_id": null,
"filename_hint": null,
"pages": null,
"issued_signals": null,
"concerns": null,
"protected": null,
"unlocked": null
},
"revision_id": "\u2026",
"operation": "overlays",
"description": "\u2026",
"record": {},
"verification": {},
"warnings": [
"\u2026"
],
"report": {}
}
Can also answer: not_found, source_not_verified, unknown_overlay, protected_feature, signed_document, bad_request, page_op_memory_ceiling, editor_failed.
POST /v1/documents/{document_id}/page-numbers
Page numbers, headers and footers, into a new document: up to six stamps, each a line of text (with {page} and {pages}) at a position along the top or bottom, on the pages named, numbered from start. A line that would cover something on a page is refused.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"stamps": [
null
],
"pages": "\u2026",
"start": 0
}
Response 201:
{
"operation": "\u2026",
"description": "\u2026",
"documents": [
null
],
"record": {}
}
Can also answer: not_found, marks_invalid, marks_glyph_missing, marks_would_cover, marks_do_not_fit, page_op_out_of_range, source_not_verified, identity_document_refused.
POST /v1/documents/{document_id}/pages
Split, extract, remove, reorder or rotate pages, into new documents; the document itself is left as it was. Send operation and, as it needs, pages ("1-3, 5, 8-", counted from one), ranges, every or max_mb (split), or degrees (rotate, a multiple of 90).
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"operation": "split",
"pages": "\u2026",
"ranges": [
"\u2026"
],
"every": 0,
"max_mb": 0.0,
"degrees": 0
}
Response 201:
{
"operation": "\u2026",
"description": "\u2026",
"documents": [
null
],
"record": {}
}
Can also answer: not_found, page_op_out_of_range, page_op_invalid, page_op_part_too_large, page_op_memory_ceiling, too_many_pages, source_not_verified, identity_document_refused.
GET /v1/documents/{document_id}/pages/{page_index}/crop.png
Native-resolution pixels of one region, at most 4 megapixels. Until the document is paid for, a corrected page is marked and native only inside its corrections.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
page_index | path | yes | integer |
x | query | yes | integer |
y | query | yes | integer |
w | query | yes | integer |
h | query | yes | integer |
dpi | query | no | integer |
revision | query | no | string or null |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found, crop_too_large, inspection_budget_spent.
GET /v1/documents/{document_id}/pages/{page_index}/fields
Where the answers go on a page: every field found, sure or possible, with its rectangle in points and in pixels at render_dpi. refusal says in words when nothing on the page can be filled. Changes nothing.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
page_index | path | yes | integer |
render_dpi | query | no | integer |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"page_index": 0,
"revision_id": "\u2026",
"render_dpi": 0,
"report": {
"page": null,
"page_kind": null,
"fields": null,
"rejected": null,
"page_style": null,
"refused": null,
"message": null,
"evidence": null
},
"refusal": {
"code": null,
"what": null,
"why": null,
"do": null
}
}
Can also answer: not_found, page_out_of_range.
POST /v1/documents/{document_id}/pages/{page_index}/ocr
Read a page and say where the words are, with their confidence.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
page_index | path | yes | integer |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"find": "\u2026",
"box_render": [
0
],
"render_dpi": 0,
"lang": "\u2026",
"turn": 0
}
Response 200:
{
"page_index": 0,
"provider": "\u2026",
"lang": "\u2026",
"render_dpi": 0,
"word_count": 0,
"available": true,
"message": "\u2026",
"matches": [
null
],
"confirm_threshold": 0.0,
"selection_text": "\u2026",
"selection_confidence": 0.0,
"word_source": "text_layer"
}
Can also answer: not_found, page_out_of_range.
POST /v1/documents/{document_id}/pages/{page_index}/preflight
Find the words in a region that are already known to refuse, before trying them.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
page_index | path | yes | integer |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"box_render": [
0
],
"render_dpi": 0,
"lang": "\u2026",
"turn": 0
}
Response 200:
{
"page_index": 0,
"render_dpi": 0,
"word_source": "text_layer",
"checked": 0,
"skipped": 0,
"regions": [
null
],
"applicable": true,
"message": "\u2026"
}
Can also answer: not_found, page_out_of_range.
GET /v1/documents/{document_id}/pages/{page_index}/preview.png
A page as a low-resolution image, to look at.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
page_index | path | yes | integer |
revision | query | no | string or null |
thumb | query | no | boolean |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found.
POST /v1/documents/{document_id}/redactions
Remove for good what lies in regions (each a page_index, box_render and render_dpi; at most 200): its text, the parts of images under it, drawings, form fields and annotations, with a mark (black, white, or label with up to 40 characters of label) in their place. match_ids names the matches of a find on this version that the regions confirm; there is no way to redact every match unseen. Before anything is kept, the new file is checked: nothing removed can be found in its text, its bytes or its pictures, and nothing changed outside the regions but the fields and annotations they touch and, on a JPEG scan, the compression blocks they cross. Regions on at most ten pages in one redaction. still_elsewhere counts where the redacted words still stand outside the regions, and shares_ended the share links that showed what was removed and no longer open. One new revision, charged as one correction; a refusal charges nothing, and a watermark, seal or signed document is refused.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"regions": [
null
],
"mark": "black",
"label": "\u2026",
"match_ids": [
"\u2026"
]
}
Response 200:
{
"document": {
"document_id": null,
"tenant_id": null,
"state": null,
"page_count": null,
"original_sha256": null,
"head_revision_id": null,
"filename_hint": null,
"pages": null,
"issued_signals": null,
"concerns": null,
"protected": null,
"unlocked": null
},
"revision_id": "\u2026",
"record": {},
"removed": {},
"verification": {
"kind": null,
"regions": null,
"removed_verified": null,
"probes": null,
"probe_words": null,
"carries_corrections": null,
"passed": null,
"outside_pixels": null,
"verification_id": null
},
"refused": [
null
],
"still_elsewhere": {},
"shares_ended": 0
}
Can also answer: not_found, page_out_of_range, redaction_invalid, region_off_page, too_many_regions, label_too_long, label_cannot_draw, match_stale, nothing_redacted, removal_failed, removal_not_verified, protected_feature, signed_document, source_not_verified, redaction_failed, too_many_pages_to_redact, page_op_memory_ceiling, daily_limit_reached.
POST /v1/documents/{document_id}/redactions:find
Find what to redact: exactly one of query (a word or phrase, at least three characters), pattern (email, phone, iban, card, date or number) or regex (a bounded regular expression), on pages (indexes from 0; every page when left out). Each match has a match_id, its page_index and boxes_render at render_dpi; at most 500 are listed, with total and truncated. Scanned pages are read with the recogniser, at most five not read before in one find (name them with pages), and scanned_pages_unread counts any this server could not read. elsewhere counts where the same words also stand outside the pages' drawn content -- the title and metadata, bookmarks, notes, form fields, links, attachments, scripts, alternative text -- never the words. Nothing is removed and nothing is charged; a match's text is answered to the person and never to an assistant.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"query": "\u2026",
"pattern": "\u2026",
"regex": "\u2026",
"pages": [
0
],
"render_dpi": 0
}
Response 200:
{
"matches": [
null
],
"total": 0,
"truncated": true,
"scanned_pages_read": 0,
"scanned_pages_unread": 0,
"elsewhere": {}
}
Can also answer: not_found, page_out_of_range, query_too_short, pattern_unknown, regex_invalid, ocr_unavailable, too_many_scanned_pages.
POST /v1/documents/{document_id}/redo
Restore the correction or the editing step last undone.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"document": {
"document_id": null,
"tenant_id": null,
"state": null,
"page_count": null,
"original_sha256": null,
"head_revision_id": null,
"filename_hint": null,
"pages": null,
"issued_signals": null,
"concerns": null,
"protected": null,
"unlocked": null
},
"undone": {
"seq": null,
"page_index": null,
"box_render": null,
"box_dpi": null,
"changed_render": null,
"changed_dpi": null,
"declared_render": null,
"declared_dpi": null,
"text_before": null,
"text_after": null,
"visibility_cost": null,
"verified": null
},
"corrections": [
null
]
}
Can also answer: not_found, nothing_to_redo.
POST /v1/documents/{document_id}/repair
Rebuild a damaged file -- a broken cross-reference table, a truncated stream, a missing tail -- into a valid one, and say in report what was found (problems_found), what was recovered and what could not be (lost). Upload the damaged file first, as any other: the upload takes it and lists the concern. Not charged.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{}
Response 200:
{
"document": {
"document_id": null,
"tenant_id": null,
"state": null,
"page_count": null,
"original_sha256": null,
"head_revision_id": null,
"filename_hint": null,
"pages": null,
"issued_signals": null,
"concerns": null,
"protected": null,
"unlocked": null
},
"revision_id": "\u2026",
"operation": "overlays",
"description": "\u2026",
"record": {},
"verification": {},
"warnings": [
"\u2026"
],
"report": {}
}
Can also answer: not_found, source_not_verified, nothing_to_repair, unreadable_pdf, password_required, page_op_memory_ceiling, editor_failed.
GET /v1/documents/{document_id}/search
Where a phrase appears in the pages that carry text.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
q | query | no | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"query": "\u2026",
"matches": [
null
],
"pages_searched": [
0
],
"pages_needing_recognition": [
0
],
"truncated": true
}
Can also answer: not_found.
POST /v1/documents/{document_id}/undo
Step back one revision: the correction at the head, or the editing step there (undone says which, with its kind). Nothing is deleted.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"document": {
"document_id": null,
"tenant_id": null,
"state": null,
"page_count": null,
"original_sha256": null,
"head_revision_id": null,
"filename_hint": null,
"pages": null,
"issued_signals": null,
"concerns": null,
"protected": null,
"unlocked": null
},
"undone": {
"seq": null,
"page_index": null,
"box_render": null,
"box_dpi": null,
"changed_render": null,
"changed_dpi": null,
"declared_render": null,
"declared_dpi": null,
"text_before": null,
"text_after": null,
"visibility_cost": null,
"verified": null
},
"corrections": [
null
]
}
Can also answer: not_found, nothing_to_undo.
GET /v1/documents/{document_id}/verification
The verification of the document as it now stands: the pixel comparison and every guard.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"verification_id": "\u2026",
"revision_id": "\u2026",
"output_sha256": "\u2026",
"dpi": 0,
"passed": true,
"failure_reason": "\u2026",
"pages": [
null
],
"guards": [
{}
],
"stream_changes": {},
"self_attack": {
"outcome": null,
"kind": null,
"change": null,
"covered": null,
"reason": null,
"detector": null,
"score": null,
"strength": null,
"lines": null,
"attempts": null,
"tried": null,
"version": null
},
"quality": {
"version": null,
"level": null,
"headline": null,
"components": null,
"advice": null
}
}
Can also answer: not_found, not_verified, no_revision.
POST /v1/documents/{document_id}/watermark
Watermark a document into a new one: text, or a PNG or JPEG as image_base64 (drawn at most half opaque), with opacity, rotation (degrees), position, size or scale, face, color and pages. Every page keeps its own content streams; no pixel outside the watermark changes, and that is checked before the document is made.
| Parameter | In | Required | Type |
|---|---|---|---|
document_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body:
{
"text": "\u2026",
"image_base64": "\u2026",
"face": "helvetica",
"size": 0.0,
"color": [
0.0
],
"opacity": 0.0,
"rotation": 0.0,
"position": "top-left",
"scale": 0.0,
"margin": 0.0,
"pages": "\u2026"
}
Response 201:
{
"operation": "\u2026",
"description": "\u2026",
"documents": [
null
],
"record": {}
}
Can also answer: not_found, marks_invalid, marks_glyph_missing, marks_image_unreadable, marks_do_not_fit, page_op_out_of_range, source_not_verified, identity_document_refused.
GET /v1/jobs/{job_id}
The progress of a queued job.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"job_id": "\u2026",
"kind": "\u2026",
"status": "\u2026",
"progress": 0.0,
"stage": "\u2026",
"result": {},
"last_error": "\u2026"
}
Can also answer: not_found.
GET /v1/ocr/languages
The languages this server reads, by their codes (eng, sqi, srp_latn), for a reading's lang. auto is always there besides.
| Parameter | In | Required | Type |
|---|---|---|---|
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"available": true,
"message": "\u2026",
"languages": [
"\u2026"
]
}
GET /v1/ocr/{job_id}
A reading as it stands: its progress, then each page's state (read, partial, unreadable or skipped) with its language, where its words came from (source: read here, or the file's own text, quoted and never read or checked here) and the words written and held back; the searchable copy in documents; where each text output is; and corrections, whether what was read holds a correction made here, which decides what downloading costs -- or why nothing was made, in refusal.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"job_id": "\u2026",
"status": "\u2026",
"progress": 0.0,
"stage": "\u2026",
"document_id": "\u2026",
"revision": "\u2026",
"changed_since": true,
"lang": "\u2026",
"outputs": [
"\u2026"
],
"description": "\u2026",
"pages": [
null
],
"documents": [
null
]
}
Can also answer: not_found, ocr_unreadable, ocr_nothing_to_read, ocr_too_many_pages, ocr_language_unknown, provider_unavailable, source_not_verified, ocr_failed.
DELETE /v1/ocr/{job_id}
Delete a reading now, and the text it holds with it. A searchable copy it made is a document of its own and stays. A reading is deleted by itself when the document read is.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 204.
Can also answer: not_found.
GET /v1/ocr/{job_id}/layout.txt
The words read, laid out as each page has them: lines where they stand, columns apart.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found, missing_capability, ocr_not_ready, payment_required, email_required.
GET /v1/ocr/{job_id}/table.csv
The pages that are clearly tables, as CSV, a row a line and a cell a column. No cell can start a spreadsheet formula.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found, missing_capability, ocr_not_ready, ocr_not_tabular, payment_required, email_required.
GET /v1/ocr/{job_id}/text.txt
The words read, as plain UTF-8 text in reading order, for whoever may download the document itself. Free when the version read has no corrections made here, merged or split here or not; otherwise downloaded as a corrected document is.
| Parameter | In | Required | Type |
|---|---|---|---|
job_id | path | yes | string |
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200.
Can also answer: not_found, missing_capability, ocr_not_ready, payment_required, email_required.
GET /v1/plans
Every plan side by side, in the numbers the service enforces. No key needed.
Response 200:
{
"currency": "\u2026",
"prices_include_vat": true,
"capabilities": [
"\u2026"
],
"plans": [
null
]
}
POST /v1/protect
Protect a PDF with AES-256 and get it back; nothing is stored. Multipart: file, user_password (to open it), owner_password (for its permissions), permissions (all, none, or print, print_high_quality, copy, edit, annotate, fill_forms, assemble, comma separated) and password for a file that already has one. Read back and checked before it is returned.
| Parameter | In | Required | Type |
|---|---|---|---|
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body: multipart/form-data.
Response 200.
Can also answer: file_too_large, not_a_pdf, protect_invalid, protect_not_pdf, protect_password_needed, protect_password_wrong, protect_owner_password_needed.
POST /v1/unlock
Take the password off a PDF with its own password, and get it back; nothing is stored. Multipart: file and password -- the owner's, for a file whose owner restricted it. One password, tried once: this is not a password cracker.
| Parameter | In | Required | Type |
|---|---|---|---|
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Request body: multipart/form-data.
Response 200.
Can also answer: file_too_large, not_a_pdf, protect_not_pdf, protect_password_needed, protect_password_wrong, protect_owner_password_needed, protect_not_protected.
GET /v1/usage
What this account holds and may do today. Read-only.
| Parameter | In | Required | Type |
|---|---|---|---|
authorization | header | no | string or null |
x-tenant-id | header | no | string or null |
Response 200:
{
"limit": 0,
"used": 0.0,
"remaining": 0.0,
"resets_on": "\u2026",
"subscribed": true,
"confirmation_sent": true,
"checkout_open": true,
"signed_in_as": "\u2026",
"onboarded": true,
"plan": "\u2026",
"entitlement": {},
"free_downloads_today": 0
}
Last updated