# Generated by `bun ocr:openapi`; do not edit directly. openapi: 3.1.0 info: title: OpenParser API version: 1.0.0 description: "OpenParser API for document parsing and schema-constrained extraction.\n\nAuthentication uses Eigenpal bearer API keys. The authenticated key resolves\n`tenant_id` server-side; clients must not supply tenant identifiers. API keys must carry\nthe platform wildcard (`*`) or the dedicated `ocr:full` scope. Missing or unrelated\nscopes grant none. Admission requests are rate limited per organization (tenant),\nnot per API key.\n\nEvery parse or extract `POST` requires an `Idempotency-Key` header. Repeating the same tenant, operation,\nand idempotency key returns the same durable job or terminal result. Reusing the key with a\ndifferent request body returns `409`.\n\nParse and file-backed extract admission accepts **either** a direct multipart file upload\n**or** an Eigenpal reusable file-pool id (`file_id` from `POST /files`). Single-document\nextract additionally accepts `parse_job_id`, referencing a tenant-owned succeeded canonical\nparse job; it is mutually exclusive with file bytes and `file_id`. `parse_job_id` is not\naccepted by extract batch items. Arbitrary source URLs and presigned third-party URLs are\nnot accepted. Cross-tenant or unknown `file_id` / `parse_job_id` values return `404`.\nReferenced file bytes are copied into dedicated OCR object storage; OCR admission never\ncreates Eigenpal `files` table rows.\n\nParse and extract operations have **no hidden automatic retry**, **no fallback model**,\n**no hidden repair beyond the explicit `repair_attempts` bound**, and **no chunking or\ntruncation** beyond documented limits.\n\nSynchronous endpoints create durable jobs, wait up to the configured sync wait limit\n(default 300 seconds; deployment-tunable, not a client-selectable hard maximum), and\nreturn the terminal result when ready:\n- `200` with the raw terminal body (`ParsedDocument` for parse; `ExtractionTerminalResult`\n for extract) on success;\n- `422` `ErrorResponse` when the durable job reaches terminal `failed` within the wait\n window (in addition to admission-time unprocessable configuration);\n- `504` `ErrorResponse` when the durable job reaches terminal `indeterminate` within the\n wait window;\n- `202` with a durable job reference if the wait limit expires first.\n\nDisconnecting does not cancel work. Cancellation is not part of this API version.\nAccepted (`202`) responses include a `Location` header that may be an absolute URI or a\npath-absolute relative reference to `GET /jobs/{id}`.\n\n`429` and `503` responses include `Retry-After` with a suggested wait in seconds before\nretrying admission. HTTP `503` is reserved for API admission dependency failures (for\nexample OCR source object upload). Transient GPU/HPS unavailability does **not** reject\nknown-model admission; jobs remain durable and queued until a ready replica and worker\ncapacity exist. Tenant concurrency caps and queue-age alarms bound and observe backlog.\n\n**Billing (customer page charge):** parse and file-backed extract charge **USD $0.001 per\nsuccessfully parsed page** ($1 per 1,000 pages; **0.1 shared-ledger credits per page** at\nthe fixed $0.01/credit presentation unit). The authoritative page count is the HPS/parse\nresult page count recorded on the durable job (`page_count`, derived from the canonical\n`ParsedDocument.pages` length). A single extract admitted with\n`parse_job_id` reuses that document, does not run OCR, and applies **no additional page\ncharge**; its provider-accepted OpenRouter attempts remain billable. No page charge applies\nbefore a successful terminal result is published and made retrievable. A job that terminates as `failed` or `indeterminate` incurs zero page charge, including an extract job that parsed successfully but did not publish a successful extraction result. Client disconnection after admission does not suppress a charge when the durable job later publishes a retrievable\nsuccessful result. Provider-accepted OpenRouter extraction attempts are billed separately\nat the customer retail token rates published by `GET /models/llm` (see `attempts` / `usage`\non `ExtractionTerminalResult`). Catalog `prompt_usd_per_1m` / `completion_usd_per_1m`\nfields are **customer retail** rates (`basis: customer_retail`), not raw provider list\nprices. Batches charge per child job. Page charges use the OCR model's customer retail\n`usd_per_page` (currently $0.001 for PaddleOCR-VL 1.6). Charge keys are idempotent. Credit reserve/refund behavior integrates with\nEigenpal billing and is not embedded in sync parse response bodies.\n\nAdmission does not limit document page count. Other document limits: **50 MiB per file**, **100 million\nrendered pixels per page**, and **100 MiB aggregate batch input** across multipart uploads\nand resolved `file_id` bytes. Reusable file-pool uploads accept up to **100 MiB**. Supported media\ntypes: **PDF**, **PNG**, **JPEG**. Encrypted PDFs are rejected. Archives, SVG, HTML, and other\nformats are rejected.\n" servers: - url: 'https://{ocr_host}' description: Dedicated OCR hostname (environment-specific deployment value) variables: ocr_host: default: api.openparser.dev enum: - api.openparser.dev - sapi.openparser.dev tags: - name: parse description: 'OCR parsing to the versioned `openparser@1` format or opt-in raw provider output' - name: extract description: Parse plus schema-constrained LLM extraction - name: pipelines description: 'Tenant-scoped saved extraction configurations reusable via `pipeline_id`' - name: models description: OCR and LLM model discovery for parse/extract - name: jobs description: Durable job status and results - name: files description: Tenant-scoped reusable input files security: - bearerAuth: [] components: securitySchemes: bearerAuth: type: http scheme: bearer description: Existing Eigenpal API key presented as a bearer token. parameters: IdempotencyKey: name: Idempotency-Key in: header required: true description: "Client-supplied idempotency key. Required on every parse or extract `POST`. Must be unique per distinct\nrequest body for a given tenant and operation.\n" schema: type: string minLength: 1 maxLength: 256 example: 7f9f2f3d-0f8a-4f0a-9a2b-2f6f0a7d2c11 JobId: name: id in: path required: true description: 'Durable OCR job identifier (`opj_…`).' schema: $ref: '#/components/schemas/JobId' FileId: name: id in: path required: true description: Tenant-scoped reusable file identifier. schema: type: string minLength: 1 PipelineId: name: id in: path required: true description: 'Tenant-scoped saved extraction pipeline identifier (`oppl_…`).' schema: $ref: '#/components/schemas/ExtractionPipelineId' ChildCursor: name: cursor in: query required: false description: Opaque pagination cursor for batch child summaries. schema: type: string minLength: 1 ChildLimit: name: limit in: query required: false description: Maximum number of batch child summaries to return. schema: type: integer minimum: 1 maximum: 100 default: 50 JobListCursor: name: cursor in: query required: false description: "Opaque pagination cursor from a prior `JobListResponse.next_cursor`. Jobs are\nreturned newest-first (`created_at` descending, `id` descending tie-break).\n" schema: type: string minLength: 1 JobListLimit: name: limit in: query required: false description: Maximum number of job summaries to return. schema: type: integer minimum: 1 maximum: 100 default: 25 JobListStatus: name: status in: query required: false description: "Optional filter by public job status. Admission-phase (`admitting`) jobs are\nnever listed.\n" schema: $ref: '#/components/schemas/JobStatus' JobListOperation: name: operation in: query required: false description: Optional filter by job operation. schema: $ref: '#/components/schemas/JobOperation' ParseResultFormat: name: format in: query required: false description: "Parse representation to return. Defaults to the job's original `output_format`\nwhen omitted. Fresh parses store both representations as immutable object-store\nartifacts; historical jobs only expose the representation already present in\n`result_json`. Requesting an unavailable alternate returns `422` and never\nre-runs OCR.\n" schema: $ref: '#/components/schemas/OcrOutputFormat' LlmModelsMode: name: mode in: query required: false description: "`suggested` (default): short recommended subset.\n`search`: full compatible catalog filtered by `q`.\n" schema: type: string enum: - suggested - search default: suggested LlmModelsQuery: name: q in: query required: false description: 'Case-insensitive substring match against id, label, or provider. Used with `mode=search`.' schema: type: string maxLength: 200 LlmModelsPage: name: page in: query required: false description: 1-based page index when paginating search results. schema: type: integer minimum: 1 default: 1 LlmModelsLimit: name: limit in: query required: false description: Page size for search; ignored for suggested mode (bounded server-side). schema: type: integer minimum: 1 maximum: 100 default: 25 requestBodies: ParseSingleUpload: required: true content: multipart/form-data: schema: type: object required: - request properties: file: type: string format: binary description: "Source document bytes (PDF, PNG, or JPEG). Required unless `request.file_id`\nreferences an existing Eigenpal reusable file.\n" request: $ref: '#/components/schemas/ParseRequest' encoding: request: contentType: application/json ExtractSingleUpload: required: true content: multipart/form-data: schema: type: object required: - request properties: file: type: string format: binary description: "Source document bytes (PDF, PNG, or JPEG). Required unless `request.file_id`\nreferences an existing Eigenpal reusable file.\n" request: $ref: '#/components/schemas/ExtractRequest' encoding: request: contentType: application/json ParseBatchUpload: required: true content: multipart/form-data: schema: type: object required: - request properties: files: type: array minItems: 1 maxItems: 100 items: type: string format: binary description: "Ordered uploaded files referenced by `file_index` in the batch request. Each file\nis limited to 50 MiB and total multipart body content is limited to 100 MiB.\nOmit when every batch item supplies `file_id` instead.\n" request: $ref: '#/components/schemas/ParseBatchRequest' encoding: files: style: form explode: true request: contentType: application/json ExtractBatchUpload: required: true content: multipart/form-data: schema: type: object required: - request properties: files: type: array minItems: 1 maxItems: 100 items: type: string format: binary description: "Ordered uploaded files referenced by `file_index` in the batch request. Each file\nis limited to 50 MiB and total multipart body content is limited to 100 MiB.\nOmit when every batch item supplies `file_id` instead.\n" request: $ref: '#/components/schemas/ExtractBatchRequest' encoding: files: style: form explode: true request: contentType: application/json SuggestSchemaRequest: required: true content: application/json: schema: $ref: '#/components/schemas/SuggestSchemaRequest' CreateExtractionPipelineRequest: required: true content: application/json: schema: $ref: '#/components/schemas/CreateExtractionPipelineRequest' UpdateExtractionPipelineRequest: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateExtractionPipelineRequest' CreateFileUpload: required: true content: multipart/form-data: schema: type: object additionalProperties: false required: - file properties: file: type: string format: binary responses: JobAccepted: description: "Durable non-terminal job admitted. Returned by async endpoints and by sync endpoints when\nthe wait limit expires before a terminal status.\n" headers: Location: description: "Job resource URL for `GET /jobs/{id}`. May be an absolute URI or a path-absolute\nrelative reference (for example `/jobs/{id}`). Required on accepted (`202`)\nresponses.\n" schema: type: string example: /jobs/opj_7f9f2f3d0f8a4f0a9a2b2f6f0a7d2c11 content: application/json: schema: $ref: '#/components/schemas/JobAccepted' examples: queued: value: id: opj_7f9f2f3d0f8a4f0a9a2b2f6f0a7d2c11 operation: parse status: queued output_format: openparser@1 created_at: 2026-07-17T12:00:00Z updated_at: 2026-07-17T12:00:00Z BatchJobAccepted: description: "Durable batch job admitted. `Location` points at the parent batch job resource.\n" headers: Location: description: "Batch job resource URL for `GET /jobs/{id}`. May be an absolute URI or a\npath-absolute relative reference (for example `/jobs/{id}`). Required on accepted\n(`202`) responses.\n" schema: type: string example: /jobs/opj_b2c3d4e56f7a8901bcdef23456789012 content: application/json: schema: $ref: '#/components/schemas/BatchJobAccepted' examples: queued: value: id: opj_b2c3d4e56f7a8901bcdef23456789012 operation: parse_batch status: queued output_format: openparser@1 created_at: 2026-07-17T12:00:00Z updated_at: 2026-07-17T12:00:00Z child_count: 2 MalformedRequest: description: Malformed request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: malformed: value: error: code: malformed_request message: 'multipart field `request` is not valid JSON' request_id: req_01h2example retryable: false Unauthorized: description: Missing or invalid API key content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: unauthorized: value: error: code: unauthorized message: invalid API key request_id: req_01h2example retryable: false Forbidden: description: 'API key lacks required OCR scope (`*` or `ocr:full`)' content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: forbidden: value: error: code: forbidden message: API key lacks required scope request_id: req_01h2example retryable: false FileNotFound: description: File not found (including cross-tenant identifiers) content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: missing: value: error: code: file_not_found message: file not found request_id: req_01h2example retryable: false InsufficientCredits: description: Billing or credits check failed content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: billing: value: error: code: insufficient_credits message: tenant has insufficient credits for admission request_id: req_01h2example retryable: false IdempotencyConflict: description: Idempotency key reused with a different request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: conflict: value: error: code: idempotency_conflict message: Idempotency-Key was already used with a different request body request_id: req_01h2example retryable: false PipelineNameConflict: description: Pipeline name or slug already exists for the authenticated tenant content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: conflict: value: error: code: pipeline_name_conflict message: pipeline name already exists request_id: req_01h2example retryable: false details: field: name LimitExceeded: description: Document or request limits exceeded content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: bytes: value: error: code: limit_exceeded message: source exceeds 50 MiB admission limit request_id: req_01h2example retryable: false details: limit: max_input_bytes max_value: 52428800 UnsupportedMediaType: description: Unsupported uploaded media type content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: media: value: error: code: unsupported_media_type message: 'only PDF, PNG, and JPEG uploads are accepted' request_id: req_01h2example retryable: false UnprocessableConfig: description: 'Invalid schema, configuration, encrypted PDF, unsupported OCR model, or unsupported LLM model' content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: unsupportedModel: value: error: code: unsupported_ocr_model message: unknown OCR model registry name request_id: req_01h2example retryable: false details: ocr_model: paddleocr-vl-9.9 unsupportedLlmModel: value: error: code: unsupported_llm_model message: unknown or deprecated LLM model request_id: req_01h2example retryable: false details: llm_model: openrouter/free valid_models: - openai/gpt-5.6-terra - openai/gpt-4.1-mini - openai/gpt-4.1 groundingUnsupportedModel: value: error: code: grounding_unsupported_model message: LLM model does not support field grounding request_id: req_01h2example retryable: false details: llm_model: vendor/legacy-extract valid_models: - openai/gpt-5.6-terra - openai/gpt-4.1-mini encryptedPdf: value: error: code: encrypted_pdf message: encrypted PDFs are not supported request_id: req_01h2example retryable: false modelPageLimit: value: error: code: model_page_limit message: google-docai-ocr supports at most 15 PDF pages per document request_id: req_01h2example retryable: false details: ocr_model: google-docai-ocr page_count: 16 max_pages: 15 media_type: application/pdf invalidSchema: value: error: code: invalid_schema message: extraction schema is not supported request_id: req_01h2example retryable: false groundingUnsupportedSchema: value: error: code: grounding_unsupported_schema message: extraction schema cannot be transformed safely for field grounding request_id: req_01h2example retryable: false UnprocessableOrSyncFailed: description: "Admission-time unprocessable configuration/schema/media policy rejection, or (sync\n`POST /parse` and `POST /extract` only) a durable job that reached terminal\n`failed` within the sync wait window. Body is always `ErrorResponse`. Async and batch\nadmissions use `UnprocessableConfig` semantics only; their terminal failures are read\nvia `GET /jobs/{id}`.\n" content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: unsupportedModel: value: error: code: unsupported_ocr_model message: unknown OCR model registry name request_id: req_01h2example retryable: false details: ocr_model: paddleocr-vl-9.9 unsupportedLlmModel: value: error: code: unsupported_llm_model message: unknown or deprecated LLM model request_id: req_01h2example retryable: false details: llm_model: openrouter/free valid_models: - openai/gpt-5.6-terra - openai/gpt-4.1-mini - openai/gpt-4.1 groundingUnsupportedSchema: value: error: code: grounding_unsupported_schema message: extraction schema cannot be transformed safely for field grounding request_id: req_01h2example retryable: false syncFailed: value: error: code: processing_failed message: OCR parse failed request_id: req_01h2example retryable: false SyncTerminalIndeterminate: description: "Sync wait observed a durable job terminal status of `indeterminate` (for example an\nambiguous provider acceptance). Body is `ErrorResponse`. Clients should not assume the\noperation can be safely retried without consulting job and billing state.\n" content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: indeterminate: value: error: code: provider_indeterminate message: job outcome indeterminate request_id: req_01h2example retryable: true RateLimited: description: "Rate or tenant concurrency limit exceeded. Tenant capacity uses\n`tenant_limit_exceeded` when the caller already holds the configured maximum\nof executable non-terminal jobs (`admitting`/`queued`/`running` singles and\nbatch children; batch parents do not count). Idempotent replays of an\nexisting equivalent job are still admitted.\n" headers: Retry-After: description: "Suggested seconds to wait before retrying admission. Present on `429` responses.\n" schema: type: integer minimum: 1 example: 30 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: rate: value: error: code: rate_limited message: request rate limit exceeded request_id: req_01h2example retryable: true tenant: value: error: code: tenant_limit_exceeded message: tenant in-flight job limit exceeded request_id: req_01h2example retryable: true details: limit: 50 current: 50 requested: 1 ServiceUnavailable: description: "API admission dependency failure (for example OCR source object upload to dedicated\nstorage). Transient GPU/HPS unavailability is **not** reported as this response —\nknown registry models remain admissible and jobs stay durable/queued; tenant caps and\nqueue alarms bound/observe backlog.\n" headers: Retry-After: description: "Suggested seconds to wait before retrying admission. Present on `503` responses.\n" schema: type: integer minimum: 1 example: 5 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: sourceUploadFailed: value: error: code: source_upload_failed message: source upload failed request_id: req_01h2example retryable: true JobNotFound: description: Job not found for the authenticated tenant content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: missing: value: error: code: job_not_found message: job not found request_id: req_01h2example retryable: false JobNotTerminal: description: "The parse job exists but is not yet terminal, so a representation body is not\navailable. Poll `GET /jobs/{id}` until `succeeded`, then retry this route.\n" content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: notTerminal: value: error: code: job_not_terminal message: parse job is not terminal yet request_id: req_01h2example retryable: true details: status: running ParseResultUnavailable: description: "The requested parse representation is not available without re-running OCR.\nTypical cases: historical jobs that only stored the originally requested\n`output_format`, non-parse jobs, or failed terminals. Clients should request\nthe available format (see `details.available_format`) or re-admit a new parse.\n" content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: formatUnavailable: value: error: code: result_format_unavailable message: requested parse representation is not available for this job request_id: req_01h2example retryable: false details: requested_format: raw available_format: openparser@1 guidance: 'Re-admit a parse with dual artifacts, or request the available format.' failed: value: error: code: processing_failed message: OCR processing failed. request_id: req_01h2example retryable: false JobSourceUnavailable: description: "Job not found, or retained source bytes are unavailable for the authenticated tenant.\n`job_not_found` covers unknown, malformed, and cross-tenant ids. `source_not_available`\ncovers batch parents, jobs without retained uploads, expired cleanup, and missing storage\nobjects.\n" content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: jobNotFound: value: error: code: job_not_found message: job not found request_id: req_01h2example retryable: false sourceNotAvailable: value: error: code: source_not_available message: job source is not available request_id: req_01h2example retryable: false PartialContent: description: 'Partial retained source bytes for a satisfiable `Range` request.' headers: Accept-Ranges: description: 'Always `bytes` for retained job sources.' schema: type: string const: bytes Content-Range: description: Served byte range and total object size. schema: type: string example: bytes 0-1023/1048576 Content-Type: description: Retained source MIME type. schema: type: string example: application/pdf content: application/octet-stream: schema: type: string format: binary RangeNotSatisfiable: description: Requested byte range is outside the retained source object. headers: Accept-Ranges: description: 'Always `bytes` for retained job sources.' schema: type: string const: bytes Content-Range: description: 'Total object size suffix `bytes */{size}`.' schema: type: string example: bytes */1048576 Content-Type: description: Retained source MIME type. schema: type: string example: application/pdf PipelineNotFound: description: Pipeline not found for the authenticated tenant (also used for deleted or cross-tenant ids) content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: missing: value: error: code: pipeline_not_found message: pipeline not found request_id: req_01h2example retryable: false examples: ParseRequestCanonical: summary: Canonical parse admission JSON value: ocr_model: paddleocr-vl-1.6 output_format: openparser@1 ParsedDocumentInvoice: value: output_format: openparser@1 document_id: doc_01h2example provenance: provider: paddle model: paddleocr-vl-1.6 text: "# Invoice\\n\\nTotal due: $1,234.56" markdown: "# Invoice\n\nTotal due: $1,234.56\n" pages: - number: 1 width: 1700 height: 2200 unit: pixel element_ids: - e0 - e1 reading_order: - e0 - e1 elements: - id: e0 kind: text role: heading text: '# Invoice' spans: [] languages: [] locations: - page_number: 1 bbox: left: 72 top: 48 right: 220 bottom: 92 confidence: score: 0.98 scope: recognition calibrated: false - id: e1 kind: text role: paragraph text: 'Total due: $1,234.56' spans: [] languages: [] locations: - page_number: 1 bbox: left: 72 top: 180 right: 420 bottom: 220 confidence: score: 0.95 scope: recognition calibrated: false text_annotations: [] relations: [] assets: [] RawParseResultPaddle: value: output_format: raw provider: paddle model: paddleocr-vl-1.6 profile: name: eigenpal-paddle-layout-v1 options: image_block_ocr: false chart_recognition: true format_block_content: true use_chart_recognition: true use_ocr_for_image_block: false return_markdown_images: false visualize: false result: layoutParsingResults: - prunedResult: parsing_res_list: [] ExtractionTerminalResultInvoice: value: output: invoice_number: INV-1001 total_due: 1234.56 parsed_document: output_format: openparser@1 document_id: doc_01h2example provenance: provider: paddle model: paddleocr-vl-1.6 text: 'Total due: $1,234.56' markdown: 'Total due: $1,234.56' pages: - number: 1 width: 1700 height: 2200 unit: pixel element_ids: - e0 reading_order: - e0 elements: - id: e0 kind: text role: paragraph text: 'Total due: $1,234.56' spans: [] languages: [] locations: - page_number: 1 bbox: left: 72 top: 180 right: 420 bottom: 220 text_annotations: [] relations: [] assets: [] llm_model: openai/gpt-5.6-terra attempts: - index: 0 kind: primary llm_model: openai/gpt-5.6-terra status: succeeded input_tokens: 1200 output_tokens: 84 cost_usd: 0.0042 usage: input_tokens: 1200 output_tokens: 84 cost_usd: 0.0042 ExtractionTerminalResultGroundedInvoice: value: output: status: paid total_due: null parsed_document: output_format: openparser@1 document_id: doc_01h2grounded provenance: provider: paddle model: paddleocr-vl-1.6 text: 'Status: paid' markdown: 'Status: paid' pages: - number: 1 width: 1700 height: 2200 unit: pixel element_ids: - e0 reading_order: - e0 elements: - id: e0 kind: text role: paragraph text: 'Status: paid' spans: [] languages: [] locations: - page_number: 1 bbox: left: 72 top: 180 right: 420 bottom: 220 text_annotations: [] relations: [] assets: [] llm_model: openai/gpt-5.6-terra attempts: - index: 0 kind: primary llm_model: openai/gpt-5.6-terra status: succeeded input_tokens: 1300 output_tokens: 96 cost_usd: 0.0048 grounding: mode: field fields: - path: status citations: - element_id: e0 page_number: 1 bbox: left: 72 top: 180 right: 420 bottom: 220 source_type: text granularity: element - path: total_due citations: [] dropped_source_ids: - elem-missing JobParseSucceeded: value: id: opj_7f9f2f3d0f8a4f0a9a2b2f6f0a7d2c11 operation: parse status: succeeded output_format: openparser@1 created_at: 2026-07-17T12:00:00Z updated_at: 2026-07-17T12:00:15Z pipeline_id: null pipeline_version: null result: output_format: openparser@1 document_id: doc_01h2example provenance: provider: paddle model: paddleocr-vl-1.6 text: Hello markdown: Hello pages: - number: 1 width: 1000 height: 1400 unit: pixel element_ids: - e0 reading_order: - e0 elements: - id: e0 kind: text role: paragraph text: Hello spans: [] languages: [] locations: - page_number: 1 bbox: left: 72 top: 48 right: 200 bottom: 92 text_annotations: [] relations: [] assets: [] JobBatchRunning: value: id: opj_b2c3d4e56f7a8901bcdef23456789012 operation: parse_batch status: running output_format: openparser@1 created_at: 2026-07-17T12:00:00Z updated_at: 2026-07-17T12:00:05Z pipeline_id: null pipeline_version: null summary: total: 2 queued: 0 running: 1 succeeded: 1 failed: 0 indeterminate: 0 children: items: - client_item_id: a job_id: opj_c3d4e5f678901234abcdef0123456789 file_index: 0 status: succeeded output_format: openparser@1 result: output_format: openparser@1 document_id: doc_a provenance: provider: paddle model: paddleocr-vl-1.6 text: A markdown: A pages: - number: 1 width: 1000 height: 1400 unit: pixel element_ids: - e0 reading_order: - e0 elements: - id: e0 kind: text role: paragraph text: A spans: [] languages: [] locations: - page_number: 1 bbox: left: 72 top: 48 right: 120 bottom: 92 text_annotations: [] relations: [] assets: [] - client_item_id: b job_id: opj_d4e5f6a789012345bcdef01234567890 file_index: 1 status: running output_format: openparser@1 next_cursor: null JobBatchMixed: value: id: opj_b2c3d4e56f7a8901bcdef23456789012 operation: parse_batch status: succeeded output_format: openparser@1 created_at: 2026-07-17T12:00:00Z updated_at: 2026-07-17T12:00:20Z pipeline_id: null pipeline_version: null summary: total: 2 queued: 0 running: 0 succeeded: 1 failed: 1 indeterminate: 0 children: items: - client_item_id: a job_id: opj_c3d4e5f678901234abcdef0123456789 file_index: 0 status: succeeded output_format: openparser@1 result: output_format: openparser@1 document_id: doc_a provenance: provider: paddle model: paddleocr-vl-1.6 text: A markdown: A pages: - number: 1 width: 1000 height: 1400 unit: pixel element_ids: - e0 reading_order: - e0 elements: - id: e0 kind: text role: paragraph text: A spans: [] languages: [] locations: - page_number: 1 bbox: left: 72 top: 48 right: 120 bottom: 92 text_annotations: [] relations: [] assets: [] - client_item_id: b job_id: opj_d4e5f6a789012345bcdef01234567890 file_index: 1 status: failed output_format: openparser@1 error: code: processing_failed message: OCR parse failed retryable: false next_cursor: null schemas: PublicFile: type: object properties: id: type: string filename: type: string contentType: anyOf: - type: string - type: 'null' size: anyOf: - type: integer minimum: 0 maximum: 9007199254740991 - type: 'null' purpose: type: 'null' createdAt: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" required: - id - filename - contentType - size - purpose - createdAt additionalProperties: false JobId: type: string maxLength: 128 pattern: '^opj_[A-Za-z0-9_-]+$' description: 'Prefixed public id for an OCR job (`opj_…`).' example: opj_V1StGXR8_Z5jdHi6B-myT OcrModel: type: string minLength: 1 maxLength: 128 description: "Stable hosted OCR model registry name from `GET /models`. Each catalog entry declares\nits supported `ocr_options`, defaults, current availability, output capabilities, and\nretail page price. Unknown model names return `422 unsupported_ocr_model`.\n" LlmModel: type: string minLength: 1 maxLength: 200 description: "OpenRouter model slug from the compatible OCR extraction catalog\n(`GET /models/llm`). Unknown or deprecated values return `422 unsupported_llm_model`.\nOrdinary extract may use any currently compatible model; field grounding requires a\ncertified model.\n" example: openai/gpt-5.6-terra RepairAttempts: default: 0 type: integer minimum: 0 maximum: 2 description: Explicit schema-repair attempts allowed after a concrete invalid JSON/schema response. JsonSchemaObject: type: object propertyNames: type: string additionalProperties: {} description: Supported JSON Schema object describing the requested extraction output. FileId: type: string minLength: 1 maxLength: 128 pattern: '^[A-Za-z0-9_-]+$' description: "Eigenpal reusable file-pool id from `POST /files`. Resolved with the same\ntenant-scoped authorization as `GET /files/{id}/content`. Missing or\ncross-tenant ids return `404 file_not_found`.\n" ParseRequest: type: object properties: ocr_model: type: string minLength: 1 maxLength: 128 ocr_options: type: object propertyNames: type: string minLength: 1 maxLength: 128 additionalProperties: {} file_id: type: string minLength: 1 maxLength: 128 pattern: '^[A-Za-z0-9_-]+$' output_format: default: openparser@1 type: string enum: - openparser@1 - raw required: - ocr_model additionalProperties: false ExtractRequest: type: object properties: pipeline_id: type: string maxLength: 128 pattern: '^oppl_[A-Za-z0-9_-]+$' description: "Saved extraction pipeline id (`oppl_…`). Inline extraction fields are forbidden.\nAdmission records pipeline id/version provenance and snapshots the effective extraction\nconfiguration; the worker never re-reads the pipeline. With `parse_job_id`, source-parse\nprovenance is recorded separately and the pipeline's OCR settings are not executed.\n" ocr_model: type: string minLength: 1 maxLength: 128 ocr_options: type: object propertyNames: type: string minLength: 1 maxLength: 128 additionalProperties: {} llm_model: type: string minLength: 1 maxLength: 200 llm_options: type: object properties: reasoning_effort: anyOf: - type: string const: auto - type: string enum: - none - minimal - low - medium - high - xhigh - max additionalProperties: false schema: type: object propertyNames: type: string additionalProperties: {} repair_attempts: type: integer minimum: 0 maximum: 2 grounding: type: string enum: - none - field description: "Optional field grounding mode. Defaults to `none` for inline requests. Changing\ngrounding with the same Idempotency-Key returns `409 idempotency_conflict`.\nUnsupported schemas return `422 grounding_unsupported_schema`.\n" file_id: type: string minLength: 1 maxLength: 128 pattern: '^[A-Za-z0-9_-]+$' parse_job_id: type: string maxLength: 128 pattern: '^opj_[A-Za-z0-9_-]+$' description: "Tenant-owned succeeded `parse` job (`opj_…`) whose canonical `openparser@1` ParsedDocument\nis reused. Mutually exclusive with multipart bytes and `file_id`; forbidden in batch.\n" output_format: default: openparser@1 type: string enum: - openparser@1 - raw additionalProperties: false description: "Single extract config. Provide either `pipeline_id` or inline extraction config.\nThe source is exactly one of multipart file bytes, `file_id`, or tenant-owned succeeded\n`parse_job_id`. Parse reuse is single-extract-only, forbids `ocr_model` / `ocr_options`,\ndoes not run OCR, and adds no page charge. `parse_job_id` is part of idempotency identity.\n" SuggestSchemaRequest: type: object properties: parse_job_id: type: string maxLength: 128 pattern: '^opj_[A-Za-z0-9_-]+$' description: 'Prefixed id (`opj_…`) of a succeeded `parse` job in the same tenant.' hint: type: string minLength: 1 maxLength: 500 description: Optional free-text guidance for the suggestion model (max 500 characters). required: - parse_job_id additionalProperties: false description: "Suggest an extraction JSON Schema from a tenant-owned succeeded `parse` job.\nOptional `hint` is caller guidance capped at 500 characters.\n" CreateExtractionPipelineRequest: type: object properties: name: type: string minLength: 1 maxLength: 128 slug: type: string minLength: 1 maxLength: 128 pattern: '^[a-z0-9][a-z0-9_-]*$' ocr_model: type: string minLength: 1 maxLength: 128 ocr_options: type: object propertyNames: type: string minLength: 1 maxLength: 128 additionalProperties: {} llm_model: type: string minLength: 1 maxLength: 200 llm_options: type: object properties: reasoning_effort: anyOf: - type: string const: auto - type: string enum: - none - minimal - low - medium - high - xhigh - max additionalProperties: false schema: type: object propertyNames: type: string additionalProperties: {} description: "JSON Schema object describing fields to extract. Root must be an object schema with\nexplicit `properties` and at least one named property. Admission applies the same\nstrict structured-output normalization as extract.\n" repair_attempts: type: integer minimum: 0 maximum: 2 grounding: type: string enum: - none - field required: - name - ocr_model - llm_model - schema additionalProperties: false description: Create a tenant-scoped saved extraction configuration. UpdateExtractionPipelineRequest: type: object properties: name: type: string minLength: 1 maxLength: 128 slug: anyOf: - type: string minLength: 1 maxLength: 128 pattern: '^[a-z0-9][a-z0-9_-]*$' - type: 'null' ocr_model: type: string minLength: 1 maxLength: 128 ocr_options: anyOf: - type: object propertyNames: type: string minLength: 1 maxLength: 128 additionalProperties: {} - type: 'null' llm_model: type: string minLength: 1 maxLength: 200 llm_options: anyOf: - type: object properties: reasoning_effort: anyOf: - type: string const: auto - type: string enum: - none - minimal - low - medium - high - xhigh - max additionalProperties: false - type: 'null' schema: type: object propertyNames: type: string additionalProperties: {} description: "Replacement extraction schema. Root must be an object schema with explicit `properties`\nand at least one named property. Merged pipeline config is re-validated on every update.\n" repair_attempts: type: integer minimum: 0 maximum: 2 grounding: type: string enum: - none - field additionalProperties: false description: 'Partial update; at least one field required. Successful updates bump `version`.' ExtractionPipeline: type: object properties: id: $ref: '#/components/schemas/ExtractionPipelineId' name: type: string minLength: 1 maxLength: 128 slug: anyOf: - type: string minLength: 1 maxLength: 128 pattern: '^[a-z0-9][a-z0-9_-]*$' - type: 'null' version: type: integer minimum: 1 maximum: 9007199254740991 ocr_model: type: string minLength: 1 maxLength: 128 ocr_options: type: object propertyNames: type: string minLength: 1 maxLength: 128 additionalProperties: {} llm_model: $ref: '#/components/schemas/LlmModel' llm_options: type: object properties: reasoning_effort: anyOf: - anyOf: - type: string const: auto - type: string enum: - none - minimal - low - medium - high - xhigh - max - type: 'null' required: - reasoning_effort additionalProperties: false schema: type: object propertyNames: type: string additionalProperties: {} description: "Persisted extraction schema with at least one root property. Normalized for strict\nstructured outputs at save time.\n" repair_attempts: type: integer minimum: 0 maximum: 2 grounding: $ref: '#/components/schemas/ExtractionGroundingMode' created_at: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" updated_at: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" required: - id - name - slug - version - ocr_model - ocr_options - llm_model - llm_options - schema - repair_attempts - grounding - created_at - updated_at additionalProperties: false description: Public saved extraction pipeline resource. ExtractionPipelineListResponse: type: object properties: items: type: array items: $ref: '#/components/schemas/ExtractionPipeline' required: - items additionalProperties: false description: Active pipelines for the authenticated tenant. DeleteExtractionPipelineResponse: type: object properties: deleted: type: boolean const: true id: $ref: '#/components/schemas/ExtractionPipelineId' required: - deleted - id additionalProperties: false description: Soft-delete acknowledgement. ExtractionPipelineId: type: string maxLength: 128 pattern: '^oppl_[A-Za-z0-9_-]+$' description: 'Prefixed public id for a saved extraction pipeline (`oppl_…`).' ParseBatchItem: type: object properties: client_item_id: type: string minLength: 1 maxLength: 128 description: Caller-supplied stable identifier for this batch item. file_index: type: integer minimum: 0 maximum: 9007199254740991 description: "Zero-based index into the uploaded `files` array. Exactly one of `file_index` or\n`file_id` is required per item.\n" file_id: type: string minLength: 1 maxLength: 128 pattern: '^[A-Za-z0-9_-]+$' ocr_model: type: string minLength: 1 maxLength: 128 ocr_options: type: object propertyNames: type: string minLength: 1 maxLength: 128 additionalProperties: {} required: - client_item_id - ocr_model additionalProperties: false ExtractBatchItem: type: object properties: client_item_id: type: string minLength: 1 maxLength: 128 file_index: type: integer minimum: 0 maximum: 9007199254740991 description: "Zero-based index into the uploaded `files` array. Exactly one of `file_index` or\n`file_id` is required per item.\n" file_id: type: string minLength: 1 maxLength: 128 pattern: '^[A-Za-z0-9_-]+$' pipeline_id: type: string maxLength: 128 pattern: '^oppl_[A-Za-z0-9_-]+$' description: Saved extraction pipeline id; mutually exclusive with inline extract fields. ocr_model: type: string minLength: 1 maxLength: 128 ocr_options: type: object propertyNames: type: string minLength: 1 maxLength: 128 additionalProperties: {} llm_model: type: string minLength: 1 maxLength: 200 llm_options: type: object properties: reasoning_effort: anyOf: - type: string const: auto - type: string enum: - none - minimal - low - medium - high - xhigh - max additionalProperties: false schema: type: object propertyNames: type: string additionalProperties: {} repair_attempts: type: integer minimum: 0 maximum: 2 grounding: type: string enum: - none - field description: "Optional field grounding mode. Defaults to `none`. `field` opts into verified\nper-leaf citations and is part of idempotency identity.\n" required: - client_item_id additionalProperties: false description: "Per-item file-backed extract config with the same `pipeline_id` XOR inline rules as\nsingle extract. Sources are `file_index` or `file_id`; `parse_job_id` is not supported\nin batch. No parent-level batch pipeline in v1.\n" ParseBatchRequest: type: object properties: items: minItems: 1 maxItems: 100 type: array items: type: object properties: client_item_id: type: string minLength: 1 maxLength: 128 file_index: type: integer minimum: 0 maximum: 9007199254740991 file_id: type: string minLength: 1 maxLength: 128 pattern: '^[A-Za-z0-9_-]+$' ocr_model: type: string minLength: 1 maxLength: 128 ocr_options: type: object propertyNames: type: string minLength: 1 maxLength: 128 additionalProperties: {} required: - client_item_id - ocr_model additionalProperties: false description: "Ordered batch items. Each item references either an uploaded `files` entry via\n`file_index` or an Eigenpal reusable `file_id`. Uploaded files must be covered by\nexactly one unique `file_index` in `[0, files.length)`.\n" output_format: default: openparser@1 type: string enum: - openparser@1 - raw required: - items additionalProperties: false ExtractBatchRequest: type: object properties: items: minItems: 1 maxItems: 100 type: array items: type: object properties: client_item_id: type: string minLength: 1 maxLength: 128 file_index: type: integer minimum: 0 maximum: 9007199254740991 file_id: type: string minLength: 1 maxLength: 128 pattern: '^[A-Za-z0-9_-]+$' pipeline_id: type: string maxLength: 128 pattern: '^oppl_[A-Za-z0-9_-]+$' ocr_model: type: string minLength: 1 maxLength: 128 ocr_options: type: object propertyNames: type: string minLength: 1 maxLength: 128 additionalProperties: {} llm_model: type: string minLength: 1 maxLength: 200 llm_options: type: object properties: reasoning_effort: anyOf: - type: string const: auto - type: string enum: - none - minimal - low - medium - high - xhigh - max additionalProperties: false schema: type: object propertyNames: type: string additionalProperties: {} repair_attempts: type: integer minimum: 0 maximum: 2 grounding: type: string enum: - none - field required: - client_item_id additionalProperties: false description: "Ordered batch items. Each item references either an uploaded `files` entry via\n`file_index` or an Eigenpal reusable `file_id`.\n" output_format: default: openparser@1 type: string enum: - openparser@1 - raw required: - items additionalProperties: false OcrOutputFormat: type: string enum: - openparser@1 - raw RawParseResult: type: object properties: output_format: type: string const: raw provider: type: string minLength: 1 maxLength: 128 model: type: string minLength: 1 maxLength: 128 profile: type: object properties: name: type: string minLength: 1 maxLength: 256 options: type: object propertyNames: type: string additionalProperties: {} required: - name - options additionalProperties: false result: type: object propertyNames: type: string additionalProperties: {} required: - output_format - provider - model - profile - result additionalProperties: false ParseResult: anyOf: - $ref: '#/components/schemas/ParsedDocument' - $ref: '#/components/schemas/RawParseResult' JobStatus: type: string enum: - queued - running - succeeded - failed - indeterminate description: "Durable job status. For batch parent jobs, status is derived from children after each\nchild transition:\n1. If any child is non-terminal, the parent remains `queued` only while every child is\n queued; it becomes `running` once any child is running or terminal.\n2. When every child is terminal and any child is `indeterminate`, the parent is\n `indeterminate`.\n3. When every child is terminal, none are `indeterminate`, and any child is `failed`:\n the parent is `failed` if zero children succeeded, otherwise `succeeded` (mixed\n success/failure closes as parent `succeeded` while preserving failed children in\n summaries).\n4. When every child is `succeeded`, the parent is `succeeded`.\n\nPartial failures are always retained on child summaries; parent status does not drop\nfailed children from results.\n" JobOperation: type: string enum: - parse - extract - parse_batch - extract_batch JobAccepted: type: object properties: id: $ref: '#/components/schemas/JobId' operation: type: string enum: - parse - extract status: $ref: '#/components/schemas/JobStatus' output_format: $ref: '#/components/schemas/OcrOutputFormat' created_at: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" updated_at: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" required: - id - operation - status - output_format - created_at - updated_at additionalProperties: false BatchJobAccepted: type: object properties: id: $ref: '#/components/schemas/JobId' operation: type: string enum: - parse_batch - extract_batch status: $ref: '#/components/schemas/JobStatus' output_format: $ref: '#/components/schemas/OcrOutputFormat' created_at: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" updated_at: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" child_count: type: integer minimum: 1 maximum: 100 required: - id - operation - status - output_format - created_at - updated_at - child_count additionalProperties: false Point: type: object properties: x: type: number minimum: 0 'y': type: number minimum: 0 required: - x - 'y' additionalProperties: false BoundingBox: type: object properties: left: type: number minimum: 0 top: type: number minimum: 0 right: type: number exclusiveMinimum: 0 bottom: type: number exclusiveMinimum: 0 required: - left - top - right - bottom additionalProperties: false description: Axis-aligned integer page coordinates with exclusive right and bottom edges. Polygon: minItems: 3 type: array items: $ref: '#/components/schemas/Point' Geometry: type: object properties: page_number: type: integer minimum: 1 maximum: 9007199254740991 bbox: $ref: '#/components/schemas/BoundingBox' polygon: $ref: '#/components/schemas/Polygon' rotation_degrees: type: number minimum: -360 maximum: 360 required: - page_number - bbox additionalProperties: false Confidence: type: object properties: score: type: number minimum: 0 maximum: 1 scope: type: string enum: - detection - recognition - classification - geometry - answer - quality calibrated: default: false type: boolean source_value: type: number source_scale: type: string enum: - zero_to_one - zero_to_hundred - log_probability - unknown required: - score - scope - calibrated additionalProperties: false TextSpan: type: object properties: start: type: integer minimum: 0 maximum: 9007199254740991 end: type: integer exclusiveMinimum: 0 maximum: 9007199254740991 required: - start - end additionalProperties: false Language: type: object properties: code: type: string minLength: 1 maxLength: 64 confidence: $ref: '#/components/schemas/Confidence' required: - code additionalProperties: false TextStyle: type: object properties: font_family: type: string minLength: 1 font_size: type: number exclusiveMinimum: 0 font_size_unit: type: string enum: - pixel - point - inch - em - unknown font_weight: type: integer minimum: 1 maximum: 1000 bold: type: boolean italic: type: boolean underline: type: boolean strikethrough: type: boolean handwritten: type: boolean monospace: type: boolean small_caps: type: boolean superscript: type: boolean subscript: type: boolean foreground_color: type: string minLength: 1 background_color: type: string minLength: 1 additionalProperties: false TextRole: type: string enum: - document_title - heading - paragraph - line - word - symbol - list - list_item - caption - footnote - page_header - page_footer - page_number - code - other SourceProvenance: type: object properties: native_id: type: string minLength: 1 native_type: type: string minLength: 1 native_label: type: string minLength: 1 additionalProperties: false TableCell: type: object properties: id: type: string minLength: 1 row_index: type: integer minimum: 0 maximum: 9007199254740991 column_index: type: integer minimum: 0 maximum: 9007199254740991 row_span: default: 1 type: integer minimum: 1 maximum: 9007199254740991 column_span: default: 1 type: integer minimum: 1 maximum: 9007199254740991 role: default: body type: string enum: - body - column_header - row_header - stub - title - footer text: type: string spans: default: [] type: array items: $ref: '#/components/schemas/TextSpan' locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' element_ids: default: [] type: array items: type: string minLength: 1 required: - id - row_index - column_index - row_span - column_span - role - text - spans - locations - element_ids additionalProperties: false StructuredValue: type: object properties: text: type: string spans: default: [] type: array items: $ref: '#/components/schemas/TextSpan' element_ids: default: [] type: array items: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' required: - text - spans - element_ids - locations additionalProperties: false TextElement: type: object properties: id: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' kind: type: string const: text role: $ref: '#/components/schemas/TextRole' text: type: string spans: default: [] type: array items: $ref: '#/components/schemas/TextSpan' languages: default: [] type: array items: $ref: '#/components/schemas/Language' style: $ref: '#/components/schemas/TextStyle' break_after: $ref: '#/components/schemas/TextBreak' required: - id - locations - kind - role - text - spans - languages additionalProperties: false TableElement: type: object properties: id: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' kind: type: string const: table row_count: type: integer minimum: 0 maximum: 9007199254740991 column_count: type: integer minimum: 0 maximum: 9007199254740991 cells: default: [] type: array items: $ref: '#/components/schemas/TableCell' html: type: string markdown: type: string required: - id - locations - kind - row_count - column_count - cells additionalProperties: false FigureElement: type: object properties: id: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' kind: type: string const: figure asset_id: type: string minLength: 1 caption: type: string caption_spans: default: [] type: array items: $ref: '#/components/schemas/TextSpan' alt_text: type: string required: - id - locations - kind - caption_spans additionalProperties: false FormulaElement: type: object properties: id: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' kind: type: string const: formula value: type: string format: $ref: '#/components/schemas/FormulaFormat' spans: default: [] type: array items: $ref: '#/components/schemas/TextSpan' required: - id - locations - kind - value - format - spans additionalProperties: false KeyValueElement: type: object properties: id: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' kind: type: string const: key_value key: $ref: '#/components/schemas/StructuredValue' value: $ref: '#/components/schemas/StructuredValue' required: - id - locations - kind - key - value additionalProperties: false QueryAnswerElement: type: object properties: id: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' kind: type: string const: query_answer query: $ref: '#/components/schemas/StructuredValue' answer: anyOf: - $ref: '#/components/schemas/StructuredValue' - type: 'null' alias: type: string minLength: 1 required: - id - locations - kind - query - answer additionalProperties: false SectionElement: type: object properties: id: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' kind: type: string const: section role: default: section $ref: '#/components/schemas/SectionRole' title: type: string spans: default: [] type: array items: $ref: '#/components/schemas/TextSpan' required: - id - locations - kind - role - spans additionalProperties: false SelectionMarkElement: type: object properties: id: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' kind: type: string const: selection_mark state: $ref: '#/components/schemas/SelectionState' mark_type: $ref: '#/components/schemas/SelectionMarkType' required: - id - locations - kind - state - mark_type additionalProperties: false SignatureElement: type: object properties: id: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' kind: type: string const: signature text: type: string required: - id - locations - kind additionalProperties: false BarcodeElement: type: object properties: id: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' kind: type: string const: barcode value: type: string symbology: type: string minLength: 1 required: - id - locations - kind - value additionalProperties: false LinkElement: type: object properties: id: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' kind: type: string const: link url: type: string minLength: 1 text: type: string spans: default: [] type: array items: $ref: '#/components/schemas/TextSpan' required: - id - locations - kind - url - spans additionalProperties: false StampElement: type: object properties: id: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' kind: type: string const: stamp text: type: string required: - id - locations - kind additionalProperties: false OtherElement: type: object properties: id: type: string minLength: 1 locations: default: [] type: array items: $ref: '#/components/schemas/Geometry' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' kind: type: string const: other label: type: string minLength: 1 text: type: string required: - id - locations - kind - label additionalProperties: false TextBreak: type: string enum: - none - space - wide_space - hyphen - line_break SectionRole: type: string enum: - section - chapter - group - other DocumentElement: oneOf: - $ref: '#/components/schemas/TextElement' - $ref: '#/components/schemas/TableElement' - $ref: '#/components/schemas/FigureElement' - $ref: '#/components/schemas/FormulaElement' - $ref: '#/components/schemas/KeyValueElement' - $ref: '#/components/schemas/QueryAnswerElement' - $ref: '#/components/schemas/SectionElement' - $ref: '#/components/schemas/SelectionMarkElement' - $ref: '#/components/schemas/SignatureElement' - $ref: '#/components/schemas/BarcodeElement' - $ref: '#/components/schemas/LinkElement' - $ref: '#/components/schemas/StampElement' - $ref: '#/components/schemas/OtherElement' description: "One semantic node in the `openparser@1` document graph. Elements carry typed payloads\n(text, table, figure, and other kinds), optional geometry in `locations`, and stable `id`\nvalues referenced by pages, relations, assets, and grounding citations.\n" DocumentElementKind: type: string enum: - text - table - figure - formula - key_value - query_answer - section - selection_mark - signature - barcode - link - stamp - other TextAnnotation: type: object properties: id: type: string minLength: 1 spans: minItems: 1 type: array items: $ref: '#/components/schemas/TextSpan' languages: default: [] type: array items: $ref: '#/components/schemas/Language' style: $ref: '#/components/schemas/TextStyle' confidence: $ref: '#/components/schemas/Confidence' source: $ref: '#/components/schemas/SourceProvenance' required: - id - spans - languages additionalProperties: false RelationType: type: string enum: - contains - precedes - continuation_of - caption_of - footnote_of - refers_to - overlaps DocumentRelation: type: object properties: type: $ref: '#/components/schemas/RelationType' from_id: type: string minLength: 1 to_id: type: string minLength: 1 required: - type - from_id - to_id additionalProperties: false CoordinateUnit: type: string enum: - pixel - point - inch - normalized DocumentPage: type: object properties: number: type: integer minimum: 1 maximum: 9007199254740991 source_page_number: type: integer minimum: 1 maximum: 9007199254740991 width: type: number exclusiveMinimum: 0 height: type: number exclusiveMinimum: 0 unit: $ref: '#/components/schemas/CoordinateUnit' rotation_degrees: default: 0 type: number minimum: -360 maximum: 360 languages: default: [] type: array items: $ref: '#/components/schemas/Language' confidence: $ref: '#/components/schemas/Confidence' quality: type: object properties: score: $ref: '#/components/schemas/Confidence' defects: default: [] type: array items: type: object properties: type: type: string minLength: 1 confidence: $ref: '#/components/schemas/Confidence' required: - type additionalProperties: false metrics: default: [] type: array items: type: object properties: name: type: string minLength: 1 value: anyOf: - type: number - type: string - type: boolean required: - name - value additionalProperties: false required: - defects - metrics additionalProperties: false image_asset_id: type: string minLength: 1 element_ids: default: [] type: array items: type: string minLength: 1 reading_order: default: [] type: array items: type: string minLength: 1 required: - number - width - height - unit - rotation_degrees - languages - element_ids - reading_order additionalProperties: false AssetKind: type: string enum: - page_image - figure - embedded_image - other DocumentAsset: type: object properties: id: type: string minLength: 1 kind: $ref: '#/components/schemas/AssetKind' uri: type: string minLength: 1 data_base64: type: string minLength: 1 mime_type: type: string minLength: 1 page_number: type: integer minimum: 1 maximum: 9007199254740991 width: type: number exclusiveMinimum: 0 height: type: number exclusiveMinimum: 0 sha256: type: string pattern: '^[0-9a-f]{64}$' required: - id - kind additionalProperties: false DocumentProvenance: type: object properties: provider: type: string minLength: 1 maxLength: 128 model: type: string minLength: 1 maxLength: 128 version: type: string minLength: 1 maxLength: 256 operation: type: string minLength: 1 maxLength: 128 required: - provider - model additionalProperties: false FormulaFormat: type: string enum: - latex - mathml - plain - unknown SelectionState: type: string enum: - selected - unselected - indeterminate SelectionMarkType: type: string enum: - checkbox - radio - other ParsedDocument: type: object properties: output_format: type: string const: openparser@1 document_id: type: string minLength: 1 provenance: $ref: '#/components/schemas/DocumentProvenance' text: type: string markdown: type: string description: Canonical best-effort Markdown rendering derived from the document graph. pages: minItems: 1 type: array items: $ref: '#/components/schemas/DocumentPage' description: One-based contiguous page coordinate spaces with element membership and reading order. elements: default: [] type: array items: $ref: '#/components/schemas/DocumentElement' description: 'Ordered semantic nodes referenced by page membership, relations, and grounding citations.' text_annotations: default: [] type: array items: $ref: '#/components/schemas/TextAnnotation' relations: default: [] type: array items: $ref: '#/components/schemas/DocumentRelation' assets: default: [] type: array items: $ref: '#/components/schemas/DocumentAsset' required: - output_format - document_id - provenance - text - markdown - pages - elements - text_annotations - relations - assets additionalProperties: false description: "Versioned OpenParser `openparser@1` document graph. `pages` establish coordinate spaces;\n`elements` carry semantic payloads and geometry; `relations` preserve hierarchy and\ncross-element meaning; `assets` hold reusable binary references (for example figure URIs).\nCompatible optional fields may be added within version 1; breaking representation changes\ncreate a new output-format version.\n" ExtractionAttemptKind: type: string enum: - primary - repair ExtractionAttemptStatus: type: string enum: - succeeded - failed - indeterminate ExtractionAttempt: type: object properties: index: type: integer minimum: 0 maximum: 9007199254740991 description: Zero-based attempt index in execution order. kind: $ref: '#/components/schemas/ExtractionAttemptKind' llm_model: $ref: '#/components/schemas/LlmModel' status: $ref: '#/components/schemas/ExtractionAttemptStatus' input_tokens: type: integer minimum: 0 maximum: 9007199254740991 output_tokens: type: integer minimum: 0 maximum: 9007199254740991 cost_usd: type: number minimum: 0 description: "Customer retail USD for this attempt (OpenRouter provider cost converted to the\nrates customers are charged). Distinct from the OCR page charge.\n" required: - index - kind - llm_model - status additionalProperties: false ExtractionUsageTotals: type: object properties: input_tokens: type: integer minimum: 0 maximum: 9007199254740991 output_tokens: type: integer minimum: 0 maximum: 9007199254740991 cost_usd: type: number minimum: 0 additionalProperties: false description: "Aggregated customer retail OpenRouter usage for transparency. `cost_usd` is the\ncustomer charge, not raw provider list cost. Distinct from the customer\nUSD $0.001/page (0.1 credits/page) OCR charge recorded by Eigenpal billing.\n" ExtractionGroundingMode: type: string enum: - none - field description: "Extraction grounding mode. `none` preserves ordinary extraction. `field` requests\nverified per-leaf source citations (citation v1 emits element-level citations only).\n" ExtractionCitationGranularity: type: string enum: - element - table_cell - text_span description: "Citation geometry granularity. Citation v1 emits `element` and `table_cell`;\n`text_span` is reserved for a later narrowing release.\n" ExtractionCitation: type: object properties: element_id: type: string minLength: 1 table_cell_id: type: string minLength: 1 page_number: type: integer minimum: 1 maximum: 9007199254740991 bbox: $ref: '#/components/schemas/BoundingBox' polygon: $ref: '#/components/schemas/Polygon' source_type: $ref: '#/components/schemas/DocumentElementKind' granularity: $ref: '#/components/schemas/ExtractionCitationGranularity' confidence: $ref: '#/components/schemas/Confidence' required: - element_id - page_number - bbox - source_type - granularity additionalProperties: false description: 'Verified provenance for one extracted leaf citation. Geometry comes from the parse graph element or table cell, never the model.' ExtractionGroundingField: type: object properties: path: type: string minLength: 1 description: "Dot-separated path from the output root. Array positions are decimal segments.\nProperty names containing dots are outside the field-grounding schema subset.\n" citations: type: array items: $ref: '#/components/schemas/ExtractionCitation' dropped_source_ids: type: array items: type: string minLength: 1 required: - path - citations additionalProperties: false description: "Grounding metadata for one leaf in the unwrapped extraction output. `path` uses\ndot-separated property segments and decimal array-index segments, for example\n`line_items.0.amount`.\n" ExtractionGroundingResult: type: object properties: mode: type: string const: field fields: type: array items: $ref: '#/components/schemas/ExtractionGroundingField' required: - mode - fields additionalProperties: false description: 'Optional terminal grounding envelope present only when `grounding: field` succeeded.' ExtractionTerminalResult: type: object properties: output: description: Validated extraction output JSON matching the requested schema (wrappers never leak). parsed_document: $ref: '#/components/schemas/ParsedDocument' llm_model: $ref: '#/components/schemas/LlmModel' parse_job_id: $ref: '#/components/schemas/JobId' description: Present only when extraction reused this source parse job without running OCR again. reasoning_effort: anyOf: - type: string enum: - none - minimal - low - medium - high - xhigh - max - type: 'null' attempts: minItems: 1 type: array items: $ref: '#/components/schemas/ExtractionAttempt' usage: $ref: '#/components/schemas/ExtractionUsageTotals' grounding: $ref: '#/components/schemas/ExtractionGroundingResult' description: "Present only for successful `grounding: field` jobs. Omitted for ordinary extraction.\n" required: - output - parsed_document - llm_model - attempts additionalProperties: false description: 'Terminal extraction result returned by sync `200` and embedded in succeeded jobs.' SuggestSchemaResponse: type: object properties: name: type: string minLength: 1 maxLength: 200 description: Short document-type label proposed by the model. schema: type: object propertyNames: type: string additionalProperties: {} description: Canonical JSON Schema object ready for extract and manual editing. required: - name - schema additionalProperties: false description: Suggested extraction schema returned directly without creating a durable job. JobFailure: type: object properties: code: type: string minLength: 1 message: type: string minLength: 1 retryable: type: boolean details: type: object propertyNames: type: string additionalProperties: {} required: - code - message - retryable additionalProperties: false BatchChildSummary: type: object properties: client_item_id: type: string minLength: 1 maxLength: 128 job_id: $ref: '#/components/schemas/JobId' file_index: type: integer minimum: 0 maximum: 9007199254740991 status: $ref: '#/components/schemas/JobStatus' output_format: $ref: '#/components/schemas/OcrOutputFormat' error: $ref: '#/components/schemas/JobFailure' result: anyOf: - $ref: '#/components/schemas/ParsedDocument' - $ref: '#/components/schemas/RawParseResult' - $ref: '#/components/schemas/ExtractionTerminalResult' description: 'Terminal child result when `status` is `succeeded`.' required: - client_item_id - job_id - file_index - status - output_format additionalProperties: false BatchChildPage: type: object properties: items: type: array items: $ref: '#/components/schemas/BatchChildSummary' next_cursor: anyOf: - type: string - type: 'null' description: Present when more child summaries are available. required: - items additionalProperties: false BatchSummaryCounts: type: object properties: total: type: integer minimum: 0 maximum: 9007199254740991 queued: type: integer minimum: 0 maximum: 9007199254740991 running: type: integer minimum: 0 maximum: 9007199254740991 succeeded: type: integer minimum: 0 maximum: 9007199254740991 failed: type: integer minimum: 0 maximum: 9007199254740991 indeterminate: type: integer minimum: 0 maximum: 9007199254740991 required: - total - queued - running - succeeded - failed - indeterminate additionalProperties: false Job: type: object properties: id: $ref: '#/components/schemas/JobId' operation: $ref: '#/components/schemas/JobOperation' status: $ref: '#/components/schemas/JobStatus' output_format: $ref: '#/components/schemas/OcrOutputFormat' created_at: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" updated_at: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" progress: type: object properties: completed: type: integer minimum: 0 maximum: 9007199254740991 total: type: integer minimum: 0 maximum: 9007199254740991 additionalProperties: false error: $ref: '#/components/schemas/JobFailure' result: anyOf: - $ref: '#/components/schemas/ParsedDocument' - $ref: '#/components/schemas/RawParseResult' - $ref: '#/components/schemas/ExtractionTerminalResult' description: Terminal result for single-item parse or extract jobs. summary: $ref: '#/components/schemas/BatchSummaryCounts' children: $ref: '#/components/schemas/BatchChildPage' has_source: type: boolean source_media_type: anyOf: - type: string minLength: 1 - type: 'null' source_parse_job_id: anyOf: - $ref: '#/components/schemas/JobId' - type: 'null' related_extractions: type: array items: type: object properties: id: $ref: '#/components/schemas/JobId' status: $ref: '#/components/schemas/JobStatus' created_at: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" updated_at: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" llm_model: anyOf: - type: string minLength: 1 - type: 'null' has_result: type: boolean url: type: string minLength: 1 required: - id - status - created_at - updated_at - has_result - url additionalProperties: false extraction_schema: type: object propertyNames: type: string additionalProperties: {} ocr_model: anyOf: - type: string minLength: 1 - type: 'null' description: "OCR model used at admit time when recorded. Omitted when unknown. Jobs do not\nexpose a durable OCR options snapshot.\n" pipeline_id: anyOf: - $ref: '#/components/schemas/ExtractionPipelineId' - type: 'null' description: "Snapshot of the saved extraction pipeline id at admit time, or `null` for parse jobs,\ninline extract config, and other non-pipeline work.\n" pipeline_version: anyOf: - type: integer minimum: 1 maximum: 9007199254740991 - type: 'null' description: "Snapshot of the saved extraction pipeline version at admit time, or `null` when\n`pipeline_id` is `null`.\n" required: - id - operation - status - output_format - created_at - updated_at - pipeline_id - pipeline_version additionalProperties: false JobSummary: type: object properties: id: $ref: '#/components/schemas/JobId' operation: $ref: '#/components/schemas/JobOperation' status: $ref: '#/components/schemas/JobStatus' output_format: $ref: '#/components/schemas/OcrOutputFormat' ocr_model: anyOf: - type: string minLength: 1 - type: 'null' llm_model: anyOf: - type: string minLength: 1 - type: 'null' page_count: type: integer minimum: 0 maximum: 9007199254740991 created_at: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" updated_at: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" error: $ref: '#/components/schemas/JobFailure' has_result: type: boolean description: 'True when `GET /jobs/{id}` includes a terminal `result`.' url: type: string minLength: 1 description: 'Path-absolute job resource URL (for example `/jobs/{id}`).' has_source: type: boolean pipeline_id: anyOf: - $ref: '#/components/schemas/ExtractionPipelineId' - type: 'null' description: "Snapshot of the saved extraction pipeline id at admit time, or `null` for parse jobs,\ninline extract config, and other non-pipeline work.\n" pipeline_version: anyOf: - type: integer minimum: 1 maximum: 9007199254740991 - type: 'null' description: "Snapshot of the saved extraction pipeline version at admit time, or `null` when\n`pipeline_id` is `null`.\n" required: - id - operation - status - output_format - page_count - created_at - updated_at - has_result - url - pipeline_id - pipeline_version additionalProperties: false description: "Lightweight list row for `GET /jobs`. Omits result bodies, idempotency keys,\nstorage object keys, and provider cost fields.\n" JobListResponse: type: object properties: data: type: array items: $ref: '#/components/schemas/JobSummary' next_cursor: anyOf: - type: string - type: 'null' description: 'Opaque cursor for the next page, or `null` when exhausted.' required: - data - next_cursor additionalProperties: false description: Cursor-paginated page of job summaries for the authenticated tenant. ErrorBody: type: object properties: code: type: string minLength: 1 message: type: string minLength: 1 request_id: type: string minLength: 1 retryable: type: boolean details: type: object propertyNames: type: string additionalProperties: {} required: - code - message - request_id - retryable additionalProperties: false ErrorResponse: type: object properties: error: $ref: '#/components/schemas/ErrorBody' required: - error additionalProperties: false DeleteFileResponse: type: object properties: deleted: type: boolean const: true required: - deleted additionalProperties: false OcrModelCatalogEntry: type: object properties: id: type: string minLength: 1 maxLength: 128 label: type: string minLength: 1 maxLength: 120 is_default: type: boolean provider: type: object properties: key: type: string minLength: 1 maxLength: 64 label: type: string minLength: 1 maxLength: 64 logo: type: string minLength: 1 maxLength: 64 logo_data: type: object properties: title: type: string minLength: 1 maxLength: 64 view_box: type: string minLength: 1 maxLength: 64 paths: minItems: 1 type: array items: type: object properties: d: type: string minLength: 1 clip_rule: type: string enum: - evenodd - nonzero fill_opacity: type: string minLength: 1 maxLength: 16 required: - d additionalProperties: false required: - title - view_box - paths additionalProperties: false required: - key - label additionalProperties: false guidance: type: object properties: summary: type: string minLength: 1 maxLength: 500 best_for: type: string minLength: 1 maxLength: 500 trade_off: type: string minLength: 1 maxLength: 500 output: type: string minLength: 1 maxLength: 500 required: - summary - best_for - trade_off - output additionalProperties: false benchmark: anyOf: - type: object properties: score: type: number version: type: string minLength: 1 maxLength: 120 qualification: type: string minLength: 1 maxLength: 500 source_url: type: string format: uri required: - score - version - qualification - source_url additionalProperties: false - type: 'null' output_summary: type: string minLength: 1 maxLength: 200 capabilities: type: object properties: parse: type: boolean extract_source: type: boolean markdown: type: boolean regions: type: boolean options: type: object propertyNames: type: string minLength: 1 maxLength: 128 additionalProperties: type: boolean required: - parse - extract_source - markdown - regions - options additionalProperties: false option_defaults: type: object propertyNames: type: string minLength: 1 maxLength: 128 additionalProperties: {} option_controls: type: array items: type: object properties: key: type: string minLength: 1 maxLength: 128 label: type: string minLength: 1 maxLength: 120 summary: type: string minLength: 1 maxLength: 500 kind: type: string enum: - boolean - enum - nullable-enum - nullable-string - nullable-string-list choices: type: array items: type: object properties: value: type: string minLength: 1 maxLength: 128 label: type: string minLength: 1 maxLength: 120 required: - value - label additionalProperties: false placeholder: type: string maxLength: 120 nullable_sentinel: type: string minLength: 1 maxLength: 128 required: - key - label - summary - kind additionalProperties: false pricing: type: object properties: usd_per_page: type: number minimum: 0 basis: type: string const: customer_retail configurations: type: array items: type: object properties: label: type: string minLength: 1 maxLength: 160 usd_per_page: type: number minimum: 0 options: type: object propertyNames: type: string minLength: 1 additionalProperties: anyOf: - type: boolean - type: string const: set - type: string const: unset required: - label - usd_per_page - options additionalProperties: false required: - usd_per_page - basis additionalProperties: false availability: type: string enum: - available - degraded - unavailable required: - id - label - is_default - provider - guidance - benchmark - output_summary - capabilities - option_defaults - option_controls - pricing - availability additionalProperties: false description: "Public OCR model registry entry. `pricing.usd_per_page` is the\ncustomer retail page price at option defaults (`basis: customer_retail`).\nOptional `pricing.configurations` lists exact named retail totals for\nprice-affecting option combinations — never additive surcharges." OcrModelsResponse: type: object properties: data: minItems: 1 type: array items: $ref: '#/components/schemas/OcrModelCatalogEntry' required: - data additionalProperties: false description: 'OCR model discovery response for `GET /models/ocr`.' OcrLlmModelCatalogEntry: type: object properties: id: type: string minLength: 1 maxLength: 200 label: type: string minLength: 1 maxLength: 120 provider: type: string minLength: 1 maxLength: 64 created_at: anyOf: - type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - type: 'null' context_length: anyOf: - type: integer exclusiveMinimum: 0 maximum: 9007199254740991 - type: 'null' recommendation: type: string enum: - suggested - compatible is_default: type: boolean certified_grounding: type: boolean certified_suggest: type: boolean supports_grounding: type: boolean supports_suggest: type: boolean pricing_known: type: boolean const: true reasoning: anyOf: - type: object properties: supported_efforts: anyOf: - type: array items: type: string enum: - none - minimal - low - medium - high - xhigh - max - type: 'null' default_effort: anyOf: - type: string enum: - none - minimal - low - medium - high - xhigh - max - type: 'null' mandatory: type: boolean supports_max_tokens: type: boolean required: - supported_efforts - default_effort - mandatory - supports_max_tokens additionalProperties: false - type: 'null' deprecated_at: anyOf: - type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - type: 'null' pricing: type: object properties: prompt_usd_per_1m: type: number minimum: 0 completion_usd_per_1m: type: number minimum: 0 basis: type: string const: customer_retail required: - prompt_usd_per_1m - completion_usd_per_1m - basis additionalProperties: false required: - id - label - provider - created_at - context_length - recommendation - is_default - certified_grounding - certified_suggest - supports_grounding - supports_suggest - pricing_known - reasoning - deprecated_at - pricing additionalProperties: false description: "One compatible extraction LLM. `recommendation` is `suggested` or `compatible`.\n`certified_grounding` / `certified_suggest` (and compatibility aliases\n`supports_grounding` / `supports_suggest`) gate heavier schemas. `pricing` is customer retail USD per 1M tokens\n(`basis: customer_retail`) — the rates customers are charged, not raw provider list cost.\n" OcrLlmModelsResponse: type: object properties: mode: type: string enum: - suggested - search catalog_version: type: string minLength: 1 fetched_at: type: string format: date-time pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" stale: type: boolean data: type: array items: $ref: '#/components/schemas/OcrLlmModelCatalogEntry' page: type: integer minimum: 1 maximum: 9007199254740991 limit: type: integer minimum: 1 maximum: 100 total: type: integer minimum: 0 maximum: 9007199254740991 has_more: type: boolean required: - mode - catalog_version - fetched_at - stale - data - page - limit - total - has_more additionalProperties: false description: "Normalized OpenRouter LLM catalog for OpenParser extraction. Includes catalog version,\nstale flag, and pagination metadata for search mode.\n" paths: /models/ocr: get: operationId: listOcrModels tags: - models summary: List OCR models description: "Returns the hosted OCR model registry with current capabilities, option defaults,\nretail page prices, and availability. Clients should discover this endpoint instead of\nhard-coding model IDs or provider-specific options.\n" responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/OcrModelsResponse' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '429': $ref: '#/components/responses/RateLimited' /models/llm: get: operationId: listLlmModels tags: - models summary: List compatible LLM models description: "Returns a cached, normalized OpenRouter catalog filtered to models that advertise\nstrict structured output (`structured_outputs` + `response_format`), have valid finite\nprovider-list cost (internally) that is converted to customer retail rates, produce text, and are not expired.\n\nDefault `mode=suggested` returns a short recommended subset. `mode=search` discovers the\nfull compatible catalog with optional `q` / pagination. Field grounding and schema\nsuggestion remain restricted to certified models.\n" parameters: - $ref: '#/components/parameters/LlmModelsMode' - $ref: '#/components/parameters/LlmModelsQuery' - $ref: '#/components/parameters/LlmModelsPage' - $ref: '#/components/parameters/LlmModelsLimit' responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/OcrLlmModelsResponse' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '429': $ref: '#/components/responses/RateLimited' /parse: post: operationId: parseSync tags: - parse summary: Parse a document synchronously description: "Admit a parse job, wait up to the sync wait limit, and return the selected terminal parse\nrepresentation when ready. `output_format` defaults to the versioned provider-neutral\n`openparser@1`; `raw` returns a stable provider envelope around the selected provider's\nuntouched successful result. Terminal `failed` within the wait window returns `422`\n`ErrorResponse`; terminal `indeterminate` returns `504` `ErrorResponse`. Returns `202`\nwith a durable job reference and `Location` if the wait limit expires first.\n\nExample (`multipart/form-data`):\n\n```bash\ncurl -X POST 'https://api.openparser.dev/parse' \\\n -H 'Authorization: Bearer YOUR_API_KEY' \\\n -H \"Idempotency-Key: $(uuidgen 2>/dev/null || openssl rand -hex 16)\" \\\n -F 'request={\"ocr_model\":\"paddleocr-vl-1.6\",\"output_format\":\"openparser@1\"};type=application/json' \\\n -F 'file=@./document.pdf'\n```\n" parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: $ref: '#/components/requestBodies/ParseSingleUpload' responses: '200': description: 'Terminal parse result in the selected `openparser@1` or `raw` representation' content: application/json: schema: $ref: '#/components/schemas/ParseResult' examples: invoice: $ref: '#/components/examples/ParsedDocumentInvoice' '202': $ref: '#/components/responses/JobAccepted' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '402': $ref: '#/components/responses/InsufficientCredits' '403': $ref: '#/components/responses/Forbidden' '409': $ref: '#/components/responses/IdempotencyConflict' '413': $ref: '#/components/responses/LimitExceeded' '415': $ref: '#/components/responses/UnsupportedMediaType' '422': $ref: '#/components/responses/UnprocessableOrSyncFailed' '429': $ref: '#/components/responses/RateLimited' '503': $ref: '#/components/responses/ServiceUnavailable' '504': $ref: '#/components/responses/SyncTerminalIndeterminate' /parse/async: post: operationId: parseAsync tags: - parse summary: Parse a document asynchronously description: "Admit a durable parse job and return immediately.\n\nExample (`multipart/form-data`):\n\n```bash\ncurl -X POST 'https://api.openparser.dev/parse/async' \\\n -H 'Authorization: Bearer YOUR_API_KEY' \\\n -H \"Idempotency-Key: $(uuidgen 2>/dev/null || openssl rand -hex 16)\" \\\n -F 'request={\"ocr_model\":\"paddleocr-vl-1.6\",\"output_format\":\"openparser@1\"};type=application/json' \\\n -F 'file=@./document.pdf'\n```\n" parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: $ref: '#/components/requestBodies/ParseSingleUpload' responses: '202': $ref: '#/components/responses/JobAccepted' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '402': $ref: '#/components/responses/InsufficientCredits' '403': $ref: '#/components/responses/Forbidden' '409': $ref: '#/components/responses/IdempotencyConflict' '413': $ref: '#/components/responses/LimitExceeded' '415': $ref: '#/components/responses/UnsupportedMediaType' '422': $ref: '#/components/responses/UnprocessableConfig' '429': $ref: '#/components/responses/RateLimited' '503': $ref: '#/components/responses/ServiceUnavailable' /parse/batch: post: operationId: parseBatch tags: - parse summary: Parse multiple documents in one batch description: "Admit up to 100 parse child jobs in one durable batch. Every uploaded file must be mapped\nexactly once by `file_index`. Partial child failures are preserved in batch results.\nParent status derivation for mixed outcomes is defined on `JobStatus`.\n" parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: $ref: '#/components/requestBodies/ParseBatchUpload' responses: '202': $ref: '#/components/responses/BatchJobAccepted' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '402': $ref: '#/components/responses/InsufficientCredits' '403': $ref: '#/components/responses/Forbidden' '409': $ref: '#/components/responses/IdempotencyConflict' '413': $ref: '#/components/responses/LimitExceeded' '415': $ref: '#/components/responses/UnsupportedMediaType' '422': $ref: '#/components/responses/UnprocessableConfig' '429': $ref: '#/components/responses/RateLimited' '503': $ref: '#/components/responses/ServiceUnavailable' /extract: post: operationId: extractSync tags: - extract summary: Extract structured data synchronously description: "Admit a single extract job from file bytes, `file_id`, or a tenant-owned succeeded\n`parse_job_id`, then run schema-constrained OpenRouter extraction via `llm_model`. A\n`parse_job_id` source reuses the canonical ParsedDocument (from dual artifacts or legacy\n`result_json`) without OCR or another page charge; historical raw-only parses return\n`422 canonical_result_unavailable`. Wait up to the sync wait limit and return\n`ExtractionTerminalResult` when ready. Terminal `failed` within the wait window returns\n`422`; terminal `indeterminate` returns `504`. Returns `202` with a durable job reference\nand `Location` if the wait expires.\n" parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: $ref: '#/components/requestBodies/ExtractSingleUpload' responses: '200': description: Terminal extraction result content: application/json: schema: $ref: '#/components/schemas/ExtractionTerminalResult' examples: invoice: $ref: '#/components/examples/ExtractionTerminalResultInvoice' groundedInvoice: $ref: '#/components/examples/ExtractionTerminalResultGroundedInvoice' '202': $ref: '#/components/responses/JobAccepted' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '402': $ref: '#/components/responses/InsufficientCredits' '403': $ref: '#/components/responses/Forbidden' '409': $ref: '#/components/responses/IdempotencyConflict' '413': $ref: '#/components/responses/LimitExceeded' '415': $ref: '#/components/responses/UnsupportedMediaType' '422': $ref: '#/components/responses/UnprocessableOrSyncFailed' '429': $ref: '#/components/responses/RateLimited' '503': $ref: '#/components/responses/ServiceUnavailable' '504': $ref: '#/components/responses/SyncTerminalIndeterminate' /extract/async: post: operationId: extractAsync tags: - extract summary: Extract structured data asynchronously description: "Admit a durable single extract job from file bytes, `file_id`, or `parse_job_id` and\nreturn immediately. Parse reuse does not run OCR or add a page charge; OpenRouter usage\nremains billable.\n" parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: $ref: '#/components/requestBodies/ExtractSingleUpload' responses: '202': $ref: '#/components/responses/JobAccepted' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '402': $ref: '#/components/responses/InsufficientCredits' '403': $ref: '#/components/responses/Forbidden' '409': $ref: '#/components/responses/IdempotencyConflict' '413': $ref: '#/components/responses/LimitExceeded' '415': $ref: '#/components/responses/UnsupportedMediaType' '422': $ref: '#/components/responses/UnprocessableConfig' '429': $ref: '#/components/responses/RateLimited' '503': $ref: '#/components/responses/ServiceUnavailable' /extract/batch: post: operationId: extractBatch tags: - extract summary: Extract structured data from multiple documents description: "Admit up to 100 file-backed extract child jobs in one durable batch. Every item uses\n`file_index` or `file_id`; `parse_job_id` reuse is single-extract-only and is not accepted\nin batch. Partial child failures are preserved. Parent status derivation follows\n`JobStatus`; billing is evaluated per child.\n" parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: $ref: '#/components/requestBodies/ExtractBatchUpload' responses: '202': $ref: '#/components/responses/BatchJobAccepted' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '402': $ref: '#/components/responses/InsufficientCredits' '403': $ref: '#/components/responses/Forbidden' '409': $ref: '#/components/responses/IdempotencyConflict' '413': $ref: '#/components/responses/LimitExceeded' '415': $ref: '#/components/responses/UnsupportedMediaType' '422': $ref: '#/components/responses/UnprocessableConfig' '429': $ref: '#/components/responses/RateLimited' '503': $ref: '#/components/responses/ServiceUnavailable' /suggest-schema: post: operationId: suggestSchema tags: - extract summary: Suggest an extraction schema description: "Suggest an extraction JSON Schema from a tenant-owned succeeded parse result.\nOptional `hint` is capped at 500 characters. Definitive failures return\n`schema_suggestion_failed`.\n" requestBody: $ref: '#/components/requestBodies/SuggestSchemaRequest' responses: '200': description: Suggested schema content: application/json: schema: $ref: '#/components/schemas/SuggestSchemaResponse' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/JobNotFound' '422': $ref: '#/components/responses/UnprocessableOrSyncFailed' '429': $ref: '#/components/responses/RateLimited' '503': $ref: '#/components/responses/ServiceUnavailable' '504': $ref: '#/components/responses/SyncTerminalIndeterminate' /jobs: get: operationId: listJobs tags: - jobs summary: List jobs description: "Tenant-scoped chronological list of top-level OCR jobs (batch children are omitted).\nReturns lightweight summaries only — full results remain on `GET /jobs/{id}`.\nCursor pagination is stable newest-first with an `id` tie-break. Optional `status`\nand `operation` filters are validated strictly; unknown values return `400`.\n" parameters: - $ref: '#/components/parameters/JobListCursor' - $ref: '#/components/parameters/JobListLimit' - $ref: '#/components/parameters/JobListStatus' - $ref: '#/components/parameters/JobListOperation' responses: '200': description: Page of job summaries content: application/json: schema: $ref: '#/components/schemas/JobListResponse' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '429': $ref: '#/components/responses/RateLimited' '/jobs/{id}': get: operationId: getJob tags: - jobs summary: Get job status and result description: "Tenant-scoped durable job read. Jobs belonging to another tenant return `404`. Batch jobs\ninclude cursor-paginated child summaries. Playground tokens (`ocr:playground`) and `ocr:full`\nkeys are both accepted. Successful parse jobs return the originally requested `output_format`\nin `result`; use `GET /jobs/{id}/result?format=` to select an alternate stored representation\nwithout re-running OCR.\n" parameters: - $ref: '#/components/parameters/JobId' - $ref: '#/components/parameters/ChildCursor' - $ref: '#/components/parameters/ChildLimit' responses: '200': description: 'Job status, progress, and result when available' content: application/json: schema: $ref: '#/components/schemas/Job' examples: parseSucceeded: $ref: '#/components/examples/JobParseSucceeded' batchRunning: $ref: '#/components/examples/JobBatchRunning' batchMixed: $ref: '#/components/examples/JobBatchMixed' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/JobNotFound' '429': $ref: '#/components/responses/RateLimited' '/jobs/{id}/result': get: operationId: getJobResult tags: - jobs summary: Get a parse job result representation description: "Return the selected parse wire body for a tenant-owned succeeded parse job.\n`format` defaults to the job's original `output_format`. Fresh dual-artifact parses\ncan serve either `openparser@1` or `raw` from object storage without re-running HPS\nor charging pages. Historical jobs only serve the representation already present in\n`result_json`; unavailable alternates return `422 result_format_unavailable` with\nguidance. Non-terminal jobs return `409 job_not_terminal`. Playground tokens\n(`ocr:playground`) and `ocr:full` keys are both accepted.\n" parameters: - $ref: '#/components/parameters/JobId' - $ref: '#/components/parameters/ParseResultFormat' responses: '200': description: 'Selected parse representation (`ParsedDocument` or `RawParseResult`)' content: application/json: schema: $ref: '#/components/schemas/ParseResult' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/JobNotFound' '409': $ref: '#/components/responses/JobNotTerminal' '422': $ref: '#/components/responses/ParseResultUnavailable' '429': $ref: '#/components/responses/RateLimited' '504': $ref: '#/components/responses/SyncTerminalIndeterminate' '/jobs/{id}/source': get: operationId: getJobSource tags: - jobs summary: Download retained job source bytes description: "Stream the retained source document for a parse or single-document extract job. Jobs without\nretained source bytes return `404 source_not_available`. Check `has_source` on `GET /jobs/{id}`\nbefore calling. Playground tokens (`ocr:playground`) and `ocr:full` keys are both accepted,\nmatching other job read routes. Optional `Range` requests may return `206` partial content or\n`416` when the range is unsatisfiable.\n" parameters: - $ref: '#/components/parameters/JobId' responses: '200': description: Full retained source document content: application/octet-stream: schema: type: string format: binary '206': $ref: '#/components/responses/PartialContent' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/JobSourceUnavailable' '416': $ref: '#/components/responses/RangeNotSatisfiable' '429': $ref: '#/components/responses/RateLimited' /files: post: operationId: createFile tags: - files summary: Upload a reusable file description: "Upload bytes directly to OpenParser's Eigenpal-compatible tenant file pool. Files may be\nreused by later parse or extract requests through `file_id`; bytes do not pass through\nVercel.\n" requestBody: $ref: '#/components/requestBodies/CreateFileUpload' responses: '200': description: Uploaded reusable file content: application/json: schema: $ref: '#/components/schemas/PublicFile' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '413': $ref: '#/components/responses/LimitExceeded' '415': $ref: '#/components/responses/UnsupportedMediaType' '429': $ref: '#/components/responses/RateLimited' '/files/{id}': get: operationId: getFile tags: - files summary: Get reusable file metadata parameters: - $ref: '#/components/parameters/FileId' responses: '200': description: Reusable file metadata content: application/json: schema: $ref: '#/components/schemas/PublicFile' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/FileNotFound' '429': $ref: '#/components/responses/RateLimited' delete: operationId: deleteFile tags: - files summary: Delete a reusable file parameters: - $ref: '#/components/parameters/FileId' responses: '200': description: File deleted content: application/json: schema: $ref: '#/components/schemas/DeleteFileResponse' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/FileNotFound' '429': $ref: '#/components/responses/RateLimited' '/files/{id}/content': get: operationId: getFileContent tags: - files summary: Download reusable file bytes parameters: - $ref: '#/components/parameters/FileId' responses: '200': description: File content content: application/octet-stream: schema: type: string format: binary '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/FileNotFound' '429': $ref: '#/components/responses/RateLimited' /pipelines: post: operationId: createExtractionPipeline tags: - pipelines summary: Create a saved extraction pipeline description: "Persist a tenant-scoped extraction configuration (OCR model, LLM model, schema,\nrepair/grounding/reasoning). Validated with the same admission gates as extract.\nPlayground tokens and `ocr:full` keys are both accepted.\n" requestBody: $ref: '#/components/requestBodies/CreateExtractionPipelineRequest' responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/ExtractionPipeline' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '409': $ref: '#/components/responses/PipelineNameConflict' '422': $ref: '#/components/responses/UnprocessableConfig' '429': $ref: '#/components/responses/RateLimited' get: operationId: listExtractionPipelines tags: - pipelines summary: List saved extraction pipelines description: "Return active (non-deleted) pipelines for the authenticated tenant, newest updates first.\n" responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/ExtractionPipelineListResponse' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '429': $ref: '#/components/responses/RateLimited' '/pipelines/{id}': get: operationId: getExtractionPipeline tags: - pipelines summary: Get a saved extraction pipeline description: "Return one active pipeline. Missing, deleted, and cross-tenant ids return\n`404 pipeline_not_found`.\n" parameters: - $ref: '#/components/parameters/PipelineId' responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/ExtractionPipeline' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/PipelineNotFound' '429': $ref: '#/components/responses/RateLimited' patch: operationId: updateExtractionPipeline tags: - pipelines summary: Update a saved extraction pipeline description: "Patch one or more fields, re-validate the effective merged config, and atomically\nincrement `version`. In-flight and completed jobs keep their admit-time snapshots.\n" parameters: - $ref: '#/components/parameters/PipelineId' requestBody: $ref: '#/components/requestBodies/UpdateExtractionPipelineRequest' responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/ExtractionPipeline' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/PipelineNotFound' '409': $ref: '#/components/responses/PipelineNameConflict' '422': $ref: '#/components/responses/UnprocessableConfig' '429': $ref: '#/components/responses/RateLimited' delete: operationId: deleteExtractionPipeline tags: - pipelines summary: Soft-delete a saved extraction pipeline description: "Marks the pipeline deleted. Subsequent extract admits with that id return\n`404 pipeline_not_found`. Historical jobs retain snapshotted config.\n" parameters: - $ref: '#/components/parameters/PipelineId' responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/DeleteExtractionPipelineResponse' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/PipelineNotFound' '429': $ref: '#/components/responses/RateLimited'