{"openapi":"3.1.0","info":{"title":"Smart OCR API","description":"The **Smart OCR** by [DHARMA-AI](https://dharma-ai.com) is purpose-trained to extract text, tables, and structured content from digital documents with best-in-class accuracy and speed.\n\n---\n\n## Processing modes\n\n| Mode | Endpoint | Input | Response |\n|------|----------|-------|----------|\n| **Sync** | `POST /v2/ocrs/` | Base64 image (PNG or JPEG) | Extracted text returned immediately |\n| **Async** | `POST /v2/ocr-requests/` | PDF document | Background processing with webhook notification |\n\n## Authentication\n\nSend a Bearer token: either a **Cognito id token** (portal users) or an **API key** (programmatic clients). The backend tells them apart by shape.\n\n| Method | Header | Format |\n|--------|--------|--------|\n| Bearer token | `Authorization` | `Bearer <Cognito id token \\| API key>` |\n| API key header | `X-Api-Key` | `<api_key>` — **DEPRECATED**, use Bearer |\n| HTTP Basic | `Authorization` | `Basic base64(email:password)` — legacy |\n\n## Quick start\n\n1. **Get your credentials** — request an API key from the DHARMA-AI team.\n2. **Choose a mode:**\n   - **Sync** — you already have images (one page at a time, instant response).\n   - **Async** — you have full PDFs (multi-page, background processing with webhook notification).\n3. **Integrate** — point your existing OCR pipeline to this API. It's a drop-in replacement.\n\n## Webhooks\n\nAsynchronous OCR requests support webhook notifications. When a request reaches a terminal status (`completed` or `failed`), an HTTP `POST` is sent to the `webhook_url` you provided at creation time.\n\n**Payload:**\n\n```json\n{\n  \"id\": \"2QPRxyz1234567890abcdefg\",\n  \"type\": \"ocr-request-updated\",\n  \"resource_id\": \"2QPQ1a2b3c4d5e6f7g8h9i0j\",\n  \"resource_type\": \"ocr-requests\",\n  \"created_at\": \"2025-06-15T14:32:15Z\"\n}\n```\n\n| Field | Description |\n|-------|-------------|\n| `id` | Unique identifier for the webhook event |\n| `type` | Always `ocr-request-updated` |\n| `resource_id` | The OCR request ID — use it to call `GET /v2/ocr-requests/{id}` and retrieve the result |\n| `resource_type` | Always `ocr-requests` |\n| `created_at` | Timestamp of the event, UTC ISO 8601 with a `Z` suffix |\n\n**Headers:**\n\n| Header | Value |\n|--------|-------|\n| `Content-Type` | `application/json` |\n| `User-Agent` | `DharmaOCR-Webhook/1.0` |\n| `X-Webhook-Id` | Same as the payload `id` |\n| `X-Webhook-Event` | Same as the payload `type` |\n| `X-Trace-Id` | Trace identifier of the delivery — quote it when contacting support |\n\n**Delivery:**\n\n- Respond with any `2xx` status within **30 seconds** to acknowledge the delivery.\n- Failed deliveries are retried, up to **5 attempts** in total, with exponential backoff (4 to 15 seconds between attempts).\n\n| Outcome | Retried |\n|---------|---------|\n| `2xx` | No — delivered |\n| Timeout or connection error | Yes |\n| `5xx`, `408`, `429` | Yes |\n| Any other `4xx` | No |\n\n- Deliveries can be duplicated: deduplicate on the payload `id` (or the `X-Webhook-Id` header).\n\n## Errors\n\nEvery error response has the same JSON shape:\n\n```json\n{\n  \"detail\": \"Human readable message\",\n  \"code\": \"stable_snake_case_code\",\n  \"request_id\": \"2QPRxyz1234567890abcdefg\"\n}\n```\n\n- Branch on `code` (stable) rather than on `detail` (may change).\n- Every response carries an `X-Request-Id` header with the same value as `request_id`. Send your own `X-Request-Id` to correlate calls, and quote it when contacting support.\n- `429` and `503` responses include a `Retry-After` header (seconds).\n- `422` validation errors add an `errors` list of `{loc, msg, type}`.\n- `402` keeps the legacy `error` and `balance_micro_usd` fields and adds `billing_url`.\n\n## Support\n\nFor questions, onboarding assistance, or custom model training — contact us at [contact@dharma-ai.com](mailto:contact@dharma-ai.com).","version":"2.0.0"},"paths":{"/v2/ocrs/":{"post":{"tags":["OCR Sync v2"],"summary":"Extract text from an image","description":"Submit a Base64-encoded image (PNG or JPEG) and receive the extracted text immediately.\n\nThe response separates the content into `header`, `margin`, `footer`, and `text` fields for structured downstream processing.\n\n**Limits:** PNG or JPEG only (`image/png`, `image/jpeg`; `image/jpg` is accepted as JPEG), up to 20 MB decoded. PDFs are rejected with 415: submit them to `POST /v2/ocr-requests`.\n\nSet `model` to `field-extractor` to get the extracted field values in `fields` instead of text: send a `response_format` `json_schema` to target specific fields, or omit it to extract every labeled field found.\n\nOptional `postprocess_config` enables company-specific post-processing (same shape as async OCR requests).","operationId":"execute_v2_ocrs__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteOCRRequestDTO"},"examples":{"full":{"summary":"Structured text (full)","description":"Default model: returns the image text split into header, margin, footer and body.","value":{"b64image":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...","filename":"contract.png","model":"full"}},"field_extractor_directed":{"summary":"Field extraction with a schema (field-extractor)","description":"Extracts only the fields declared in `response_format.json_schema`; missing fields come back null.","value":{"b64image":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...","filename":"invoice.png","model":"field-extractor","response_format":{"type":"json_schema","json_schema":{"name":"invoice","schema":{"type":"object","properties":{"invoice_number":{"type":"string"},"issue_date":{"type":"string"},"issuer_cnpj":{"type":"string"},"total_amount":{"type":"number"}}}}}}},"field_extractor_general":{"summary":"General field extraction (field-extractor)","description":"Without `response_format`, extracts every labeled field found in the image.","value":{"b64image":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...","filename":"invoice.png","model":"field-extractor"}}}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__ocr__adapter__input__api__v2__dto__ocr_dto__OCRResponseDTO"},"examples":{"full":{"summary":"Structured text (full)","value":{"id":"2QPQ1a2b3c4d5e6f7g8h9i0j","filename":"contract.png","content":{"header":"ACME Corp. — Confidential","footer":"Page 1 of 1","text":"This agreement is entered into by and between the parties listed above..."},"metadata":{"num_pages":1,"total_time":1.23,"failed_pages":[],"truncated_pages":[],"num_input_tokens":1326,"num_output_tokens":1146,"postprocess_input_tokens":0,"postprocess_output_tokens":0}}},"field_extractor":{"summary":"Extracted fields (field-extractor)","description":"`fields` holds the extracted values and `content` is empty.","value":{"id":"2QPQ1a2b3c4d5e6f7g8h9i0j","filename":"invoice.png","content":{},"fields":{"invoice_number":"000123456","issue_date":"2025-06-10","issuer_cnpj":"12.345.678/0001-90","total_amount":1520.75},"metadata":{"num_pages":1,"total_time":1.23,"failed_pages":[],"truncated_pages":[],"num_input_tokens":1326,"num_output_tokens":64,"postprocess_input_tokens":0,"postprocess_output_tokens":0}}}}}}},"401":{"description":"Missing or invalid credentials","headers":{"WWW-Authenticate":{"description":"Authentication scheme (`Bearer`).","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"missing_credentials":{"summary":"No credentials sent","value":{"detail":"Missing credentials. Send your API key or token as `Authorization: Bearer <credential>`.","code":"missing_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_api_key":{"summary":"Unknown, revoked or wrong-type API key","value":{"detail":"Invalid API key.","code":"invalid_api_key","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_credentials":{"summary":"Wrong HTTP Basic email or password (legacy)","value":{"detail":"Invalid email or password.","code":"invalid_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_token":{"summary":"Malformed token or bad signature","value":{"detail":"Invalid authentication token.","code":"invalid_token","request_id":"2QPRxyz1234567890abcdefg"}},"token_expired":{"summary":"Expired token","value":{"detail":"Authentication token has expired. Sign in again.","code":"token_expired","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"403":{"description":"Authenticated but not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"forbidden":{"summary":"Not allowed","value":{"detail":"Forbidden","code":"forbidden","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"422":{"description":"Request schema validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationExceptionResponse"},"example":{"detail":"Validation error","code":"validation_error","request_id":"2QPRxyz1234567890abcdefg","errors":[{"loc":["body","field_name"],"msg":"Field required","type":"missing"}]}}}},"500":{"description":"Unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"internal_error":{"summary":"Unexpected error","value":{"detail":"Unexpected error, please contact support","code":"internal_error","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"402":{"description":"Not enough credits (`insufficient_credits`) or postpaid credit limit reached (`credit_limit_reached`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InsufficientCreditsResponse"},"examples":{"insufficient_credits":{"summary":"Prepaid balance exhausted","value":{"detail":"Your organization has no credits left. Add credits to continue processing documents.","code":"insufficient_credits","request_id":"2QPRxyz1234567890abcdefg","error":"insufficient_credits","balance_micro_usd":0,"billing_url":"https://portal.example.com/billing"}},"credit_limit_reached":{"summary":"Postpaid credit limit reached","value":{"detail":"Your organization has reached its credit limit. Settle the open balance or ask your account manager to raise the limit.","code":"credit_limit_reached","request_id":"2QPRxyz1234567890abcdefg","error":"insufficient_credits","balance_micro_usd":-1000000,"billing_url":"https://portal.example.com/billing"}}}}}},"400":{"description":"The image payload could not be decoded or read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"invalid_base64":{"summary":"Not valid base64","value":{"detail":"The provided base64 string is invalid and could not be decoded.","code":"invalid_base64","request_id":"2QPRxyz1234567890abcdefg"}},"unreadable_image":{"summary":"Decodes but is not a readable image","value":{"detail":"The image could not be read. Make sure it is a valid, uncorrupted PNG or JPEG file.","code":"unreadable_image","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"413":{"description":"The decoded image is larger than the documented maximum","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"payload_too_large":{"summary":"Image too large","value":{"detail":"The image exceeds the maximum size of 20 MB (decoded). Reduce the resolution or compress the image.","code":"payload_too_large","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"415":{"description":"The data URI media type is not a supported image type (PDFs go to `POST /v2/ocr-requests`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"pdf_not_supported":{"summary":"PDF sent to sync OCR","value":{"detail":"PDF documents are not accepted by synchronous OCR. Submit PDFs with POST /v2/ocr-requests, or send each page as a PNG or JPEG image.","code":"unsupported_media_type","request_id":"2QPRxyz1234567890abcdefg"}},"unsupported_image_type":{"summary":"Image type not supported","value":{"detail":"Unsupported image type 'image/tiff'. Supported types: image/png, image/jpeg.","code":"unsupported_media_type","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"502":{"description":"The model or post-processing produced an unusable result; retrying may help","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"model_output_invalid":{"summary":"Unusable model output","value":{"detail":"OCR model produced invalid output after retry attempts. (failed after 3 retries)","code":"model_output_invalid","request_id":"2QPRxyz1234567890abcdefg"}},"postprocess_failed":{"summary":"Post-processing failed","value":{"detail":"The OCR result could not be post-processed. Please retry; contact support if it persists.","code":"postprocess_failed","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"503":{"description":"The OCR model or a dependency is temporarily unavailable; retry after `Retry-After` seconds","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"model_unavailable":{"summary":"Model unavailable or scaling up","value":{"detail":"OCR model inference failed. The service may be temporarily unavailable.","code":"model_unavailable","request_id":"2QPRxyz1234567890abcdefg"}},"service_unavailable":{"summary":"Dependency temporarily failing","value":{"detail":"The OCR result could not be saved. Please retry shortly.","code":"service_unavailable","request_id":"2QPRxyz1234567890abcdefg"}}}}}}},"security":[{"HTTPBearer":[]},{"HTTPBasic":[]}]}},"/v2/ocr-requests/":{"post":{"tags":["OCR Async v2"],"summary":"Submit a PDF for processing","description":"Create a new asynchronous OCR request. The response includes:\n\n- `upload_url` — a pre-signed URL where you must upload your PDF via **HTTP PUT**; it expires 1 hour after creation.\n- `id` — the request identifier, used to check status and retrieve results.\n\nOnce the PDF is uploaded, processing starts automatically. A webhook notification will be sent to the provided `webhook_url` when processing completes or fails (see the **Webhooks** section for the payload format).\n\nSet `model` to `field-extractor` to extract field values instead of text: send a `response_format` `json_schema` to target specific fields, or omit it to extract every labeled field found.","operationId":"create_v2_ocr_requests__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOCRRequestDTO"},"examples":{"full":{"summary":"Structured text (full)","description":"Default model: returns the PDF text split into header, margin, footer and body.","value":{"filename":"contract.pdf","webhook_url":"https://your-server.com/webhooks/ocr","model":"full"}},"field_extractor_directed":{"summary":"Field extraction with a schema (field-extractor)","description":"Extracts only the fields declared in `response_format.json_schema`; missing fields come back null.","value":{"filename":"invoice.pdf","webhook_url":"https://your-server.com/webhooks/ocr","model":"field-extractor","response_format":{"type":"json_schema","json_schema":{"name":"invoice","schema":{"type":"object","properties":{"invoice_number":{"type":"string"},"issue_date":{"type":"string"},"issuer_cnpj":{"type":"string"},"total_amount":{"type":"number"}}}}}}},"field_extractor_general":{"summary":"General field extraction (field-extractor)","description":"Without `response_format`, extracts every labeled field found in the document.","value":{"filename":"invoice.pdf","webhook_url":"https://your-server.com/webhooks/ocr","model":"field-extractor"}}}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOCRResponseDTO"},"examples":{"full":{"summary":"Structured text (full)","value":{"id":"2QPQ1a2b3c4d5e6f7g8h9i0j","status":"queued","upload_url":"https://s3.amazonaws.com/bucket/key?X-Amz-Signature=...","created_at":"2025-06-15T14:30:00Z","updated_at":"2025-06-15T14:30:00Z","webhook_url":"https://your-server.com/webhooks/ocr","model":"full"}},"field_extractor":{"summary":"Field extraction with a schema (field-extractor)","value":{"id":"2QPQ1a2b3c4d5e6f7g8h9i0j","status":"queued","upload_url":"https://s3.amazonaws.com/bucket/key?X-Amz-Signature=...","created_at":"2025-06-15T14:30:00Z","updated_at":"2025-06-15T14:30:00Z","webhook_url":"https://your-server.com/webhooks/ocr","model":"field-extractor","response_format":{"type":"json_schema","json_schema":{"name":"invoice","schema":{"type":"object","properties":{"invoice_number":{"type":"string"},"issue_date":{"type":"string"},"issuer_cnpj":{"type":"string"},"total_amount":{"type":"number"}}}}}}}}}}},"401":{"description":"Missing or invalid credentials","headers":{"WWW-Authenticate":{"description":"Authentication scheme (`Bearer`).","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"missing_credentials":{"summary":"No credentials sent","value":{"detail":"Missing credentials. Send your API key or token as `Authorization: Bearer <credential>`.","code":"missing_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_api_key":{"summary":"Unknown, revoked or wrong-type API key","value":{"detail":"Invalid API key.","code":"invalid_api_key","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_credentials":{"summary":"Wrong HTTP Basic email or password (legacy)","value":{"detail":"Invalid email or password.","code":"invalid_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_token":{"summary":"Malformed token or bad signature","value":{"detail":"Invalid authentication token.","code":"invalid_token","request_id":"2QPRxyz1234567890abcdefg"}},"token_expired":{"summary":"Expired token","value":{"detail":"Authentication token has expired. Sign in again.","code":"token_expired","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"403":{"description":"Authenticated but not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"forbidden":{"summary":"Not allowed","value":{"detail":"Forbidden","code":"forbidden","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"422":{"description":"Request schema validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationExceptionResponse"},"example":{"detail":"Validation error","code":"validation_error","request_id":"2QPRxyz1234567890abcdefg","errors":[{"loc":["body","field_name"],"msg":"Field required","type":"missing"}]}}}},"500":{"description":"Unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"internal_error":{"summary":"Unexpected error","value":{"detail":"Unexpected error, please contact support","code":"internal_error","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"402":{"description":"Not enough credits (`insufficient_credits`) or postpaid credit limit reached (`credit_limit_reached`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InsufficientCreditsResponse"},"examples":{"insufficient_credits":{"summary":"Prepaid balance exhausted","value":{"detail":"Your organization has no credits left. Add credits to continue processing documents.","code":"insufficient_credits","request_id":"2QPRxyz1234567890abcdefg","error":"insufficient_credits","balance_micro_usd":0,"billing_url":"https://portal.example.com/billing"}},"credit_limit_reached":{"summary":"Postpaid credit limit reached","value":{"detail":"Your organization has reached its credit limit. Settle the open balance or ask your account manager to raise the limit.","code":"credit_limit_reached","request_id":"2QPRxyz1234567890abcdefg","error":"insufficient_credits","balance_micro_usd":-1000000,"billing_url":"https://portal.example.com/billing"}}}}}},"429":{"description":"Rate limit exceeded; retry after `Retry-After` seconds","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"detail":"OCR request creation rate limit exceeded. The processing pipeline is at capacity; please reduce submission rate and retry shortly.","code":"rate_limited","request_id":"2QPRxyz1234567890abcdefg"}}}}}}},"security":[{"HTTPBearer":[]},{"HTTPBasic":[]}]}},"/v2/ocr-requests/{id}":{"get":{"tags":["OCR Async v2"],"summary":"Check status or retrieve result","description":"Poll the current status of an asynchronous OCR request.\n\n- **`queued`** — the request is waiting to be processed.\n- **`processing`** — pages are being rasterized and processed.\n- **`completed`** — the result is ready. The `result_url` field contains a pre-signed download URL.\n- **`failed`** — processing failed. `failure_code` is a stable code to branch on (`corrupt_pdf`, `encrypted_pdf`, `upload_not_received`, `processing_timeout`, `internal_error`) and `failure_reason` a human-readable explanation.\n\nResults are retained for 3 days after completion (see `expires_at`); after that this endpoint returns **410** `result_expired` and the document must be resubmitted.","operationId":"get_v2_ocr_requests__id__get","security":[{"HTTPBearer":[]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOCRResponseDTO"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"examples":{"missing_credentials":{"summary":"No credentials sent","value":{"detail":"Missing credentials. Send your API key or token as `Authorization: Bearer <credential>`.","code":"missing_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_api_key":{"summary":"Unknown, revoked or wrong-type API key","value":{"detail":"Invalid API key.","code":"invalid_api_key","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_credentials":{"summary":"Wrong HTTP Basic email or password (legacy)","value":{"detail":"Invalid email or password.","code":"invalid_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_token":{"summary":"Malformed token or bad signature","value":{"detail":"Invalid authentication token.","code":"invalid_token","request_id":"2QPRxyz1234567890abcdefg"}},"token_expired":{"summary":"Expired token","value":{"detail":"Authentication token has expired. Sign in again.","code":"token_expired","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}},"headers":{"WWW-Authenticate":{"description":"Authentication scheme (`Bearer`).","schema":{"type":"string"}}}},"403":{"description":"Authenticated but not allowed","content":{"application/json":{"examples":{"forbidden":{"summary":"Not allowed","value":{"detail":"Forbidden","code":"forbidden","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}}},"422":{"description":"Request schema validation error","content":{"application/json":{"example":{"detail":"Validation error","code":"validation_error","request_id":"2QPRxyz1234567890abcdefg","errors":[{"loc":["body","field_name"],"msg":"Field required","type":"missing"}]},"schema":{"$ref":"#/components/schemas/ValidationExceptionResponse"}}}},"500":{"description":"Unexpected error","content":{"application/json":{"examples":{"internal_error":{"summary":"Unexpected error","value":{"detail":"Unexpected error, please contact support","code":"internal_error","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}}},"404":{"description":"OCR Request not found (or owned by another organization)","content":{"application/json":{"examples":{"ocr_request_not_found":{"summary":"Unknown id","value":{"detail":"OCR Request 2QPQ1a2b3c4d5e6f7g8h9i0j not found","code":"ocr_request_not_found","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}}},"410":{"description":"The result was deleted after the retention period; submit the document again","content":{"application/json":{"examples":{"result_expired":{"summary":"Result past retention","value":{"detail":"OCR Request 2QPQ1a2b3c4d5e6f7g8h9i0j expired. Results are retained for 3 days after completion; submit the document again to reprocess it.","code":"result_expired","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}}},"503":{"description":"Result storage is temporarily unavailable; retry after `Retry-After` seconds","content":{"application/json":{"examples":{"service_unavailable":{"summary":"Storage temporarily failing","value":{"detail":"Result storage is temporarily unavailable. Please retry shortly.","code":"service_unavailable","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}}}}}},"/v2/processings/":{"get":{"tags":["OCR Async v2"],"summary":"List your recent processings","description":"Cursor-paginated history of the caller's processings (newest first), unifying async PDF requests and sync image OCRs. Strictly scoped to the caller's company — you only ever see your own processings. Fetch a `pdf` item's status and result with `GET /v2/ocr-requests/{id}`; sync `image` results are only returned in the original `POST /v2/ocrs` response. Entries older than 3 days are hidden, matching the result retention period.","operationId":"list_recent_v2_processings__get","security":[{"HTTPBearer":[]},{"HTTPBasic":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProcessingPageDTO"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"examples":{"missing_credentials":{"summary":"No credentials sent","value":{"detail":"Missing credentials. Send your API key or token as `Authorization: Bearer <credential>`.","code":"missing_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_api_key":{"summary":"Unknown, revoked or wrong-type API key","value":{"detail":"Invalid API key.","code":"invalid_api_key","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_credentials":{"summary":"Wrong HTTP Basic email or password (legacy)","value":{"detail":"Invalid email or password.","code":"invalid_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_token":{"summary":"Malformed token or bad signature","value":{"detail":"Invalid authentication token.","code":"invalid_token","request_id":"2QPRxyz1234567890abcdefg"}},"token_expired":{"summary":"Expired token","value":{"detail":"Authentication token has expired. Sign in again.","code":"token_expired","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}},"headers":{"WWW-Authenticate":{"description":"Authentication scheme (`Bearer`).","schema":{"type":"string"}}}},"403":{"description":"Authenticated but not allowed","content":{"application/json":{"examples":{"forbidden":{"summary":"Not allowed","value":{"detail":"Forbidden","code":"forbidden","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}}},"422":{"description":"Request schema validation error","content":{"application/json":{"example":{"detail":"Validation error","code":"validation_error","request_id":"2QPRxyz1234567890abcdefg","errors":[{"loc":["body","field_name"],"msg":"Field required","type":"missing"}]},"schema":{"$ref":"#/components/schemas/ValidationExceptionResponse"}}}},"500":{"description":"Unexpected error","content":{"application/json":{"examples":{"internal_error":{"summary":"Unexpected error","value":{"detail":"Unexpected error, please contact support","code":"internal_error","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}}}}}},"/v2/account/balance":{"get":{"tags":["Account"],"summary":"Get credit balance","description":"Returns the credits of the organization that owns the API key (or of the portal user's organization): billing mode, current balance, credit limit (postpaid), what can still be spent and the price per page.\n\nCall it before submitting work to avoid `402` responses. Amounts come both as integers in millionths of `currency` (`*_micro_usd`, the suffix is historical) and as decimal strings. `available_credit_micro_usd` is `null` when spending is unlimited (postpaid without a credit limit).","operationId":"get_balance_v2_account_balance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountBalanceResponseDTO"}}}},"401":{"description":"Missing or invalid credentials","headers":{"WWW-Authenticate":{"description":"Authentication scheme (`Bearer`).","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"missing_credentials":{"summary":"No credentials sent","value":{"detail":"Missing credentials. Send your API key or token as `Authorization: Bearer <credential>`.","code":"missing_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_api_key":{"summary":"Unknown, revoked or wrong-type API key","value":{"detail":"Invalid API key.","code":"invalid_api_key","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_credentials":{"summary":"Wrong HTTP Basic email or password (legacy)","value":{"detail":"Invalid email or password.","code":"invalid_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_token":{"summary":"Malformed token or bad signature","value":{"detail":"Invalid authentication token.","code":"invalid_token","request_id":"2QPRxyz1234567890abcdefg"}},"token_expired":{"summary":"Expired token","value":{"detail":"Authentication token has expired. Sign in again.","code":"token_expired","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"403":{"description":"Authenticated but not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"forbidden":{"summary":"Not allowed","value":{"detail":"Forbidden","code":"forbidden","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"422":{"description":"Request schema validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationExceptionResponse"},"example":{"detail":"Validation error","code":"validation_error","request_id":"2QPRxyz1234567890abcdefg","errors":[{"loc":["body","field_name"],"msg":"Field required","type":"missing"}]}}}},"500":{"description":"Unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"internal_error":{"summary":"Unexpected error","value":{"detail":"Unexpected error, please contact support","code":"internal_error","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"example":{"detail":"Organization 'org-id' not found"}}}}},"security":[{"HTTPBearer":[]},{"HTTPBasic":[]}]}},"/v1/account/me":{"get":{"tags":["Account"],"summary":"Get account information","description":"Returns the company ID and company name associated with the authenticated API key.","operationId":"get_my_account_info_v1_account_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountInfoResponseDTO"}}}},"401":{"description":"Missing or invalid credentials","headers":{"WWW-Authenticate":{"description":"Authentication scheme (`Bearer`).","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"missing_credentials":{"summary":"No credentials sent","value":{"detail":"Missing credentials. Send your API key or token as `Authorization: Bearer <credential>`.","code":"missing_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_api_key":{"summary":"Unknown, revoked or wrong-type API key","value":{"detail":"Invalid API key.","code":"invalid_api_key","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_credentials":{"summary":"Wrong HTTP Basic email or password (legacy)","value":{"detail":"Invalid email or password.","code":"invalid_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_token":{"summary":"Malformed token or bad signature","value":{"detail":"Invalid authentication token.","code":"invalid_token","request_id":"2QPRxyz1234567890abcdefg"}},"token_expired":{"summary":"Expired token","value":{"detail":"Authentication token has expired. Sign in again.","code":"token_expired","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"403":{"description":"Authenticated but not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"forbidden":{"summary":"Not allowed","value":{"detail":"Forbidden","code":"forbidden","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"422":{"description":"Request schema validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationExceptionResponse"},"example":{"detail":"Validation error","code":"validation_error","request_id":"2QPRxyz1234567890abcdefg","errors":[{"loc":["body","field_name"],"msg":"Field required","type":"missing"}]}}}},"500":{"description":"Unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"internal_error":{"summary":"Unexpected error","value":{"detail":"Unexpected error, please contact support","code":"internal_error","request_id":"2QPRxyz1234567890abcdefg"}}}}}}},"security":[{"HTTPBearer":[]},{"HTTPBasic":[]}]}},"/v1/ocrs/":{"post":{"tags":["OCR Sync v1"],"summary":"Extract text from an image","description":"Submit a Base64-encoded image (PNG or JPEG) and receive the extracted text immediately.\n\n**Limits:** PNG or JPEG only (`image/png`, `image/jpeg`; `image/jpg` is accepted as JPEG), up to 20 MB decoded. PDFs are rejected with 415: submit them to `POST /v2/ocr-requests`.\n\nOptional `postprocess_config` enables company-specific post-processing (same shape as async OCR requests).","operationId":"execute_v1_ocrs__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteOCRRequestDTO"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__ocr__adapter__input__api__v1__dto__ocr_dto__OCRResponseDTO"}}}},"401":{"description":"Missing or invalid credentials","headers":{"WWW-Authenticate":{"description":"Authentication scheme (`Bearer`).","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"missing_credentials":{"summary":"No credentials sent","value":{"detail":"Missing credentials. Send your API key or token as `Authorization: Bearer <credential>`.","code":"missing_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_api_key":{"summary":"Unknown, revoked or wrong-type API key","value":{"detail":"Invalid API key.","code":"invalid_api_key","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_credentials":{"summary":"Wrong HTTP Basic email or password (legacy)","value":{"detail":"Invalid email or password.","code":"invalid_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_token":{"summary":"Malformed token or bad signature","value":{"detail":"Invalid authentication token.","code":"invalid_token","request_id":"2QPRxyz1234567890abcdefg"}},"token_expired":{"summary":"Expired token","value":{"detail":"Authentication token has expired. Sign in again.","code":"token_expired","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"403":{"description":"Authenticated but not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"forbidden":{"summary":"Not allowed","value":{"detail":"Forbidden","code":"forbidden","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"422":{"description":"Request schema validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationExceptionResponse"},"example":{"detail":"Validation error","code":"validation_error","request_id":"2QPRxyz1234567890abcdefg","errors":[{"loc":["body","field_name"],"msg":"Field required","type":"missing"}]}}}},"500":{"description":"Unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"internal_error":{"summary":"Unexpected error","value":{"detail":"Unexpected error, please contact support","code":"internal_error","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"402":{"description":"Not enough credits (`insufficient_credits`) or postpaid credit limit reached (`credit_limit_reached`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InsufficientCreditsResponse"},"examples":{"insufficient_credits":{"summary":"Prepaid balance exhausted","value":{"detail":"Your organization has no credits left. Add credits to continue processing documents.","code":"insufficient_credits","request_id":"2QPRxyz1234567890abcdefg","error":"insufficient_credits","balance_micro_usd":0,"billing_url":"https://portal.example.com/billing"}},"credit_limit_reached":{"summary":"Postpaid credit limit reached","value":{"detail":"Your organization has reached its credit limit. Settle the open balance or ask your account manager to raise the limit.","code":"credit_limit_reached","request_id":"2QPRxyz1234567890abcdefg","error":"insufficient_credits","balance_micro_usd":-1000000,"billing_url":"https://portal.example.com/billing"}}}}}},"400":{"description":"The image payload could not be decoded or read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"invalid_base64":{"summary":"Not valid base64","value":{"detail":"The provided base64 string is invalid and could not be decoded.","code":"invalid_base64","request_id":"2QPRxyz1234567890abcdefg"}},"unreadable_image":{"summary":"Decodes but is not a readable image","value":{"detail":"The image could not be read. Make sure it is a valid, uncorrupted PNG or JPEG file.","code":"unreadable_image","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"413":{"description":"The decoded image is larger than the documented maximum","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"payload_too_large":{"summary":"Image too large","value":{"detail":"The image exceeds the maximum size of 20 MB (decoded). Reduce the resolution or compress the image.","code":"payload_too_large","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"415":{"description":"The data URI media type is not a supported image type (PDFs go to `POST /v2/ocr-requests`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"pdf_not_supported":{"summary":"PDF sent to sync OCR","value":{"detail":"PDF documents are not accepted by synchronous OCR. Submit PDFs with POST /v2/ocr-requests, or send each page as a PNG or JPEG image.","code":"unsupported_media_type","request_id":"2QPRxyz1234567890abcdefg"}},"unsupported_image_type":{"summary":"Image type not supported","value":{"detail":"Unsupported image type 'image/tiff'. Supported types: image/png, image/jpeg.","code":"unsupported_media_type","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"502":{"description":"The model or post-processing produced an unusable result; retrying may help","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"model_output_invalid":{"summary":"Unusable model output","value":{"detail":"OCR model produced invalid output after retry attempts. (failed after 3 retries)","code":"model_output_invalid","request_id":"2QPRxyz1234567890abcdefg"}},"postprocess_failed":{"summary":"Post-processing failed","value":{"detail":"The OCR result could not be post-processed. Please retry; contact support if it persists.","code":"postprocess_failed","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"503":{"description":"The OCR model or a dependency is temporarily unavailable; retry after `Retry-After` seconds","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"model_unavailable":{"summary":"Model unavailable or scaling up","value":{"detail":"OCR model inference failed. The service may be temporarily unavailable.","code":"model_unavailable","request_id":"2QPRxyz1234567890abcdefg"}},"service_unavailable":{"summary":"Dependency temporarily failing","value":{"detail":"The OCR result could not be saved. Please retry shortly.","code":"service_unavailable","request_id":"2QPRxyz1234567890abcdefg"}}}}}}},"deprecated":true,"security":[{"HTTPBearer":[]},{"HTTPBasic":[]}]}},"/v1/ocr-requests/":{"post":{"tags":["OCR Async v1"],"summary":"Submit a PDF for processing","description":"Create a new asynchronous OCR request. See **OCR Async v2** for detailed workflow documentation.","operationId":"create_v1_ocr_requests__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOCRRequestDTO"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOCRResponseDTO"}}}},"401":{"description":"Missing or invalid credentials","headers":{"WWW-Authenticate":{"description":"Authentication scheme (`Bearer`).","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"missing_credentials":{"summary":"No credentials sent","value":{"detail":"Missing credentials. Send your API key or token as `Authorization: Bearer <credential>`.","code":"missing_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_api_key":{"summary":"Unknown, revoked or wrong-type API key","value":{"detail":"Invalid API key.","code":"invalid_api_key","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_credentials":{"summary":"Wrong HTTP Basic email or password (legacy)","value":{"detail":"Invalid email or password.","code":"invalid_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_token":{"summary":"Malformed token or bad signature","value":{"detail":"Invalid authentication token.","code":"invalid_token","request_id":"2QPRxyz1234567890abcdefg"}},"token_expired":{"summary":"Expired token","value":{"detail":"Authentication token has expired. Sign in again.","code":"token_expired","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"403":{"description":"Authenticated but not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"forbidden":{"summary":"Not allowed","value":{"detail":"Forbidden","code":"forbidden","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"422":{"description":"Request schema validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationExceptionResponse"},"example":{"detail":"Validation error","code":"validation_error","request_id":"2QPRxyz1234567890abcdefg","errors":[{"loc":["body","field_name"],"msg":"Field required","type":"missing"}]}}}},"500":{"description":"Unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"internal_error":{"summary":"Unexpected error","value":{"detail":"Unexpected error, please contact support","code":"internal_error","request_id":"2QPRxyz1234567890abcdefg"}}}}}},"402":{"description":"Not enough credits (`insufficient_credits`) or postpaid credit limit reached (`credit_limit_reached`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InsufficientCreditsResponse"},"examples":{"insufficient_credits":{"summary":"Prepaid balance exhausted","value":{"detail":"Your organization has no credits left. Add credits to continue processing documents.","code":"insufficient_credits","request_id":"2QPRxyz1234567890abcdefg","error":"insufficient_credits","balance_micro_usd":0,"billing_url":"https://portal.example.com/billing"}},"credit_limit_reached":{"summary":"Postpaid credit limit reached","value":{"detail":"Your organization has reached its credit limit. Settle the open balance or ask your account manager to raise the limit.","code":"credit_limit_reached","request_id":"2QPRxyz1234567890abcdefg","error":"insufficient_credits","balance_micro_usd":-1000000,"billing_url":"https://portal.example.com/billing"}}}}}},"429":{"description":"Rate limit exceeded; retry after `Retry-After` seconds","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"detail":"OCR request creation rate limit exceeded. The processing pipeline is at capacity; please reduce submission rate and retry shortly.","code":"rate_limited","request_id":"2QPRxyz1234567890abcdefg"}}}}}}},"deprecated":true,"security":[{"HTTPBearer":[]},{"HTTPBasic":[]}]}},"/v1/ocr-requests/{id}":{"get":{"tags":["OCR Async v1"],"summary":"Check status or retrieve result","description":"Poll the current status of an asynchronous OCR request. See **OCR Async v2** for status details.","operationId":"get_v1_ocr_requests__id__get","deprecated":true,"security":[{"HTTPBearer":[]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetOCRResponseDTO"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"examples":{"missing_credentials":{"summary":"No credentials sent","value":{"detail":"Missing credentials. Send your API key or token as `Authorization: Bearer <credential>`.","code":"missing_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_api_key":{"summary":"Unknown, revoked or wrong-type API key","value":{"detail":"Invalid API key.","code":"invalid_api_key","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_credentials":{"summary":"Wrong HTTP Basic email or password (legacy)","value":{"detail":"Invalid email or password.","code":"invalid_credentials","request_id":"2QPRxyz1234567890abcdefg"}},"invalid_token":{"summary":"Malformed token or bad signature","value":{"detail":"Invalid authentication token.","code":"invalid_token","request_id":"2QPRxyz1234567890abcdefg"}},"token_expired":{"summary":"Expired token","value":{"detail":"Authentication token has expired. Sign in again.","code":"token_expired","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}},"headers":{"WWW-Authenticate":{"description":"Authentication scheme (`Bearer`).","schema":{"type":"string"}}}},"403":{"description":"Authenticated but not allowed","content":{"application/json":{"examples":{"forbidden":{"summary":"Not allowed","value":{"detail":"Forbidden","code":"forbidden","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}}},"422":{"description":"Request schema validation error","content":{"application/json":{"example":{"detail":"Validation error","code":"validation_error","request_id":"2QPRxyz1234567890abcdefg","errors":[{"loc":["body","field_name"],"msg":"Field required","type":"missing"}]},"schema":{"$ref":"#/components/schemas/ValidationExceptionResponse"}}}},"500":{"description":"Unexpected error","content":{"application/json":{"examples":{"internal_error":{"summary":"Unexpected error","value":{"detail":"Unexpected error, please contact support","code":"internal_error","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}}},"404":{"description":"OCR Request not found (or owned by another organization)","content":{"application/json":{"examples":{"ocr_request_not_found":{"summary":"Unknown id","value":{"detail":"OCR Request 2QPQ1a2b3c4d5e6f7g8h9i0j not found","code":"ocr_request_not_found","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}}},"410":{"description":"The result was deleted after the retention period; submit the document again","content":{"application/json":{"examples":{"result_expired":{"summary":"Result past retention","value":{"detail":"OCR Request 2QPQ1a2b3c4d5e6f7g8h9i0j expired. Results are retained for 3 days after completion; submit the document again to reprocess it.","code":"result_expired","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}}},"503":{"description":"Result storage is temporarily unavailable; retry after `Retry-After` seconds","content":{"application/json":{"examples":{"service_unavailable":{"summary":"Storage temporarily failing","value":{"detail":"Result storage is temporarily unavailable. Please retry shortly.","code":"service_unavailable","request_id":"2QPRxyz1234567890abcdefg"}}},"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}}}}}}},"components":{"schemas":{"AccountBalanceResponseDTO":{"properties":{"org_id":{"type":"string","title":"Org Id","description":"Organization the API key or portal user belongs to"},"billing_mode":{"type":"string","title":"Billing Mode","description":"`prepaid` (spend purchased credits) or `postpaid` (invoiced monthly)"},"currency":{"type":"string","title":"Currency","description":"Currency of every amount in this response"},"balance_micro_usd":{"type":"integer","title":"Balance Micro Usd","description":"Current balance in millionths of `currency` (the `_usd` suffix is historical). Negative for a postpaid org with accrued usage."},"balance":{"type":"string","title":"Balance","description":"`balance_micro_usd` as a decimal string in `currency`, e.g. `25.00`"},"credit_limit_micro_usd":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Credit Limit Micro Usd","description":"Postpaid only: how far below zero the balance may go. Null for prepaid, or postpaid without a limit."},"credit_limit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credit Limit","description":"`credit_limit_micro_usd` as a decimal string"},"available_credit_micro_usd":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Available Credit Micro Usd","description":"What can still be spent before requests are rejected with 402. Null means unlimited."},"available_credit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Available Credit","description":"`available_credit_micro_usd` as a decimal string"},"price_per_page_micro_usd":{"type":"integer","title":"Price Per Page Micro Usd","description":"Price charged per processed page, in millionths of `currency`"},"price_per_page":{"type":"string","title":"Price Per Page","description":"`price_per_page_micro_usd` as a decimal string"}},"type":"object","required":["org_id","billing_mode","currency","balance_micro_usd","balance","credit_limit_micro_usd","credit_limit","available_credit_micro_usd","available_credit","price_per_page_micro_usd","price_per_page"],"title":"AccountBalanceResponseDTO"},"AccountInfoResponseDTO":{"properties":{"company_id":{"type":"string","title":"Company Id"},"company_name":{"type":"string","title":"Company Name"}},"type":"object","required":["company_id","company_name"],"title":"AccountInfoResponseDTO"},"ContentDTO":{"properties":{"header":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Header","description":"Text extracted from the header region of the page."},"margin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Margin","description":"Text extracted from the margin region of the page."},"footer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Footer","description":"Text extracted from the footer region of the page."},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text","description":"Main body text extracted from the page."}},"type":"object","title":"ContentDTO"},"CreateOCRRequestDTO":{"properties":{"filename":{"type":"string","title":"Filename","description":"Name of the PDF file (must end with `.pdf`)."},"webhook_url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Webhook Url","description":"Optional URL that will receive a POST request when processing completes or fails. Omit to disable webhook notifications. See the **Webhooks** section for the payload format."},"params":{"anyOf":[{"$ref":"#/components/schemas/OCRRequestParams"},{"type":"null"}],"description":"Optional extraction parameters (e.g., header/footer/margin width in pixels)."},"model":{"type":"string","enum":["full","field-extractor"],"title":"Model","description":"OCR model to use. `full` for structured text, `field-extractor` to extract field values instead of PDF text: with a `response_format` json_schema it targets those fields (directed), without one it extracts all labeled fields it finds (general).","default":"full"},"response_format":{"anyOf":[{"$ref":"#/components/schemas/ResponseFormat"},{"type":"null"}],"description":"How the response is shaped, mirroring the OpenAI convention. Optional for `field-extractor`: a `json_schema` targets specific fields; omit it for a general field extraction / plain PDF-to-text."},"postprocess_config":{"anyOf":[{"$ref":"#/components/schemas/OCRPostprocessConfig"},{"type":"null"}],"description":"When set, each page is post-processed for the configured company workflow after OCR. `app_name` must be non-blank (workflow key). `company_name` may be null or blank to use the API key company, or a string to target another context. `reference_fields` is arbitrary JSON passed through to the handler. Omit entirely for PDF-to-text only."}},"type":"object","required":["filename"],"title":"CreateOCRRequestDTO"},"CreateOCRResponseDTO":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier for this OCR request."},"status":{"$ref":"#/components/schemas/OCRRequestStatus","description":"Current status of the request. Initially `queued`."},"upload_url":{"type":"string","title":"Upload Url","description":"Pre-signed URL where you must upload your PDF via HTTP PUT (`Content-Type: application/pdf`). It expires 1 hour after creation."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"Timestamp when the request was created (ISO 8601)."},"updated_at":{"type":"string","format":"date-time","title":"Updated At","description":"Timestamp of the last status update (ISO 8601)."},"webhook_url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Webhook Url","description":"The webhook URL that will be notified. Null when no webhook was provided."},"params":{"anyOf":[{"$ref":"#/components/schemas/OCRRequestParams"},{"type":"null"}],"description":"Extraction parameters, if provided."},"model":{"type":"string","title":"Model","description":"OCR model selected for this request.","default":"full"},"response_format":{"anyOf":[{"$ref":"#/components/schemas/ResponseFormat"},{"type":"null"}],"description":"Echo of `response_format` from create when present; null if create omitted it."},"postprocess_config":{"anyOf":[{"$ref":"#/components/schemas/OCRPostprocessConfig"},{"type":"null"}],"description":"Echo of `postprocess_config` from create when present; omitted if create omitted it."},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At","description":"When the result and uploaded files are deleted: 3 days after completion (ISO 8601). Null until the request is `completed`. After that, `GET` returns 410 and the document must be resubmitted."}},"type":"object","required":["id","status","upload_url","created_at","updated_at"],"title":"CreateOCRResponseDTO","examples":[{"created_at":"2025-06-15T14:30:00Z","id":"2QPQ1a2b3c4d5e6f7g8h9i0j","model":"full","postprocess_config":{"app_name":"NFe full","company_name":"CIPA","reference_fields":{}},"status":"queued","updated_at":"2025-06-15T14:30:00Z","upload_url":"https://s3.amazonaws.com/bucket/key?X-Amz-Signature=...","webhook_url":"https://your-server.com/webhooks/ocr"}]},"ExceptionResponse":{"properties":{"detail":{"type":"string","title":"Detail","description":"Human readable, actionable message. Do not parse; use `code` instead."},"code":{"type":"string","title":"Code","description":"Stable snake_case error code, safe to branch on."},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Id","description":"Identifier of this request (same as the `X-Request-Id` header). Quote it when contacting support."}},"type":"object","required":["detail","code"],"title":"ExceptionResponse"},"ExecuteOCRRequestDTO":{"properties":{"b64image":{"type":"string","title":"B64Image","description":"Base64-encoded image as a data URI. Supported formats: PNG and JPEG (`image/png`, `image/jpeg`, `image/jpg`), up to 20 MB decoded. PDFs are not accepted here; use POST /v2/ocr-requests. Example: `data:image/png;base64,iVBORw0KGgo...`"},"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename","description":"Optional original filename, shown in the portal and echoed back in responses. Must be non-blank when provided. Defaults to null (the portal displays `Image`)."},"model":{"type":"string","enum":["full","field-extractor"],"title":"Model","description":"OCR model to use. `full` for structured text, `field-extractor` to extract field values instead of structured text: with a `response_format` json_schema it targets those fields (directed), without one it extracts all labeled fields it finds (general).","default":"full"},"response_format":{"anyOf":[{"$ref":"#/components/schemas/ResponseFormat"},{"type":"null"}],"description":"How the response is shaped, mirroring the OpenAI convention. Optional for `field-extractor`: a `json_schema` targets specific fields; omit it for a general field extraction / plain structured text."},"postprocess_config":{"anyOf":[{"$ref":"#/components/schemas/OCRPostprocessConfig"},{"type":"null"}],"description":"When set, runs company-specific post-OCR handling after extraction. `app_name` must be non-blank (workflow key). `company_name` may be null or blank to use the API key company, or a string to target another context. `reference_fields` is arbitrary JSON passed through to the handler. Omit entirely when only structured text is needed."}},"type":"object","required":["b64image"],"title":"ExecuteOCRRequestDTO"},"ExternalMetadataDTO":{"properties":{"num_pages":{"type":"integer","title":"Num Pages","description":"Total number of pages processed.","default":0},"total_time":{"type":"number","title":"Total Time","description":"Total processing time in seconds.","default":0.0},"failed_pages":{"items":{"type":"integer"},"type":"array","title":"Failed Pages","description":"Page numbers that failed during processing."},"truncated_pages":{"items":{"type":"integer"},"type":"array","title":"Truncated Pages","description":"Page numbers where output was truncated due to length limits."},"num_input_tokens":{"type":"integer","title":"Num Input Tokens","description":"Total input tokens consumed by the OCR model.","default":0},"num_output_tokens":{"type":"integer","title":"Num Output Tokens","description":"Total output tokens generated by the OCR model.","default":0},"postprocess_input_tokens":{"type":"integer","title":"Postprocess Input Tokens","description":"Total input tokens consumed by post-processing (when enabled).","default":0},"postprocess_output_tokens":{"type":"integer","title":"Postprocess Output Tokens","description":"Total output tokens generated by post-processing (when enabled).","default":0}},"type":"object","title":"ExternalMetadataDTO"},"GetOCRResponseDTO":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier for this OCR request."},"status":{"$ref":"#/components/schemas/OCRRequestStatus","description":"Current status: `queued`, `processing`, `completed`, or `failed`."},"webhook_url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Webhook Url","description":"The webhook URL registered for this request. Null when no webhook was provided."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"Timestamp when the request was created (ISO 8601)."},"updated_at":{"type":"string","format":"date-time","title":"Updated At","description":"Timestamp of the last status update (ISO 8601)."},"result_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Result Url","description":"Pre-signed URL to download the extracted JSON result. Only present when status is `completed`."},"metadata":{"anyOf":[{"$ref":"#/components/schemas/ExternalMetadataDTO"},{"type":"null"}],"description":"Processing metadata. Only present when status is `completed`."},"failure_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Reason","description":"Human-readable reason for failure. Only present when status is `failed`."},"failure_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Code","description":"Stable failure code, only present when status is `failed`: `corrupt_pdf`, `encrypted_pdf`, `upload_not_received`, `processing_timeout` or `internal_error`."},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At","description":"When the result and uploaded files are deleted: 3 days after completion (ISO 8601). Null until the request is `completed`. After that, `GET` returns 410 and the document must be resubmitted."},"total_pages":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Pages","description":"Total number of pages detected in the PDF."},"params":{"anyOf":[{"$ref":"#/components/schemas/OCRRequestParams"},{"type":"null"}],"description":"Extraction parameters used for this request."},"processing_started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Processing Started At","description":"Timestamp when processing started (ISO 8601)."},"processing_ended_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Processing Ended At","description":"Timestamp when processing ended (ISO 8601)."},"model":{"type":"string","title":"Model","description":"OCR model used for this request.","default":"full"},"response_format":{"anyOf":[{"$ref":"#/components/schemas/ResponseFormat"},{"type":"null"}],"description":"Echo of `response_format` from create when present; omitted if create omitted it."},"postprocess_config":{"anyOf":[{"$ref":"#/components/schemas/OCRPostprocessConfig"},{"type":"null"}],"description":"Echo of `postprocess_config` from create when present; omitted if create omitted it."}},"type":"object","required":["id","status","created_at","updated_at"],"title":"GetOCRResponseDTO","examples":[{"created_at":"2025-06-15T14:30:00Z","expires_at":"2025-06-18T14:32:15Z","id":"2QPQ1a2b3c4d5e6f7g8h9i0j","metadata":{"failed_pages":[],"num_input_tokens":48200,"num_output_tokens":15300,"num_pages":12,"postprocess_input_tokens":0,"postprocess_output_tokens":0,"total_time":34.5,"truncated_pages":[]},"model":"full","postprocess_config":{"app_name":"NFe full","company_name":"CIPA","reference_fields":{}},"processing_ended_at":"2025-06-15T14:32:15Z","processing_started_at":"2025-06-15T14:30:02Z","result_url":"https://s3.amazonaws.com/bucket/result.json?X-Amz-Signature=...","status":"completed","total_pages":12,"updated_at":"2025-06-15T14:32:15Z","webhook_url":"https://your-server.com/webhooks/ocr"},{"created_at":"2025-06-15T14:30:00Z","failure_code":"corrupt_pdf","failure_reason":"The PDF could not be opened. It may be corrupted or not a valid PDF file; check the file and submit it again.","id":"2QPQ9z8y7x6w5v4u3t2s1r0q","model":"full","processing_ended_at":"2025-06-15T14:30:09Z","processing_started_at":"2025-06-15T14:30:02Z","status":"failed","updated_at":"2025-06-15T14:30:09Z","webhook_url":"https://your-server.com/webhooks/ocr"}]},"InsufficientCreditsResponse":{"properties":{"detail":{"type":"string","title":"Detail","description":"Human readable, actionable message. Do not parse; use `code` instead."},"code":{"type":"string","title":"Code","description":"Stable snake_case error code, safe to branch on."},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Id","description":"Identifier of this request (same as the `X-Request-Id` header). Quote it when contacting support."},"error":{"type":"string","title":"Error","description":"Legacy field, always `insufficient_credits`. Prefer `code`.","default":"insufficient_credits"},"balance_micro_usd":{"type":"integer","title":"Balance Micro Usd","description":"Current organization balance in micro units."},"billing_url":{"type":"string","title":"Billing Url","description":"Portal page where credits can be added."}},"type":"object","required":["detail","code","balance_micro_usd","billing_url"],"title":"InsufficientCreditsResponse"},"JsonSchemaSpec":{"properties":{"name":{"type":"string","title":"Name"},"schema":{"additionalProperties":true,"type":"object","title":"Schema"},"strict":{"type":"boolean","title":"Strict","default":false},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["name","schema"],"title":"JsonSchemaSpec"},"OCRPostprocessConfig":{"properties":{"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name","description":"Optional display or target company name. When omitted, null, or blank, the API key's company name is used for the request row and normalized JSON."},"app_name":{"type":"string","title":"App Name","description":"Application or workflow label for post-processing."},"reference_fields":{"additionalProperties":true,"type":"object","title":"Reference Fields","description":"Arbitrary reference data for downstream post-processing."},"output_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Output Schema","description":"JSON Schema object (with a top-level 'properties' key) that defines which fields to extract from the OCR text. When set with app_name='extract', the generic extraction handler is used instead of a company-specific one."}},"type":"object","required":["app_name"],"title":"OCRPostprocessConfig"},"OCRRequestParams":{"properties":{"header_width":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Header Width","description":"Height of the header region in pixels. Text above this line is extracted separately."},"footer_width":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Footer Width","description":"Height of the footer region in pixels. Text below this line is extracted separately."},"margin_width":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Margin Width","description":"Width of the margin region in pixels. Text within this area is extracted separately."},"alternative_checkbox":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Alternative Checkbox","description":"Enable alternative checkbox detection mode."}},"type":"object","title":"OCRRequestParams"},"OCRRequestStatus":{"type":"string","enum":["queued","processing","completed","failed"],"title":"OCRRequestStatus"},"ProcessingItemDTO":{"properties":{"id":{"type":"string","title":"Id","description":"Identifier. For `pdf` items, fetch status and result with GET /v2/ocr-requests/{id}. Sync `image` results are returned only in the original POST /v2/ocrs response and cannot be re-fetched."},"kind":{"type":"string","enum":["pdf","image"],"title":"Kind","description":"`pdf` = async OCR request; `image` = sync OCR."},"status":{"type":"string","title":"Status","description":"`queued`, `processing`, `completed`, or `failed`. Images are always `completed`."},"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename","description":"Original filename; null when none was provided (portal displays `Image`)."},"total_pages":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Pages","description":"Pages processed/detected."},"model":{"type":"string","title":"Model","description":"OCR model used."},"failure_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Reason","description":"Human-readable reason when status is `failed`."},"failure_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Code","description":"Stable failure code when status is `failed`: `corrupt_pdf`, `encrypted_pdf`, `upload_not_received`, `processing_timeout` or `internal_error`."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"When the processing was created (ISO 8601)."}},"type":"object","required":["id","kind","status","model","created_at"],"title":"ProcessingItemDTO"},"ProcessingPageDTO":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ProcessingItemDTO"},"type":"array","title":"Items"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Pass as `cursor` to fetch the next page; null at the end."}},"type":"object","required":["items"],"title":"ProcessingPageDTO"},"ResponseFormat":{"properties":{"type":{"type":"string","enum":["json_object","json_schema","text"],"title":"Type","default":"json_object"},"json_schema":{"anyOf":[{"$ref":"#/components/schemas/JsonSchemaSpec"},{"type":"null"}]}},"type":"object","title":"ResponseFormat"},"ValidationErrorItem":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Loc","description":"Location of the offending field, e.g. `['body', 'b64image']`."},"msg":{"type":"string","title":"Msg","description":"What is wrong with the field."},"type":{"type":"string","title":"Type","description":"Machine readable error type, e.g. `missing`, `value_error`."}},"type":"object","required":["loc","msg","type"],"title":"ValidationErrorItem"},"ValidationExceptionResponse":{"properties":{"detail":{"type":"string","title":"Detail","description":"Human readable, actionable message. Do not parse; use `code` instead."},"code":{"type":"string","title":"Code","description":"Stable snake_case error code, safe to branch on."},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Id","description":"Identifier of this request (same as the `X-Request-Id` header). Quote it when contacting support."},"errors":{"items":{"$ref":"#/components/schemas/ValidationErrorItem"},"type":"array","title":"Errors"}},"type":"object","required":["detail","code","errors"],"title":"ValidationExceptionResponse"},"app__ocr__adapter__input__api__v1__dto__ocr_dto__OCRResponseDTO":{"properties":{"id":{"type":"string","title":"Id"},"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename","description":"Original filename provided at submission; null when none was sent (portal displays `Image`)."},"text":{"type":"string","title":"Text"},"fields":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Fields","description":"Extracted field values, present only when a field-extraction `model` (e.g. `field-extractor`) was requested. Keys follow the request `response_format` schema; `text` is empty in this case."},"metadata":{"anyOf":[{"$ref":"#/components/schemas/ExternalMetadataDTO"},{"type":"null"}]},"postprocess_config":{"anyOf":[{"$ref":"#/components/schemas/OCRPostprocessConfig"},{"type":"null"}],"description":"Echo of `postprocess_config` from the sync request when present; omitted when the request had none."},"postprocess_content":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Postprocess Content","description":"Structured payload from the post-processing handler when it ran. Omitted when post-processing was not requested or produced no output."}},"type":"object","required":["id","text"],"title":"OCRResponseDTO"},"app__ocr__adapter__input__api__v2__dto__ocr_dto__OCRResponseDTO":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier for this OCR result."},"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename","description":"Original filename provided at submission; null when none was sent (portal displays `Image`)."},"content":{"$ref":"#/components/schemas/ContentDTO","description":"Structured extracted text, separated by page region."},"fields":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Fields","description":"Extracted field values, present only when a field-extraction `model` (e.g. `field-extractor`) was requested. Keys follow the request `response_format` schema; `content` is empty in this case."},"metadata":{"anyOf":[{"$ref":"#/components/schemas/ExternalMetadataDTO"},{"type":"null"}],"description":"Processing metadata."},"postprocess_config":{"anyOf":[{"$ref":"#/components/schemas/OCRPostprocessConfig"},{"type":"null"}],"description":"Echo of post-processing options persisted for this result. Omitted when the sync request was sent without `postprocess_config`."},"postprocess_content":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Postprocess Content","description":"Structured payload from the post-processing handler when it ran. Omitted when post-processing was not requested or produced no output."}},"type":"object","required":["id","content"],"title":"OCRResponseDTO","examples":[{"content":{"footer":"Page 1 of 1","header":"ACME Corp. — Confidential","text":"This agreement is entered into by and between the parties listed above..."},"filename":"contract.png","id":"2QPQ1a2b3c4d5e6f7g8h9i0j","metadata":{"failed_pages":[],"num_input_tokens":1326,"num_output_tokens":1146,"num_pages":1,"postprocess_input_tokens":0,"postprocess_output_tokens":0,"total_time":1.23,"truncated_pages":[]}}]}},"securitySchemes":{"HTTPBearer":{"type":"http","description":"Bearer token: a Cognito id token (portal) or an API key (programmatic clients).","scheme":"bearer"},"HTTPBasic":{"type":"http","description":"HTTP Basic Authentication with email and password (legacy, ocr-playground).","scheme":"basic"}}},"tags":[{"name":"OCR Sync v2","description":"Send a single image and receive the extracted text **immediately** in the same response.\n\n| | |\n|---|---|\n| **Input** | Base64-encoded image (PNG or JPEG) as a data URI — `data:image/png;base64,<data>` or `data:image/jpeg;base64,<data>` |\n| **Response** | Structured content with separated `header`, `margin`, `footer`, and `text` fields |\n| **Best for** | Single-page documents, or pipelines that already convert pages to images |"},{"name":"OCR Async v2","description":"Submit a full PDF document for background processing. The API notifies you via webhook when the result is ready.\n\n**Workflow:**\n\n1. **Create** a request (`POST`) — you receive an `upload_url` (pre-signed S3 URL).\n2. **Upload** your PDF to that URL via `HTTP PUT`.\n3. **Processing** — the API rasterizes each page and runs OCR automatically.\n4. **Notification** — a webhook is sent to your `webhook_url` (see the **Webhooks** section).\n5. **Retrieve** the result (`GET`) — the response includes a `result_url` to download the extracted JSON.\n\n| | |\n|---|---|\n| **Input** | PDF file (uploaded to the pre-signed URL returned at creation) |\n| **Notification** | HTTP POST to your `webhook_url` — see the **Webhooks** section |\n| **Output** | A `result_url` pointing to the extracted text in structured JSON |\n| **Best for** | Multi-page PDF documents where you want to offload all PDF handling to the API |"},{"name":"Account","description":"Retrieve account information for the authenticated API key."},{"name":"OCR Sync v1","description":"**Deprecated** — use **OCR Sync v2** instead. This version will be removed in a future release."},{"name":"OCR Async v1","description":"**Deprecated** — use **OCR Async v2** instead. This version will be removed in a future release."}]}