# 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' UpdateExtractionReviewRequest: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateExtractionReviewRequest' CompleteExtractionReviewRequest: required: true content: application/json: schema: $ref: '#/components/schemas/CompleteExtractionReviewRequest' ReopenExtractionReviewRequest: required: true content: application/json: schema: $ref: '#/components/schemas/ReopenExtractionReviewRequest' 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 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 signed_on: 2025-05-20 parsed_document: output_format: openparser@1 document_id: doc_01h2grounded provenance: provider: paddle model: paddleocr-vl-1.6 text: 'Status: paid. Signed this 20 day of May 2025' markdown: 'Status: paid. Signed this 20 day of May 2025' pages: - number: 1 width: 1700 height: 2200 unit: pixel element_ids: - e0 - e1 reading_order: - e0 - e1 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 - id: e1 kind: text role: paragraph text: Signed this 20 day of May 2025 spans: [] languages: [] locations: - page_number: 1 bbox: left: 72 top: 240 right: 520 bottom: 280 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 - path: signed_on quote: 20 day of May 2025 confidence: 0.92 citations: - element_id: e1 page_number: 1 bbox: left: 72 top: 240 right: 520 bottom: 280 source_type: text granularity: element lineage: format: lineage@1 profiles: - https://docs.openparser.dev/lineage/openparser entities: document:source: kind: artifact locator: uri: urn:openparser:source:doc_01h2example document:parsed: kind: artifact locator: uri: urn:openparser:document:doc_01h2example mediaType: application/vnd.openparser.document+json attributes: openparser:outputFormat: openparser@1 source-element:e0: kind: collection value: 'Status: paid' locator: uri: urn:openparser:document:doc_01h2example mediaType: application/vnd.openparser.document+json selector: type: openparser.document-region value: elementId: e0 pageNumber: 1 bbox: left: 72 top: 180 right: 420 bottom: 220 sourceType: text geometryGranularity: element confidence: - score: 0.91 scale: min: 0 max: 1 kind: derived scope: recognition_source_region granularity: word calibrated: false method: region_word_minimum sampleCount: 2 sources: - type: activity id: activity:ocr attributes: minimum: 0.91 maximum: 0.99 regionMean: 0.95 field:/status: kind: decision path: /status value: paid confidence: - score: 0.97 scale: min: 0 max: 1 kind: derived scope: extraction calibrated: false method: source_text_alignment sources: - type: activity id: activity:extract attributes: openparser:alignmentStatus: match_exact field:/total_due: kind: decision path: /total_due value: null source-element:e1: kind: collection value: Signed this 20 day of May 2025 locator: uri: urn:openparser:document:doc_01h2example mediaType: application/vnd.openparser.document+json selector: type: openparser.document-region value: elementId: e1 pageNumber: 1 bbox: left: 72 top: 240 right: 520 bottom: 280 sourceType: text geometryGranularity: element source-text:/signed_on: kind: value value: 20 day of May 2025 confidence: - score: 0.94 scale: min: 0 max: 1 kind: derived scope: extraction calibrated: false method: source_text_alignment sources: - type: activity id: activity:extract attributes: openparser:alignmentStatus: match_exact field:/signed_on: kind: decision path: /signed_on value: 2025-05-20 confidence: - score: 0.92 scale: min: 0 max: 1 kind: reported scope: extraction calibrated: false sources: - type: activity id: activity:transform activities: activity:ocr: type: ocr status: ended associations: - agent: agent:ocr-model role: model activity:extract: type: extract status: ended associations: - agent: agent:extraction-model role: model activity:transform: type: transform status: ended associations: - agent: agent:extraction-model role: model attributes: openparser:implicit: true agents: agent:ocr-model: type: model name: paddleocr-vl-1.6 agent:extraction-model: type: model name: openai/gpt-5.6-terra derivations: - output: document:parsed activity: activity:ocr inputs: - entity: document:source role: document effect: direct transformation: type: transformation - output: source-element:e0 activity: activity:ocr inputs: - entity: document:parsed role: parsed_document effect: direct transformation: type: filter - output: field:/status activity: activity:extract inputs: - entity: document:parsed role: parsed_document effect: direct - entity: source-element:e0 role: resolved_source_evidence effect: direct confidence: score: 0.98 scale: min: 0 max: 1 kind: derived scope: recognition_source_region granularity: word calibrated: false method: cited_minimum_context_downblend sampleCount: 1 sources: - type: activity id: activity:ocr attributes: minimum: 0.99 maximum: 0.99 contextMean: 0.91 contextSampleCount: 1 transformation: type: transformation - output: field:/total_due activity: activity:extract inputs: - entity: document:parsed role: parsed_document effect: direct transformation: type: transformation attributes: openparser:droppedSourceIds: - elem-missing - output: source-element:e1 activity: activity:ocr inputs: - entity: document:parsed role: parsed_document effect: direct transformation: type: filter - output: source-text:/signed_on activity: activity:extract inputs: - entity: document:parsed role: parsed_document effect: direct - entity: source-element:e1 role: resolved_source_evidence effect: direct transformation: type: transformation - output: field:/signed_on activity: activity:transform inputs: - entity: source-text:/signed_on role: source_text effect: direct transformation: type: transformation outputs: - field:/status - field:/total_due - field:/signed_on 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 completed_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 completed_at: null 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 completed_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`.\nAny currently compatible model may be used for extract and field grounding.\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 confidence: type: number minimum: 0 maximum: 1 description: "The model's own confidence in this value, 0 to 1, when it reported one. This is a\nself-report, not a calibrated probability, and lineage keeps it labelled as such.\nOmitted when the model reported nothing.\n" reason: type: string minLength: 1 maxLength: 2000 description: "One or two sentences from the model explaining why the quote is the source for this\nvalue: what in the document identifies it. This covers the read only; a rewrite is\nreported separately in `transform_claim`. Omitted when none was recorded.\n" quote: type: string minLength: 1 maxLength: 4096 description: "The span of document text the model says this value was read from, copied verbatim.\nUseful when the value was reformatted and so cannot be found in the document as\nwritten. Like `reason` this is the model's own report. Omitted when none was recorded.\n" transform_claim: type: object properties: operation: type: string enum: - date_time_format - numeric_format - quantity_magnitude - unit_conversion - currency_code - boolean_alias - text_normalization - enum_alias parameters: type: object propertyNames: type: string maxLength: 64 additionalProperties: anyOf: - type: string maxLength: 128 - type: number - type: boolean reason: type: string minLength: 1 maxLength: 2000 confidence: type: string enum: - low - medium - high required: - operation - parameters - reason additionalProperties: false description: "The model's bounded report of a rewrite: operation, parameters, reason, and optional\nlow/medium/high ordinal confidence. The claim is untrusted and never authorizes a\ndeterministic validator; only explicit request/schema intent can do that.\n" 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.' LineageConfidenceScale: type: object properties: min: type: number max: type: number required: - min - max additionalProperties: false LineageConfidenceAssertion: type: object properties: score: type: number scale: $ref: '#/components/schemas/LineageConfidenceScale' kind: type: string enum: - reported - derived - assessed scope: type: string minLength: 1 maxLength: 128 granularity: type: string minLength: 1 maxLength: 128 calibrated: default: false type: boolean sources: maxItems: 256 type: array items: type: object properties: type: type: string enum: - entity - activity - agent id: type: string minLength: 1 maxLength: 512 required: - type - id additionalProperties: false method: type: string minLength: 1 maxLength: 256 sampleCount: type: integer exclusiveMinimum: 0 maximum: 9007199254740991 attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} required: - score - scale - kind - scope - calibrated additionalProperties: false description: 'A score with an explicit numeric scale, scope, granularity, calibration status, and provenance. Scores from different scopes or providers are not interchangeable probabilities.' LineageAttribution: type: object properties: agent: type: string minLength: 1 maxLength: 512 role: type: string minLength: 1 maxLength: 128 attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} required: - agent additionalProperties: false LineageDigest: type: object properties: algorithm: type: string minLength: 1 maxLength: 64 value: type: string minLength: 1 maxLength: 512 required: - algorithm - value additionalProperties: false LineageLocator: type: object properties: uri: type: string minLength: 1 maxLength: 4096 mediaType: type: string minLength: 1 maxLength: 256 digest: $ref: '#/components/schemas/LineageDigest' attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} required: - uri additionalProperties: false LineageSelector: type: object properties: type: type: string minLength: 1 maxLength: 128 value: {} attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} required: - type - value additionalProperties: false LineageEntity: type: object properties: kind: type: string enum: - value - artifact - evidence - decision - collection name: type: string minLength: 1 maxLength: 512 value: {} path: type: string maxLength: 2048 pattern: "^(?:\\/(?:[^~/]|~0|~1)*)*$" schema: type: object propertyNames: type: string additionalProperties: {} locator: $ref: '#/components/schemas/LineageLocator' selector: $ref: '#/components/schemas/LineageSelector' digest: $ref: '#/components/schemas/LineageDigest' confidence: maxItems: 64 type: array items: $ref: '#/components/schemas/LineageConfidenceAssertion' approvals: maxItems: 64 type: array items: type: object properties: agent: type: string minLength: 1 maxLength: 512 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))$" note: type: string minLength: 1 maxLength: 2000 attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} required: - agent - at additionalProperties: false attributions: maxItems: 64 type: array items: $ref: '#/components/schemas/LineageAttribution' attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} required: - kind additionalProperties: false description: 'An immutable value, artifact, evidence item, decision, or collection in a `lineage@1` derivation DAG. `path` is an RFC 6901 JSON Pointer.' LineageAssociation: type: object properties: agent: type: string minLength: 1 maxLength: 512 role: type: string minLength: 1 maxLength: 128 attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} required: - agent additionalProperties: false LineageImplementation: type: object properties: type: type: string minLength: 1 maxLength: 128 name: type: string minLength: 1 maxLength: 512 version: type: string minLength: 1 maxLength: 128 uri: type: string minLength: 1 maxLength: 4096 attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} additionalProperties: false LineageActivity: type: object properties: type: type: string minLength: 1 maxLength: 256 name: type: string minLength: 1 maxLength: 512 status: type: string enum: - scheduled - started - ended - failed - cancelled startedAt: type: string maxLength: 64 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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$" endedAt: type: string maxLength: 64 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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$" implementation: $ref: '#/components/schemas/LineageImplementation' parameters: type: object propertyNames: type: string minLength: 1 additionalProperties: {} associations: maxItems: 64 type: array items: $ref: '#/components/schemas/LineageAssociation' attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} required: - type additionalProperties: false description: 'An operation that used entities and generated new ones, with implementation, timing, parameters, and responsible agents when known.' LineageAgent: type: object properties: type: type: string minLength: 1 maxLength: 128 name: type: string minLength: 1 maxLength: 512 attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} additionalProperties: false LineageDerivationInput: type: object properties: entity: type: string minLength: 1 maxLength: 512 role: type: string minLength: 1 maxLength: 128 effect: default: direct type: string enum: - direct - indirect confidence: $ref: '#/components/schemas/LineageConfidenceAssertion' attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} required: - entity - effect additionalProperties: false LineageTransformation: type: object properties: type: type: string minLength: 1 maxLength: 128 description: type: string minLength: 1 maxLength: 4096 expression: type: string minLength: 1 maxLength: 8192 masking: type: boolean attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} additionalProperties: false LineageDerivation: type: object properties: id: type: string minLength: 1 maxLength: 512 output: type: string minLength: 1 maxLength: 512 activity: type: string minLength: 1 maxLength: 512 inputs: default: [] maxItems: 1024 type: array items: $ref: '#/components/schemas/LineageDerivationInput' transformation: $ref: '#/components/schemas/LineageTransformation' confidence: $ref: '#/components/schemas/LineageConfidenceAssertion' attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} required: - output - activity - inputs additionalProperties: false description: 'One explicit hyperedge: an activity generated exactly one output entity from zero or more typed input entities.' LineageRelation: type: object properties: type: type: string enum: - member_of - specialization_of - alternate_of source: type: string minLength: 1 maxLength: 512 target: type: string minLength: 1 maxLength: 512 attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} required: - type - source - target additionalProperties: false LineageDocument: type: object properties: format: type: string const: lineage@1 id: type: string minLength: 1 maxLength: 512 profiles: maxItems: 64 type: array items: type: string minLength: 1 maxLength: 1024 entities: default: {} type: object propertyNames: type: string minLength: 1 maxLength: 512 additionalProperties: $ref: '#/components/schemas/LineageEntity' activities: default: {} type: object propertyNames: type: string minLength: 1 maxLength: 512 additionalProperties: $ref: '#/components/schemas/LineageActivity' agents: default: {} type: object propertyNames: type: string minLength: 1 maxLength: 512 additionalProperties: $ref: '#/components/schemas/LineageAgent' derivations: default: [] maxItems: 100000 type: array items: $ref: '#/components/schemas/LineageDerivation' relations: default: [] maxItems: 100000 type: array items: $ref: '#/components/schemas/LineageRelation' outputs: default: [] maxItems: 10000 type: array items: type: string minLength: 1 maxLength: 512 attributes: type: object propertyNames: type: string minLength: 1 additionalProperties: {} required: - format - entities - activities - agents - derivations - relations - outputs additionalProperties: false description: 'A complete, acyclic `lineage@1` data-derivation graph grounded in W3C PROV semantics. Downstream systems can append entities, activities, agents, and derivations.' 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" lineage: $ref: '#/components/schemas/LineageDocument' description: "Portable `lineage@1` derivation DAG present with successful field grounding. It connects every output value to document evidence and the OCR/extraction activities that produced it.\n" required: - output - parsed_document - llm_model - attempts additionalProperties: false description: 'Terminal extraction result returned by sync `200` and embedded in succeeded jobs.' ExtractionReviewStatus: type: string enum: - pending - approved - rejected ExtractionReviewConfirmation: type: object properties: path: type: string minLength: 1 maxLength: 2048 pattern: "^(?:\\/(?:[^~/]|~0|~1)*)*$" value: {} note: type: string maxLength: 2000 required: - path - value additionalProperties: false description: 'This field should say `value`, signed by the caller. Editing and approving are the same act.' ExtractionReviewRetraction: type: object properties: path: type: string minLength: 1 maxLength: 2048 pattern: "^(?:\\/(?:[^~/]|~0|~1)*)*$" required: - path additionalProperties: false description: 'Take back the caller own current tip on this path. Only a path is accepted: the tip is unambiguous once eligibility has been checked.' ExtractionReviewEvent: oneOf: - type: object properties: version: type: integer exclusiveMinimum: 0 maximum: 9007199254740991 actor_id: type: string minLength: 1 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))$" type: type: string const: field_confirmed path: type: string minLength: 1 maxLength: 2048 pattern: "^(?:\\/(?:[^~/]|~0|~1)*)*$" previous_value: {} value: {} note: type: string maxLength: 2000 required: - version - actor_id - created_at - type - path - value additionalProperties: false - type: object properties: version: type: integer exclusiveMinimum: 0 maximum: 9007199254740991 actor_id: type: string minLength: 1 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))$" type: type: string const: field_confirmation_retracted path: type: string minLength: 1 maxLength: 2048 pattern: "^(?:\\/(?:[^~/]|~0|~1)*)*$" required: - version - actor_id - created_at - type - path additionalProperties: false - type: object properties: version: type: integer exclusiveMinimum: 0 maximum: 9007199254740991 actor_id: type: string minLength: 1 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))$" type: type: string enum: - approved - rejected note: type: string maxLength: 2000 required: - version - actor_id - created_at - type additionalProperties: false - type: object properties: version: type: integer exclusiveMinimum: 0 maximum: 9007199254740991 actor_id: type: string minLength: 1 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))$" type: type: string const: completion_retracted required: - version - actor_id - created_at - type additionalProperties: false ExtractionReview: type: object properties: job_id: $ref: '#/components/schemas/JobId' status: $ref: '#/components/schemas/ExtractionReviewStatus' machine_output: {} corrected_output: {} lineage: $ref: '#/components/schemas/LineageDocument' version: type: integer minimum: 0 maximum: 9007199254740991 events: type: array items: $ref: '#/components/schemas/ExtractionReviewEvent' 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' updated_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' completed_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' reviewed_by_actor_id: anyOf: - type: string - type: 'null' viewer_actor_id: type: string required: - job_id - status - machine_output - corrected_output - version - events - created_at - updated_at - completed_at - reviewed_by_actor_id - viewer_actor_id additionalProperties: false description: 'Versioned review state that preserves immutable machine output beside corrected output and append-only attributed events. Grounded reviews also extend the machine `lineage@1` graph with confirm and completion activities. Retracting a tip removes that confirmation from the projected graph while the event log keeps the retraction.' UpdateExtractionReviewRequest: type: object properties: expected_version: type: integer minimum: 0 maximum: 9007199254740991 confirmations: default: [] maxItems: 100 type: array items: type: object properties: path: type: string minLength: 1 maxLength: 2048 pattern: "^(?:\\/(?:[^~/]|~0|~1)*)*$" value: {} note: type: string maxLength: 2000 required: - path - value additionalProperties: false description: Fields the caller is signing. A value that matches the standing field is a sign-off; a different value also corrects it. retractions: default: [] maxItems: 100 type: array items: type: object properties: path: type: string minLength: 1 maxLength: 2048 pattern: "^(?:\\/(?:[^~/]|~0|~1)*)*$" required: - path additionalProperties: false description: JSON Pointers whose current tip the caller is taking back. Each entry peels one confirmation. The restored value is the one recorded on that confirmation. required: - expected_version additionalProperties: false description: 'Optimistic review update. Retractions peel one current tip each, in order, then confirmations apply. A retraction and a confirmation that overlap are rejected. At least one confirmation or retraction is required.' CompleteExtractionReviewRequest: type: object properties: expected_version: type: integer minimum: 0 maximum: 9007199254740991 status: type: string enum: - approved - rejected note: type: string maxLength: 2000 required: - expected_version - status additionalProperties: false ReopenExtractionReviewRequest: type: object properties: expected_version: type: integer minimum: 0 maximum: 9007199254740991 required: - expected_version additionalProperties: false 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))$" completed_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' 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" review_status: $ref: '#/components/schemas/ExtractionReviewStatus' required: - id - operation - status - output_format - created_at - updated_at - completed_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" review_status: $ref: '#/components/schemas/ExtractionReviewStatus' 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` mark Eigenpal-tested quality tiers;\n`supports_grounding` is true for every compatible model while `supports_suggest`\nmatches certification. `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}/review': get: operationId: getExtractionReview tags: - jobs summary: Get an extraction review description: "Return the immutable machine output beside the current corrected output and append-only\nreview events. A succeeded extraction with no confirmations returns a synthesized pending review\nat version 0. Cross-tenant and unknown jobs return `404`.\n" parameters: - $ref: '#/components/parameters/JobId' responses: '200': description: Current extraction review content: application/json: schema: $ref: '#/components/schemas/ExtractionReview' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/JobNotFound' '409': description: Job is not a succeeded extraction with reviewable output content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '429': $ref: '#/components/responses/RateLimited' patch: operationId: updateExtractionReview tags: - jobs summary: Confirm extraction field values description: "Confirm that a field should say a given value, signed by the caller, without mutating the\nmachine result. `expected_version` provides optimistic concurrency; stale writes return `409`.\nEvery confirmation and retraction appends an actor- and timestamp-attributed event.\n\nA confirmation whose value matches what extraction produced is a plain sign-off; one that\ndiffers also corrects the field. There is no separate approval: who stands behind a value is\nderived from live confirmations. Retractions are applied first, then confirmations.\n\nA retraction peels the caller's own current tip on that path and restores the value the\nconfirmation replaced. Two retractions of the same path undo two confirmations, in order. A\nretraction cannot be combined with a confirmation on the same or overlapping path. The tip is\nnot retractable when someone else made it, or when a later overlapping confirmation named a\ndifferent value. A co-signature of the same value becomes the tip, so only that co-signer can\ntake it back. Completing the review still freezes everything. Provide at least one\nconfirmation or retraction.\n" parameters: - $ref: '#/components/parameters/JobId' requestBody: $ref: '#/components/requestBodies/UpdateExtractionReviewRequest' responses: '200': description: Updated extraction review content: application/json: schema: $ref: '#/components/schemas/ExtractionReview' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/JobNotFound' '409': description: Review is completed or the expected version is stale content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '413': description: Successful response content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '422': description: 'A path is invalid, a retraction is not eligible, or no confirmation or retraction was provided' content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '429': $ref: '#/components/responses/RateLimited' '/jobs/{id}/review/complete': post: operationId: completeExtractionReview tags: - jobs summary: Approve or reject an extraction review description: "Finalize a pending review as approved or rejected. A completed review is frozen: field\nconfirmations are rejected until it is reopened. Uses the same optimistic version check as\nfield confirmations.\n" parameters: - $ref: '#/components/parameters/JobId' requestBody: $ref: '#/components/requestBodies/CompleteExtractionReviewRequest' responses: '200': description: Completed extraction review content: application/json: schema: $ref: '#/components/schemas/ExtractionReview' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/JobNotFound' '409': description: Review is already completed or the expected version is stale content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '413': description: Successful response content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '429': $ref: '#/components/responses/RateLimited' '/jobs/{id}/review/reopen': post: operationId: reopenExtractionReview tags: - jobs summary: Reopen a completed extraction review description: "Take a sign-off back so the run returns to `pending` and its fields can be reviewed again.\nOnly the reviewer who completed the run may reopen it. Both events stay in the log, so the\ntrail shows the run was signed off and then reopened, while the review status and the\nlineage decision follow the live completion. Uses the same optimistic version check as\nfield confirmations.\n" parameters: - $ref: '#/components/parameters/JobId' requestBody: $ref: '#/components/requestBodies/ReopenExtractionReviewRequest' responses: '200': description: 'Reopened extraction review, now pending' content: application/json: schema: $ref: '#/components/schemas/ExtractionReview' '400': $ref: '#/components/responses/MalformedRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/JobNotFound' '409': description: "Review is not signed off (`review_not_completed`), was signed off by another reviewer\n(`review_reopen_not_author`), or the expected version is stale\n" content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '413': description: Successful response content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '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'