{"openapi":"3.1.0","info":{"title":"anyformat API","description":"Document extraction and workflow automation API.\n\nAnyFormat lets you define extraction workflows that pull structured data from any document — PDFs, images, scanned files, or plain text. Upload a file, run it through a workflow, and get back structured fields with confidence scores and source evidence.\n\n## Quick start\n\nSee the [Quick start guide](https://docs.anyformat.ai/api-reference/introduction) for a walkthrough.\n\n## Authentication\n\nAll endpoints (except `/health/`) require a Bearer token in the `Authorization` header:\n\n```\nAuthorization: Bearer <your-api-key>\n```\n\nGet your API key from [app.anyformat.ai/api-key](https://app.anyformat.ai/api-key).\n\n## Versioning\n\nEndpoints are versioned by path prefix (`/v2/`, `/v3/`). Every response under\na versioned prefix includes `X-API-Version`.\n","version":"2.0.0"},"servers":[{"url":"https://api.anyformat.ai","description":"API server"}],"paths":{"/health/":{"get":{"tags":["health"],"summary":"Health Check","description":"Returns 200 OK if the service is running. No authentication required.\n\nUse this endpoint to verify API connectivity before making authenticated calls.","operationId":"health_check_health__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthCheckResponse"}}}}}}},"/key-check/":{"get":{"tags":["health"],"summary":"Key Check","description":"Validate the caller's API key.\n\nSuccess (200): the key is active and the response names its\norganization and granted scopes. Failure (401): the standard error envelope with\n``error_code`` set to ``MISSING_API_KEY`` (no key sent) or\n``INVALID_API_KEY`` (key sent but not recognised).\n\nReuses the same ``/me/organization/`` round-trip that every\nauthenticated request already runs, so a call here warms the same\ncache — cheap to invoke as a probe before the first real request.","operationId":"key_check_key_check__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyCheckResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}},"security":[{"ApiKeyAuth":[]}]}},"/v2/files/{collection_id}/":{"delete":{"tags":["files"],"summary":"Delete file collection","description":"Delete a file collection and all its files permanently.\n\nThis removes all uploaded files and any extraction results associated with\nthe collection. This action is irreversible.","operationId":"delete_file_v2_files__collection_id___delete","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","title":"Collection Id"}}],"responses":{"204":{"description":"Successful Response","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/workflows/{workflow_id}/files/":{"get":{"tags":["files"],"summary":"List file collections","description":"List file collections for a workflow.\n\nA file collection groups one or more uploaded files together. Each\ncollection's ``status`` field reflects extraction progress: non-terminal\nvalues are ``not_started``, ``queued``, ``in_progress``; terminal values\nare ``processed`` (success), ``error``, and ``cancelled``.","operationId":"v2_list_workflow_files","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Deprecated. Use `cursor` for stable keyset pagination — offset pagination can skip or repeat rows when the underlying list changes between requests.","deprecated":true,"default":1,"title":"Page"},"description":"Deprecated. Use `cursor` for stable keyset pagination — offset pagination can skip or repeat rows when the underlying list changes between requests.","deprecated":true},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque token from a previous response's `next_cursor`. When present, `page` is ignored and pagination uses keyset order.","title":"Cursor"},"description":"Opaque token from a previous response's `next_cursor`. When present, `page` is ignored and pagination uses keyset order."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_CollectionListItem_"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}},"post":{"tags":["files"],"summary":"Create file collection","description":"Upload one or more files to a workflow, creating one collection per file.\n\nUse this when you want to upload files without immediately running extraction.\nTo upload and extract in one step, use `POST /v2/workflows/{workflow_id}/run/` instead.\n\nSupported file types: PDF, PNG, JPG, TIFF, TXT, DOCX, XLSX, CSV, and more.\n\nMulti-file collections aren't supported yet — each uploaded file becomes\nits own one-file collection. The response's ``id`` is the last\ncollection's id; ``files`` enumerates every uploaded file in order.\n\nFilenames are unique within a workflow. By default (`on_conflict=error`) a\nfile whose name collides with an existing file fails the whole request with\n``409`` before anything is uploaded. Pass `on_conflict=rename` to instead\nauto-rename the collision (``report.pdf`` -> ``report (1).pdf``); each\nreturned file's ``filename`` is then the name it landed under, with\n``original_filename`` holding the uploaded name when a rename happened.","operationId":"v2_create_workflow_file","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v2_create_workflow_file"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectionResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/workflows/{workflow_id}/files/from-url/":{"post":{"tags":["files"],"summary":"Create file collection from URL","description":"Create a file collection by pointing the backend at a URL.\n\nUse this when the source document already lives at an HTTPS URL (for\nexample, a presigned S3 link or a hosted asset). The backend fetches\nthe bytes server-side — the caller does not stream them.\n\nThe fetch is bounded by a 10-second timeout and a byte cap that\nmirrors Django's ``DATA_UPLOAD_MAX_MEMORY_SIZE`` (20 MB by default).\nThe caller's `filename` is authoritative: a ``Content-Disposition`` on\nthe fetched response never overrides it.\n\nFilenames are unique within a workflow. By default (`on_conflict=error`)\na colliding `filename` fails the request with ``409`` — surfaced once the\nasync import settles, not before it starts; pass `on_conflict=rename` to\nauto-rename it instead (``report.pdf`` -> ``report (1).pdf``). The returned\nfile's ``filename`` is then the name it actually landed under, with\n``original_filename`` holding the requested name when a rename happened.\n\nError statuses:\n- ``400`` for caller-input errors the backend won't accept: oversize\n  response (``RemoteFileFetchTooLarge``) and SSRF-blocked URL\n  (``RemoteFileUrlBlocked``). Mirrors the ``content_base64`` path's\n  ``RequestDataTooBig`` → 400 mapping for uniform wire shape.\n- ``409`` when the fetched file's name collides with a live file and the\n  caller did not opt into ``rename`` (``FILENAME_CONFLICT``).\n- ``422`` when the upstream URL prevented processing: timeout,\n  DNS failure, or non-2xx response from the target.","operationId":"v2_create_workflow_file_from_url","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDocumentPacketFromUrlRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectionResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/workflows/{workflow_id}/files/{collection_id}/results/":{"get":{"tags":["files"],"summary":"Get file results","description":"Retrieve the extraction results for a file collection.\n\nReturns the structured data extracted from each file, including field values,\nconfidence scores, and source evidence (text excerpts and page numbers). Also\nincludes a `verification_url` linking to the AnyFormat dashboard for human review.\n\nPossible non-200 responses:\n\n- **412 `PRECONDITION_FAILED`** — extraction still in progress; retry with backoff.\n- **422 `EXTRACTION_FAILED`** — extraction did not complete successfully; terminal.\n  Polling will not transition the collection out of this state. Possible\n  next steps: review the document, retry the upload, or open the\n  collection in the AnyFormat dashboard for more context.\n- **422 `EXTRACTION_CANCELLED`** — extraction was cancelled; terminal.\n  Possible next steps: review the document, retry the upload, or open\n  the collection in the AnyFormat dashboard.","operationId":"v2_get_file_results","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","title":"Collection Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultsResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"412":{"description":"Extraction not yet available — `retryable=true`. Poll again after backoff.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"PRECONDITION_FAILED":{"value":{"error":"Extraction not yet available — retry after backoff.","detail":"Extraction not yet available — retry after backoff.","error_code":"PRECONDITION_FAILED","retryable":true,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/workflows/":{"post":{"tags":["workflows"],"summary":"Create workflow","description":"Create a workflow from a strongly-typed graph (atomic).\n\nProvide an explicit list of typed `nodes` (parse / classify / splitter /\nextract) and `edges` between them. The full workflow — fields, nodes,\nrouting — is created in a single transaction.","operationId":"v2_create_workflow","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}},"get":{"tags":["workflows"],"summary":"List workflows","description":"List all workflows in your organization with pagination.\n\nWorkflows can be filtered by status and sorted by any field.","operationId":"v2_list_workflows","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"sort_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sort By"}},{"name":"order","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Order"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowListResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/workflows/{workflow_id}/":{"put":{"tags":["workflows"],"summary":"Update workflow","description":"Replace a workflow's typed graph definition (atomic).\n\nProvide the full replacement graph — nodes and edges — identically to\n`POST /v2/workflows/`. The workflow's extraction fields are rebuilt from\nthe new definition in a single transaction.","operationId":"v2_update_workflow","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}},"get":{"tags":["workflows"],"summary":"Get workflow","description":"Retrieve a single workflow by its ID, including its configured extraction fields.","operationId":"v2_get_workflow","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}},"delete":{"tags":["workflows"],"summary":"Delete workflow","description":"Delete a workflow and all associated file collections and extraction results.\n\nThis action is irreversible.","operationId":"v2_delete_workflow","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}}],"responses":{"204":{"description":"Successful Response","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/workflows/{workflow_id}/definition/":{"get":{"tags":["workflows"],"summary":"Get workflow definition","description":"Retrieve the workflow's typed definition in the shape PUT accepts.\n\nReturns the same body shape as `PUT /v2/workflows/{workflow_id}/` —\nfeed the response back into PUT unchanged to perform a guaranteed\nno-op edit (no new version cut). To edit one field on a 60-field\nworkflow: GET this, mutate, PUT.","operationId":"v2_get_workflow_definition","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"version_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional version external id (10-char). Omit to return the workflow's latest version.","title":"Version Id"},"description":"Optional version external id (10-char). Omit to return the workflow's latest version."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowUpdateRequest"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/workflows/{workflow_id}/run/":{"post":{"tags":["workflows"],"summary":"Run workflow","description":"Upload a file and immediately run the extraction workflow on it.\n\nThis is the primary endpoint for document extraction. It creates a file collection,\nuploads the file, and starts extraction in one step. The response includes a collection\n`id` that you can use to poll for results via\n`GET /v2/workflows/{workflow_id}/files/{collection_id}/results/`.\n\nProvide the file as a binary upload in the `file` field.","operationId":"v2_run_workflow","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"X-Anyformat-Priority","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Anyformat-Priority"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v2_run_workflow"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunResponseV2"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/workflows/{workflow_id}/upload/":{"post":{"tags":["workflows"],"summary":"Upload file","description":"Upload a file to a workflow without running extraction.\n\nUse this when you want to stage files for later processing. For upload-and-extract\nin one step, use `POST /v2/workflows/{workflow_id}/run/` instead.","operationId":"v2_upload_file","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v2_upload_file"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadFileResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/workflows/{workflow_id}/files/{file_id}/run/":{"post":{"tags":["workflows"],"summary":"Run uploaded file","description":"Start extraction on a file that was already uploaded via\n`POST /v2/workflows/{workflow_id}/upload/` (pass the `file_id` from that\nresponse).\n\nThis is the second half of the staged upload-then-run flow. For\nupload-and-extract in one step, use `POST /v2/workflows/{workflow_id}/run/`.\nThe returned `id` is the file's collection — poll results via\n`GET /v2/workflows/{workflow_id}/files/{id}/results/`.","operationId":"v2_run_file","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"file_id","in":"path","required":true,"schema":{"type":"string","title":"File Id"}},{"name":"X-Anyformat-Priority","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Anyformat-Priority"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunResponseV2"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/workflows/{workflow_id}/runs/":{"get":{"tags":["workflows"],"summary":"List workflow runs","description":"List all extraction runs for a workflow with pagination.\n\nEach run corresponds to a file collection that was processed by the workflow.\nUse the run's `id` (collection UUID) with\n`GET /v2/workflows/{workflow_id}/files/{id}/results/` to fetch detailed results.","operationId":"v2_list_workflow_runs","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Deprecated. Use `cursor` for stable keyset pagination — offset pagination can skip or repeat rows when the underlying list changes between requests.","deprecated":true,"default":1,"title":"Page"},"description":"Deprecated. Use `cursor` for stable keyset pagination — offset pagination can skip or repeat rows when the underlying list changes between requests.","deprecated":true},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque token from a previous response's `next_cursor`. When present, `page` is ignored and pagination uses keyset order.","title":"Cursor"},"description":"Opaque token from a previous response's `next_cursor`. When present, `page` is ignored and pagination uses keyset order."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunListResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/operations/parse":{"post":{"tags":["operations"],"summary":"Parse a document","description":"Upload a single document and parse it with the platform's fast lite parse.\n\nProvide the file as a binary multipart upload in the ``file`` field. Returns\na ``job_id``; poll ``GET /v2/operations/parse/{job_id}`` for the markdown.","operationId":"v2_parse","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v2_parse"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseJobResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}},"security":[{"ApiKeyAuth":[]}]}},"/v2/operations/parse/{job_id}":{"get":{"tags":["operations"],"summary":"Get parse job result","description":"Poll a parse job. Returns ``status`` (processing | done | error) and, once\ndone, the parsed ``markdown`` inline. ``job_id`` is the collection id.","operationId":"v2_parse_result","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseResultResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/organizations/{org_id}/suggestions/fields/":{"post":{"tags":["suggestions"],"summary":"Suggest extraction fields","operationId":"v2_suggest_fields","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestFieldsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestFieldsResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/organizations/{org_id}/suggestions/field-description/":{"post":{"tags":["suggestions"],"summary":"Suggest a field description","operationId":"v2_suggest_field_description","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestFieldDescriptionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestFieldDescriptionResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/organizations/{org_id}/suggestions/workflow-description/":{"post":{"tags":["suggestions"],"summary":"Suggest a workflow description","operationId":"v2_suggest_workflow_description","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestWorkflowDescriptionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestWorkflowDescriptionResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v2/organizations/{org_id}/suggestions/workflow-name/":{"post":{"tags":["suggestions"],"summary":"Suggest a workflow name","operationId":"v2_suggest_workflow_name","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestWorkflowNameRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestWorkflowNameResponse"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, file, or collection ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/workflows/":{"post":{"tags":["workflows"],"summary":"Create workflow","description":"Create a workflow from a strongly-typed graph (atomic).\n\nProvide an explicit list of typed `nodes` (parse / classify / splitter /\nextract / validate) and `edges` between them — the same body shape\n`POST /v2/workflows/` accepts. Fetch the stored graph back via\n`GET /v3/workflows/{workflow_id}/`.","operationId":"v3_create_workflow","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowSummaryV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}},"get":{"tags":["workflows"],"summary":"List workflows","description":"List your organization's workflows, newest first.\n\nKeyset-paginated: follow `next_cursor` until it is `null`. The sort\norder is fixed (`-created_at, -id`); there are no totals or page numbers.","operationId":"v3_list_workflows","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Page size, capped at 100.","default":20,"title":"Limit"},"description":"Page size, capped at 100."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque token from a previous response's `next_cursor`.","title":"Cursor"},"description":"Opaque token from a previous response's `next_cursor`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowListPageV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/workflows/{workflow_id}/":{"get":{"tags":["workflows"],"summary":"Get workflow","description":"Retrieve a workflow with its complete typed graph inline.\n\n`{name, description, nodes, edges}` is the exact shape\n`POST /v3/workflows/` accepts — mutate it and feed it back to\n`PATCH /v3/workflows/{workflow_id}/` to edit.\n\nPass `version` to read one version for comparison or audit; any other\nquery parameter is rejected, so a misspelled `version` cannot silently\nread the latest. Versions are read-only: runs always use the latest\nversion, and a PATCH always builds on the latest version.","operationId":"v3_get_workflow","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"version","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A `version_id` from `GET /v3/workflows/{workflow_id}/versions/`. Reads that version's graph instead of the latest.","title":"Version"},"description":"A `version_id` from `GET /v3/workflows/{workflow_id}/versions/`. Reads that version's graph instead of the latest."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowDetailV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}},"patch":{"tags":["workflows"],"summary":"Update workflow","description":"Replace a workflow's typed graph (atomic).\n\nThe body is the `{name, description, nodes, edges}` sub-shape of\n`GET /v3/workflows/{workflow_id}/` — GET, mutate, PATCH. Echo each\nexisting field's `persistent_id` unchanged (including across\nrenames) to keep the field's identity, so analytics, ground truth\nand quality metrics stay attached; omit `persistent_id` only for\ngenuinely new fields (a pidless field is always treated as new —\nname coincidence with a prior field does NOT confer identity). An\nechoed `persistent_id` that doesn't match any field in the current\nversion is a 400. Responds with the updated workflow in the exact\n`GET /v3/workflows/{workflow_id}/` shape, so the result can be\nedited and PATCHed again. The returned graph is this request's own\nwrite result — including the `persistent_id`s assigned to new\nfields — never the state left by a concurrent update.","operationId":"v3_update_workflow","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowDetailV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}},"delete":{"tags":["workflows"],"summary":"Delete workflow","description":"Delete a workflow and all associated document packets and runs.\n\nThis action is irreversible.","operationId":"v3_delete_workflow","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}}],"responses":{"204":{"description":"Successful Response","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/workflows/{workflow_id}/upload/":{"post":{"tags":["workflows"],"summary":"Upload document packet to workflow","description":"Upload one or more files as a single document packet (atomic).\n\nAll files are grouped into ONE packet — the unit later runs address.\nCreation is all-or-nothing: any rejected file (unsupported type,\ndisguised bytes) fails the whole request and nothing is stored.\n\nFilenames are unique within a workflow. By default (`on_conflict=error`) a\nfile whose name collides with an existing file fails the request with\n``409`` before anything is uploaded; pass `on_conflict=rename` to auto-rename\nthe collision instead (`contract.pdf` -> `contract (1).pdf`); each returned\nfile's ``name`` is then the name it landed under, with ``original_name``\nholding the uploaded name when a rename happened.\n\nUpload without running; trigger extraction via\n`POST /v3/document-packets/{document_packet_id}/run/`.","operationId":"v3_upload_to_workflow","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional caller-supplied key (Stripe convention). Retrying the request with the same key replays the original upload slots so no duplicate packet is created.","title":"Idempotency-Key"},"description":"Optional caller-supplied key (Stripe convention). Retrying the request with the same key replays the original upload slots so no duplicate packet is created."}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v3_upload_to_workflow"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentPacketCreatedV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/workflows/{workflow_id}/upload/run/":{"post":{"tags":["workflows"],"summary":"Upload and run workflow","description":"Upload one document packet and run it in a single call.\n\nComposes `POST /v3/workflows/{workflow_id}/upload/` and\n`POST /v3/document-packets/{document_packet_id}/run/`: the files are\ngrouped into ONE packet (all-or-nothing) and an extraction is enqueued\non the workflow's latest version. Poll `GET /v3/runs/{run_id}/` until\n`status` is terminal.\n\nFilenames are unique within a workflow. By default (`on_conflict=error`) a\ncolliding filename fails the request with ``409`` before anything is\nuploaded or run; pass `on_conflict=rename` to auto-rename instead.","operationId":"v3_upload_and_run_workflow","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional caller-supplied key (Stripe convention). Retrying the request with the same key replays the original packet AND run — no duplicate upload, no second extraction.","title":"Idempotency-Key"},"description":"Optional caller-supplied key (Stripe convention). Retrying the request with the same key replays the original packet AND run — no duplicate upload, no second extraction."},{"name":"X-Anyformat-Priority","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Anyformat-Priority"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v3_upload_and_run_workflow"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunTriggeredV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/workflows/{workflow_id}/upload/from-url/":{"post":{"tags":["workflows"],"summary":"Create document packet from URLs","description":"Import every URL into a single document packet, atomically.\n\nThe backend fetches each HTTPS URL server-side (10s timeout, 20 MB cap\nper file) and registers the packet in one transaction only after every\nfetch succeeded — any failure imports nothing (no partial packet, no\norphan files).\n\nEach file is named by its response's `Content-Disposition` filename when\npresent, else by the last segment of the URL's path. A presigned URL can\nsign the header in (S3: `ResponseContentDisposition`), which is how a\ncaller names a file whose URL path is opaque.\n\nFilenames are unique within a workflow. By default (`on_conflict=error`)\na colliding filename fails the request with ``409`` — surfaced once\nthe atomic import settles, not before it starts; pass `on_conflict=rename`\nto auto-rename instead (``report.pdf`` -> ``report (1).pdf``). Each returned\n`name` is the name the file actually landed under; ``original_name`` holds\nthe name it was fetched under when a rename happened.","operationId":"v3_upload_from_url","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentPacketFromUrlsRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentPacketCreatedV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/workflows/{workflow_id}/document-packets/":{"get":{"tags":["workflows"],"summary":"List workflow document packets","description":"List a workflow's document packets, newest first.\n\nKeyset-paginated: follow `next_cursor` until it is `null`. The sort\norder is fixed (`-created_at, -id`); there are no totals or page\nnumbers. Items are slim — fetch\n`GET /v3/document-packets/{document_packet_id}/` for the per-file\nbreakdown and `latest_run_id`.","operationId":"v3_list_workflow_document_packets","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Page size, capped at 100.","default":20,"title":"Limit"},"description":"Page size, capped at 100."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque token from a previous response's `next_cursor`.","title":"Cursor"},"description":"Opaque token from a previous response's `next_cursor`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentPacketListPageV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/workflows/{workflow_id}/versions/":{"get":{"tags":["workflows"],"summary":"List workflow versions","description":"List a workflow's versions, newest first.\n\nVersions are read-only: they exist for comparison and audit, and runs\nalways use the latest version (item 0 of the first page). Read a\nversion's graph with `GET /v3/workflows/{workflow_id}/?version=`.\n\nKeyset-paginated: follow `next_cursor` until it is `null`. The sort\norder is fixed (`-created_at, -id`); there are no totals or page numbers.","operationId":"v3_list_workflow_versions","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Page size, capped at 100.","default":20,"title":"Limit"},"description":"Page size, capped at 100."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque token from a previous response's `next_cursor`.","title":"Cursor"},"description":"Opaque token from a previous response's `next_cursor`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowVersionListPageV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/workflows/{workflow_id}/runs/":{"get":{"tags":["workflows"],"summary":"List workflow runs","description":"List a workflow's runs, newest first.\n\nKeyset-paginated: follow `next_cursor` until it is `null`. The sort\norder is fixed (`-created_at, -id`); there are no totals or page\nnumbers. Items are slim — fetch `GET /v3/runs/{run_id}/` for the\nresults.\n\nOptional half-open interval on the packet's `created_at`:\n`document_packet_created_after` (inclusive) /\n`document_packet_created_before` (exclusive). Typical daily-batch\nworkflow: upload day N, fetch day N+1 with\n`after=<N>T00:00:00 & before=<N+1>T00:00:00`.","operationId":"v3_list_workflow_runs","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Page size, capped at 100.","default":20,"title":"Limit"},"description":"Page size, capped at 100."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque token from a previous response's `next_cursor`.","title":"Cursor"},"description":"Opaque token from a previous response's `next_cursor`."},{"name":"document_packet_created_after","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Include only runs whose document packet was created at or after this ISO 8601 datetime (inclusive lower bound). Combine with `document_packet_created_before` to fetch one day's uploads.","title":"Document Packet Created After"},"description":"Include only runs whose document packet was created at or after this ISO 8601 datetime (inclusive lower bound). Combine with `document_packet_created_before` to fetch one day's uploads."},{"name":"document_packet_created_before","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Include only runs whose document packet was created before this ISO 8601 datetime (exclusive upper bound). Adjacent day-buckets tile without overlap: `after=2026-07-17T00:00:00 & before=2026-07-18T00:00:00` is exactly July 17.","title":"Document Packet Created Before"},"description":"Include only runs whose document packet was created before this ISO 8601 datetime (exclusive upper bound). Adjacent day-buckets tile without overlap: `after=2026-07-17T00:00:00 & before=2026-07-18T00:00:00` is exactly July 17."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunListPageV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/document-packets/{document_packet_id}/":{"get":{"tags":["document-packets"],"summary":"Get document packet","description":"Retrieve one document packet flat: status, timestamps, the files it\ngroups, and `latest_run_id` (`null` until the packet has been run).\n\nUnknown ids — including packets belonging to another organization —\nreturn 404.","operationId":"v3_get_document_packet","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"document_packet_id","in":"path","required":true,"schema":{"type":"string","title":"Document Packet Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentPacketDetailV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}},"delete":{"tags":["document-packets"],"summary":"Delete document packet","description":"Delete a document packet and all its files.\n\nSame semantics as `DELETE /v2/files/{collection_id}/`: the packet and\nevery file in it are removed together, along with any extraction\nresults. This action is irreversible.","operationId":"v3_delete_document_packet","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"document_packet_id","in":"path","required":true,"schema":{"type":"string","title":"Document Packet Id"}}],"responses":{"204":{"description":"Successful Response","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/document-packets/{document_packet_id}/run/":{"post":{"tags":["document-packets"],"summary":"Run document packet","description":"Run (or re-run) a document packet on the latest version of its\nworkflow.\n\nEvery call creates a NEW run — re-running after editing the workflow\nis the intended flow; earlier runs stay readable at\n`GET /v3/runs/{run_id}/`. The only exception is an `Idempotency-Key`\nreplay, which returns the original run.\n\nUnknown ids — including packets belonging to another organization —\nreturn 404. An organization without extraction credit gets 402.","operationId":"v3_run_document_packet","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"document_packet_id","in":"path","required":true,"schema":{"type":"string","title":"Document Packet Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional caller-supplied key (Stripe convention). Retrying the request with the same key returns the original run instead of triggering (and billing) a second extraction.","title":"Idempotency-Key"},"description":"Optional caller-supplied key (Stripe convention). Retrying the request with the same key returns the original run instead of triggering (and billing) a second extraction."},{"name":"X-Anyformat-Priority","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Anyformat-Priority"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunTriggeredV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/workflows/{workflow_id}/dataset/upload/":{"post":{"tags":["datasets"],"summary":"Upload a document (+ ground truth) to a workflow dataset","description":"Upload one document (1..N files) plus optional ground truth as ONE\ndocument packet in the dataset (atomic).\n\nAll-or-nothing: any rejected file (unsupported type, disguised bytes) or a\nground-truth failure fails the whole request and nothing is stored.\n\nFilenames are unique within a workflow. By default (`on_conflict=error`) a\nfile whose name collides with an existing file fails the request with `409`\nbefore anything is uploaded; pass `on_conflict=rename` to auto-rename the\ncollision instead (`invoice.pdf` -> `invoice (1).pdf`), each returned file's\n``name`` being the name it landed under and ``original_name`` holding the\nuploaded name when a rename happened.\n\nBulk ingestion loops this endpoint, one call per document; each call is\nbounded and independently retryable.","operationId":"v3_upload_to_dataset","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional caller-supplied key (Stripe convention). Retrying the request with the same key replays the original document packet — no duplicate document is registered.","title":"Idempotency-Key"},"description":"Optional caller-supplied key (Stripe convention). Retrying the request with the same key replays the original document packet — no duplicate document is registered."}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v3_upload_to_dataset"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetUploadResponseV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Ground truth failed validation (`GT_INVALID`): `detail.errors` lists each offending key. Other 422 reasons — unsupported bytes (`UNSUPPORTED_FILE_TYPE`) and an unresolved extract node (`EXTRACT_NODE_UNRESOLVED`) — use the standard envelope with a string `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroundTruthInvalidError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/workflows/{workflow_id}/edit-references/":{"post":{"tags":["edit references"],"summary":"Upload reference documents to a workflow","description":"Upload the standing data an Edit node fills forms from.\n\nReturns one document per file, each with the `id` to put in an Edit node's\n`reference_document_ids`.\n\nA text reference is usable immediately (`status: ready`). A PDF is parsed\nonce, here — never on a run — so it comes back `pending` and reaches\n`ready` shortly after; poll `GET /v3/workflows/{workflow_id}/edit-references/`\nuntil it settles. Starting a run whose Edit node names a reference that is\nnot yet `ready` is refused rather than filled from a partial reference.\n\nUpload once, reuse forever: every later run reads the already-parsed text,\nso the parse is neither repeated nor re-billed.","operationId":"v3_upload_edit_references","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v3_upload_edit_references"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditReferenceListResponseV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}},"get":{"tags":["edit references"],"summary":"List a workflow's reference documents","description":"List the reference documents on a workflow, with their parse status.\n\nPoll this after uploading a PDF reference until its `status` leaves\n`pending`.","operationId":"v3_list_edit_references","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditReferenceListResponseV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/workflows/{workflow_id}/edit-references/{document_id}/":{"delete":{"tags":["edit references"],"summary":"Delete a reference document","description":"Delete a reference document and its stored objects.\n\nAn Edit node still naming the deleted id will refuse to run rather than\nfill from a reference that no longer exists — remove the id from the node\nin the same change.","operationId":"v3_delete_edit_reference","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"document_id","in":"path","required":true,"schema":{"type":"string","title":"Document Id"}}],"responses":{"204":{"description":"Successful Response","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/workflows/{workflow_id}/knowledge/ask":{"post":{"tags":["knowledge"],"summary":"Ask a question about a workflow's documents","description":"Answer a question from the content of this workflow's documents.\n\nThe answer is grounded: every claim comes back with the exact quote it\nrests on, resolved to a page and a region in the source PDF, so you can\nshow a customer where a number came from instead of asking them to trust\nit. `path` reports the route the agent took to get there.\n\nThe workflow needs a knowledge node — that is what indexes its documents.\nWithout one this returns 409.\n\nBilled per question against the organization's credits, on the text the\nagent actually reads. A question the organization cannot pay for is\nrefused before it runs, not after.\n\nPass a `thread_id` you mint yourself (starting with `kb-`) to ask a\nfollow-up in context; omit it and each question stands alone.","operationId":"v3_ask_knowledge","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskRequestV3"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskResponseV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"402":{"description":"`PAYMENT_REQUIRED` — the organization has no credits. Refused before the question runs, so nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"`KNOWLEDGE_NOT_ENABLED` — no knowledge node on the workflow, permanent until one is added. `KNOWLEDGE_NOT_READY` — the first index is still building, worth retrying. `KNOWLEDGE_THREAD_MISMATCH` — this `thread_id` belongs to a different workflow.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"504":{"description":"The ask exceeded the agent's own time ceiling. Retry with a narrower question.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/runs/{run_id}/":{"get":{"tags":["runs"],"summary":"Get run","description":"Retrieve one run flat: lifecycle status plus results inline.\n\nAlways 200 while the run exists — no precondition errors while the\nextraction is in flight. `results` is `null` until `status` reaches\n`processed`, then carries the extraction results envelope (the same\nshape as the v2 results endpoint). A run that ended in `error` or\n`cancelled` stays readable with `results: null`.\n\nUnknown ids — including runs belonging to another organization —\nreturn 404.","operationId":"v3_get_run","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunDetailV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/parse/":{"post":{"tags":["parse"],"summary":"Parse a document","description":"Parse one document with the platform's fast lite parse (atomic).\n\nOne file per call. The upload runs against your organization's system\nparse workflow, provisioned automatically on first use. Poll\n`GET /v3/runs/{run_id}/` until `status` is `processed`; the markdown is\nat `results.parse.markdown`.\n\nHonors `Idempotency-Key`: a retried request with the same key replays\nthe original packet and run.","operationId":"v3_parse","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional caller-supplied key (Stripe convention). Retrying the request with the same key replays the original packet AND run — no duplicate upload, no second extraction.","title":"Idempotency-Key"},"description":"Optional caller-supplied key (Stripe convention). Retrying the request with the same key replays the original packet AND run — no duplicate upload, no second extraction."}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_v3_parse"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunTriggeredV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/parse/from-url/":{"post":{"tags":["parse"],"summary":"Parse a document from a URL","description":"Parse one document fetched from a URL with the platform's fast lite\nparse (atomic).\n\nOne HTTPS URL per call. The upload runs against your organization's\nsystem parse workflow, provisioned automatically on first use. Poll\n`GET /v3/runs/{run_id}/` until `status` is `processed`; the markdown is\nat `results.parse.markdown`.\n\nThe file is named by the response's `Content-Disposition` filename when\npresent, else by the last segment of the URL's path.\n\nNot idempotent: every call fetches the URL, creates a packet and starts\na new run. For a retry-safe flow use `POST /v3/workflows/{id}/upload/from-url/`\nand then `POST /v3/document-packets/{id}/run/` with an `Idempotency-Key`.","operationId":"v3_parse_from_url","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseFromUrlRequest"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunTriggeredV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}},"security":[{"ApiKeyAuth":[]}]}},"/v3/workflows/{workflow_id}/evals/":{"post":{"tags":["evals"],"summary":"Launch an eval","description":"Launch an eval over a workflow's whole dataset (async, fire-and-forget).\n\nEnqueues one fresh extraction per dataset document on the target version and\npins the realized cohort into a new eval, then returns `202` immediately with\n`eval_id` and `run_number` to poll. Grading finalizes on a worker path — read\nthe eval by `eval_id` for the headline once it leaves `in_progress`.\n\nWithout an `Idempotency-Key` every launch creates a NEW eval — re-launching\nruns a fresh cohort. Supplying the header replays: a retry with the same key\nreturns the original eval instead of launching a second run. Omit `version_id`\nto evaluate the workflow's current version; pass one to override. (With an\nomitted version, a replayed key sent after a new version was published targets\na different version than the first call, so the backend answers `422` for the\nkey reuse — pass an explicit `version_id` for a stable replay.)\n\nA run that enqueues zero documents (empty dataset, or every document failed\nto enqueue) creates no eval and returns `422 EMPTY_EVAL`.","operationId":"v3_launch_eval","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional caller-supplied key (Stripe convention). Retrying with the same key returns the original eval instead of launching (and billing) a second full-dataset run.","title":"Idempotency-Key"},"description":"Optional caller-supplied key (Stripe convention). Retrying with the same key returns the original eval instead of launching (and billing) a second full-dataset run."}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/EvalLaunchRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvalLaunchedV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}},"get":{"tags":["evals"],"summary":"List evals","description":"List a workflow's evals, newest first.\n\nKeyset-paginated: follow `next_cursor` until it is `null`. The sort order is\nfixed (`-created_at, -id`); there are no totals or page numbers. Each item is\nthe same headline `GET /v3/workflows/{workflow_id}/evals/{eval_id}/` returns.\n\nAn unknown or cross-org workflow returns 404.","operationId":"v3_list_evals","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Page size, capped at 100.","default":20,"title":"Limit"},"description":"Page size, capped at 100."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque token from a previous response's `next_cursor`.","title":"Cursor"},"description":"Opaque token from a previous response's `next_cursor`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvalListPageV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}},"/v3/workflows/{workflow_id}/evals/{eval_id}/":{"get":{"tags":["evals"],"summary":"Get eval","description":"Retrieve one eval's frozen headline — poll this until `status` leaves\n`in_progress`.\n\n`accuracy`, `matched`, `mismatched` and `ungraded` are `null` while the eval\nis `in_progress`; `accuracy` also stays `null` on a `processed` eval with a 0\ngraded denominator. `id` here equals the launch's `eval_id`.\n\nAn unknown eval, or one on another workflow or organization, returns 404\n(existence never leaks).","operationId":"v3_get_eval","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"eval_id","in":"path","required":true,"schema":{"type":"string","title":"Eval Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvalDetailV3"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Authentication failed — missing, invalid, or expired API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"AUTH_FAILED":{"value":{"error":"Authentication failed.","detail":"Authentication failed.","error_code":"AUTH_FAILED","retryable":false,"request_id":"req_abc123"}}}}}},"404":{"description":"Resource not found — the workflow, document packet, or run ID does not exist or is not visible to this API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"NOT_FOUND":{"value":{"error":"Resource not found.","detail":"Resource not found.","error_code":"NOT_FOUND","retryable":false,"request_id":"req_abc123"}}}}}},"429":{"description":"Rate limited — retry after the `Retry-After` header. Default windows: 60 requests/minute for extraction submission, 600 requests/minute for general endpoints.","headers":{"Retry-After":{"description":"Seconds until the next request is allowed.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window (60s).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"RATE_LIMITED":{"value":{"error":"Rate limit exceeded — retry after backoff.","detail":"Rate limit exceeded — retry after backoff.","error_code":"RATE_LIMITED","retryable":true,"request_id":"req_abc123"}}}}}}}}}},"components":{"schemas":{"AllOfCheck":{"properties":{"type":{"type":"string","const":"all_of","title":"Type"},"checks":{"items":{"oneOf":[{"$ref":"#/components/schemas/RangeCheck"},{"$ref":"#/components/schemas/DateCheck"},{"$ref":"#/components/schemas/ArithmeticCheck"},{"$ref":"#/components/schemas/ComparisonCheck"},{"$ref":"#/components/schemas/OneOfCheck"},{"$ref":"#/components/schemas/RegexCheck"},{"$ref":"#/components/schemas/RequiredCheck"},{"$ref":"#/components/schemas/ConfidenceCheck"},{"$ref":"#/components/schemas/ExpressionCheck"},{"$ref":"#/components/schemas/ValidationCheck"},{"$ref":"#/components/schemas/AllOfCheck"},{"$ref":"#/components/schemas/AnyOfCheck"}],"discriminator":{"propertyName":"type","mapping":{"all_of":"#/components/schemas/AllOfCheck","any_of":"#/components/schemas/AnyOfCheck","arithmetic":"#/components/schemas/ArithmeticCheck","comparison":"#/components/schemas/ComparisonCheck","confidence":"#/components/schemas/ConfidenceCheck","date":"#/components/schemas/DateCheck","expression":"#/components/schemas/ExpressionCheck","one_of":"#/components/schemas/OneOfCheck","range":"#/components/schemas/RangeCheck","regex":"#/components/schemas/RegexCheck","required":"#/components/schemas/RequiredCheck","validation":"#/components/schemas/ValidationCheck"}}},"type":"array","maxItems":32,"minItems":1,"title":"Checks"}},"additionalProperties":false,"type":"object","required":["type","checks"],"title":"AllOfCheck","description":"AND combinator — passes iff every sub-check passes.\n\nTri-state: FAIL if any child fails; else INCONCLUSIVE if any child is\ninconclusive; else PASS. Children are the same closed ``Check`` union\n(mutual recursion via forward ref) so combinators nest by construction —\nthe CheckBuilder UI restricts nesting to a single level for MVP.\n\n``max_length=32`` bounds runaway fan-out per combinator. Practical rules\nstay well below the cap; a legitimate use case wanting more should motivate\nthe raise rather than land silently. Nesting-depth is bounded by pydantic's\nown recursion during parse."},"AnyOfCheck":{"properties":{"type":{"type":"string","const":"any_of","title":"Type"},"checks":{"items":{"oneOf":[{"$ref":"#/components/schemas/RangeCheck"},{"$ref":"#/components/schemas/DateCheck"},{"$ref":"#/components/schemas/ArithmeticCheck"},{"$ref":"#/components/schemas/ComparisonCheck"},{"$ref":"#/components/schemas/OneOfCheck"},{"$ref":"#/components/schemas/RegexCheck"},{"$ref":"#/components/schemas/RequiredCheck"},{"$ref":"#/components/schemas/ConfidenceCheck"},{"$ref":"#/components/schemas/ExpressionCheck"},{"$ref":"#/components/schemas/ValidationCheck"},{"$ref":"#/components/schemas/AllOfCheck"},{"$ref":"#/components/schemas/AnyOfCheck"}],"discriminator":{"propertyName":"type","mapping":{"all_of":"#/components/schemas/AllOfCheck","any_of":"#/components/schemas/AnyOfCheck","arithmetic":"#/components/schemas/ArithmeticCheck","comparison":"#/components/schemas/ComparisonCheck","confidence":"#/components/schemas/ConfidenceCheck","date":"#/components/schemas/DateCheck","expression":"#/components/schemas/ExpressionCheck","one_of":"#/components/schemas/OneOfCheck","range":"#/components/schemas/RangeCheck","regex":"#/components/schemas/RegexCheck","required":"#/components/schemas/RequiredCheck","validation":"#/components/schemas/ValidationCheck"}}},"type":"array","maxItems":32,"minItems":1,"title":"Checks"}},"additionalProperties":false,"type":"object","required":["type","checks"],"title":"AnyOfCheck","description":"OR combinator — passes iff any sub-check passes.\n\nTri-state: PASS if any child passes; else INCONCLUSIVE if any child is\ninconclusive; else FAIL.\n\n``max_length=32`` — see :class:`AllOfCheck` for the rationale."},"ArithmeticCheck":{"properties":{"type":{"type":"string","const":"arithmetic","title":"Type"},"operands":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Operands","description":"persistent_ids combined by `operator`."},"operator":{"type":"string","enum":["sum","subtract","product"],"title":"Operator","default":"sum"},"equals":{"type":"string","minLength":1,"title":"Equals","description":"persistent_id whose value the result must equal."},"tolerance":{"type":"number","minimum":0.0,"title":"Tolerance","description":"Absolute slack allowed around `equals`.","default":0.0}},"additionalProperties":false,"type":"object","required":["type","operands","equals"],"title":"ArithmeticCheck"},"AskCitationV3":{"properties":{"path":{"type":"string","title":"Path","description":"Document path inside the workflow's corpus."},"quote":{"type":"string","title":"Quote","description":"The exact span the answer rests on."},"file_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Id","description":"The source file, for downloads and links."},"block_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Block Id","description":"Anchor within the document."},"page":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Page","description":"1-based page in the source PDF."},"bbox":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Bbox","description":"Region on that page, as `{x0, y0, x1, y1}` in relative coordinates."}},"type":"object","required":["path","quote","file_id","block_id","page","bbox"],"title":"AskCitationV3","description":"Where an answer came from, resolved to a place in the source PDF."},"AskRequestV3":{"properties":{"question":{"type":"string","minLength":1,"title":"Question","description":"A question about the content of this workflow's documents.","examples":["Which contracts renew before March and what notice do they need?"]},"thread_id":{"anyOf":[{"type":"string","maxLength":64,"pattern":"^kb-[A-Za-z0-9._-]+$"},{"type":"null"}],"title":"Thread Id","description":"Optional conversation id, minted by you, to ask a follow-up in context. Must start with `kb-`. Reuse it to continue; omit it for a fresh question.","examples":["kb-renewals-q3"]}},"type":"object","required":["question"],"title":"AskRequestV3"},"AskResponseV3":{"properties":{"answer":{"type":"string","title":"Answer"},"citations":{"items":{"$ref":"#/components/schemas/AskCitationV3"},"type":"array","title":"Citations"},"path":{"items":{"$ref":"#/components/schemas/AskStepV3"},"type":"array","title":"Path","description":"The route the agent took to the answer — auditable, not decorative."},"steps_used":{"type":"integer","title":"Steps Used"},"thread_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thread Id","description":"Present when the question was asked in a thread."}},"type":"object","required":["answer","citations","path","steps_used"],"title":"AskResponseV3"},"AskStepV3":{"properties":{"tool":{"type":"string","title":"Tool"},"args":{"additionalProperties":true,"type":"object","title":"Args"}},"type":"object","required":["tool","args"],"title":"AskStepV3","description":"One navigation step the agent took, in order."},"Block":{"properties":{"id":{"type":"string","title":"Id","description":"Stable block identifier in the form `p<page>_b<index>`."},"type":{"type":"string","title":"Type","description":"Semantic type: `text`, `title`, `section-header`, `table`, `picture`, `other`."},"page":{"type":"integer","title":"Page","description":"1-indexed page number this block belongs to."},"bbox":{"additionalProperties":{"type":"number"},"type":"object","title":"Bbox","description":"Normalised bounding box in [0, 1] page coordinates with keys `x0`/`y0`/`x1`/`y1`."},"layout_confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Layout Confidence","description":"0-100 layout detection confidence for this block. `null` when no layout detector ran — the `lite` tier gets its layout from the OCR response, which reports no confidence in the type it assigned."},"parse_confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Parse Confidence","description":"0-100 parse confidence calibrated from LLM logprobs. `null` when logprobs were unavailable (e.g. text-bytes strategy)."},"content":{"type":"string","title":"Content","description":"Raw section body — markdown for text/title blocks, HTML for tables, `<figure-content>` for pictures."},"hyperlinks":{"items":{"$ref":"#/components/schemas/Hyperlink"},"type":"array","title":"Hyperlinks","description":"Hyperlinks found in the content via `[text](uri)` markdown syntax."},"rows":{"anyOf":[{"items":{"items":{"additionalProperties":{"type":"string"},"type":"object"},"type":"array"},"type":"array"},{"type":"null"}],"title":"Rows","description":"2D array of table cells for `type=table` blocks — each cell is `{cell_id, text}`. `null` for non-table blocks."},"image_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Base64","description":"Inline base64-encoded cropped image for `type=picture` blocks. Currently `null` for all blocks — image hydration is performed client-side by the SDK consumer."}},"type":"object","required":["id","type","page","bbox","content"],"title":"Block","description":"One semantic block of a parsed document — a structured alternative to\nwalking `<a id></a>` anchors in `markdown`.\n\nAll blocks expose the common fields (`id`, `type`, `page`, `bbox`,\n`confidence`, `content`). Type-specific structured data lives in the\noptional fields (`rows` for tables, `image_base64` for pictures).\nConsumers can switch on `type` to access the per-type fields, or treat\n`content` as the universal fallback."},"Body_v2_create_workflow_file":{"properties":{"files":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Files"},"on_conflict":{"type":"string","enum":["error","rename"],"title":"On Conflict","description":"How to handle an uploaded filename that already exists in the workflow (filenames are unique within a workflow). `error` (the default) rejects the whole request with `409` and lists the conflicting names, so a rename is never silent — the caller must opt in. `rename` accepts the collision and lets the server auto-rename the file by inserting a ` (n)` counter before the extension (`invoice.pdf` → `invoice (1).pdf`).","default":"error"}},"type":"object","required":["files"],"title":"Body_v2_create_workflow_file"},"Body_v2_parse":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_v2_parse"},"Body_v2_run_workflow":{"properties":{"file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"File"}},"type":"object","title":"Body_v2_run_workflow"},"Body_v2_upload_file":{"properties":{"file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"File"}},"type":"object","title":"Body_v2_upload_file"},"Body_v3_parse":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File","description":"The document to parse."}},"type":"object","required":["file"],"title":"Body_v3_parse"},"Body_v3_upload_and_run_workflow":{"properties":{"files":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Files","description":"1..10 files forming one document packet."},"metadata":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Metadata","description":"Optional JSON-encoded object of free-form metadata attached to the packet. The extract operator may source datapoints from a top-level key whose name matches a schema field."},"on_conflict":{"type":"string","enum":["error","rename"],"title":"On Conflict","description":"How to handle an uploaded filename that already exists in the workflow (filenames are unique within a workflow). `error` (the default) rejects the whole request with `409` and lists the conflicting names, so a rename is never silent — the caller must opt in. `rename` accepts the collision and lets the server auto-rename the file by inserting a ` (n)` counter before the extension (`invoice.pdf` → `invoice (1).pdf`).","default":"error"}},"type":"object","required":["files"],"title":"Body_v3_upload_and_run_workflow"},"Body_v3_upload_edit_references":{"properties":{"files":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Files","description":"1..10 reference documents. Accepted: `.csv`, `.txt`, `.md`, `.rst` and `.pdf`. Content is checked by its bytes, not its extension."}},"type":"object","required":["files"],"title":"Body_v3_upload_edit_references"},"Body_v3_upload_to_dataset":{"properties":{"files":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Files","description":"1..10 files forming ONE document (one document packet in the dataset)."},"ground_truth":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ground Truth","description":"Optional JSON-encoded object: the expected document for this document packet. Keys are the workflow schema's field identifiers — advertise `persistent_id` (the API also accepts `sanitized_name`). A scalar field maps to `string | null`; a table/object field maps to an array of row objects. Ground truth attaches to the workflow's current version."},"on_conflict":{"type":"string","enum":["error","rename"],"title":"On Conflict","description":"How to handle an uploaded filename that already exists in the workflow (filenames are unique within a workflow). `error` (the default) rejects the whole request with `409` and lists the conflicting names, so a rename is never silent — the caller must opt in. `rename` accepts the collision and lets the server auto-rename the file by inserting a ` (n)` counter before the extension (`invoice.pdf` → `invoice (1).pdf`).","default":"error"}},"type":"object","required":["files"],"title":"Body_v3_upload_to_dataset"},"Body_v3_upload_to_workflow":{"properties":{"files":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Files","description":"1..10 files forming one document packet."},"metadata":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Metadata","description":"Optional JSON-encoded object of free-form metadata attached to the packet. The extract operator may source datapoints from a top-level key whose name matches a schema field."},"on_conflict":{"type":"string","enum":["error","rename"],"title":"On Conflict","description":"How to handle an uploaded filename that already exists in the workflow (filenames are unique within a workflow). `error` (the default) rejects the whole request with `409` and lists the conflicting names, so a rename is never silent — the caller must opt in. `rename` accepts the collision and lets the server auto-rename the file by inserting a ` (n)` counter before the extension (`invoice.pdf` → `invoice (1).pdf`).","default":"error"}},"type":"object","required":["files"],"title":"Body_v3_upload_to_workflow"},"BooleanField":{"properties":{"persistent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Persistent Id","description":"Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit for new fields; when omitted on an update, the server matches the field to the prior version by name."},"name":{"type":"string","minLength":1,"title":"Name","description":"Field name. Used as the key in the extraction response."},"description":{"type":"string","title":"Description","description":"Free-form description shown to the extraction model.","default":""},"source":{"type":"string","enum":["extraction","smart_lookup","lookup_if_missing"],"title":"Source","description":"How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).","default":"extraction"},"data_type":{"type":"string","const":"boolean","title":"Data Type"}},"additionalProperties":false,"type":"object","required":["name","data_type"],"title":"BooleanField"},"ClassificationResult":{"properties":{"category":{"type":"string","title":"Category","description":"The category the document was classified as."},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence","description":"0-100 model confidence in the verdict. `null` when the verdict carries no score, because nothing was measured."},"evidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Evidence","description":"Free-form evidence text (the snippets the classifier cited). `null` when none captured."}},"type":"object","required":["category","confidence"],"title":"ClassificationResult","description":"One classifier verdict for the collection."},"ClassifyCategory":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable category id used as the edge `branch` value when routing."},"name":{"type":"string","minLength":1,"title":"Name","description":"Display name shown to the LLM; classification and routing key off it, so it must be unique across categories."},"description":{"type":"string","minLength":1,"title":"Description","description":"Free-form description shown to the LLM."}},"additionalProperties":false,"type":"object","required":["id","name","description"],"title":"ClassifyCategory"},"ClassifyNode":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable identifier for this node within the graph."},"type":{"type":"string","const":"classify","title":"Type"},"user_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Prompt","description":"Optional extra instructions inserted between the classifier's system prompt and the document text."},"categories":{"items":{"$ref":"#/components/schemas/ClassifyCategory"},"type":"array","minItems":1,"title":"Categories"}},"additionalProperties":false,"type":"object","required":["id","type","categories"],"title":"ClassifyNode"},"CollectionListItem":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the file collection.","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e1"]},"file_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Id","description":"The file's UUID — pass to POST /v2/workflows/{id}/files/{file_id}/run/ to run it.","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e2"]},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Human-readable name for the collection.","examples":["Collection for Invoice Processing"]},"status":{"type":"string","enum":["not_started","queued","in_progress","processed","error","cancelled"],"title":"Status","description":"Processing status. Non-terminal: `not_started` (no extraction yet), `queued`, `in_progress`. Terminal: `processed` (success), `error`, `cancelled`.","examples":["processed"]},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At","description":"Timestamp when the collection was created (ISO 8601)."},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At","description":"Timestamp when the collection was last updated (ISO 8601)."}},"type":"object","required":["id","status"],"title":"CollectionListItem","description":"A file collection entry in list responses. Each collection groups one or more uploaded files and tracks their extraction status."},"ComparisonCheck":{"properties":{"type":{"type":"string","const":"comparison","title":"Type"},"left":{"type":"string","minLength":1,"title":"Left","description":"persistent_id of the left-hand field."},"op":{"type":"string","enum":["==","!=",">",">=","<","<="],"title":"Op"},"right":{"oneOf":[{"$ref":"#/components/schemas/_FieldOperand"},{"$ref":"#/components/schemas/_LiteralOperand"}],"title":"Right","discriminator":{"propertyName":"source","mapping":{"field":"#/components/schemas/_FieldOperand","literal":"#/components/schemas/_LiteralOperand"}}}},"additionalProperties":false,"type":"object","required":["type","left","op","right"],"title":"ComparisonCheck"},"ConfidenceCheck":{"properties":{"type":{"type":"string","const":"confidence","title":"Type"},"field":{"type":"string","minLength":1,"title":"Field","description":"Field whose extraction confidence to compare. Either the ``persistent_id`` (Studio field-picker path) or the ``sanitized_name`` (SDK/API/assistant path) — the executor resolves both against the workflow's field tree, same as ``ValidateNode`` deterministic checks."},"op":{"type":"string","enum":["<","<=",">",">=","==","!="],"title":"Op"},"threshold":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Threshold","description":"Confidence percentile 0..100."}},"additionalProperties":false,"type":"object","required":["type","field","op","threshold"],"title":"ConfidenceCheck"},"CreateCollectionResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the newly created file collection.","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e1"]},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Human-readable name for the collection."},"files":{"items":{"$ref":"#/components/schemas/FileItem"},"type":"array","title":"Files","description":"List of files included in the collection, with their upload status."},"workflow_id":{"type":"string","title":"Workflow Id","description":"The UUID of the workflow this collection belongs to.","examples":["0686bb97-8c30-70f0-8000-97669e000eb8"]},"rejected":{"items":{"$ref":"#/components/schemas/RejectedFileItem"},"type":"array","title":"Rejected","description":"Files the backend refused to accept — unsupported extension at slot-time or disguised bytes at register-time. Empty when every file uploaded cleanly."}},"type":"object","required":["id","files","workflow_id"],"title":"CreateCollectionResponse","description":"Response from creating a file collection. Contains the collection ID and the status of each uploaded file."},"CreateDocumentPacketFromUrlRequest":{"properties":{"url":{"type":"string","title":"Url","description":"HTTPS URL the backend will fetch the file bytes from.","examples":["https://example.com/invoices/april.pdf"]},"filename":{"type":"string","title":"Filename","description":"Filename to record on the uploaded file.","examples":["april.pdf"]},"content_type":{"type":"string","title":"Content Type","description":"MIME type of the file. Leave empty to use the URL's response Content-Type header.","default":"","examples":["application/pdf"]},"on_conflict":{"type":"string","enum":["error","rename"],"title":"On Conflict","description":"How to handle an uploaded filename that already exists in the workflow (filenames are unique within a workflow). `error` (the default) rejects the whole request with `409` and lists the conflicting names, so a rename is never silent — the caller must opt in. `rename` accepts the collision and lets the server auto-rename the file by inserting a ` (n)` counter before the extension (`invoice.pdf` → `invoice (1).pdf`).","default":"error"}},"type":"object","required":["url","filename"],"title":"CreateDocumentPacketFromUrlRequest","description":"Payload for creating a document packet from a single remote URL.\n\nSingle URL per request keeps the wire shape predictable; SDKs that need\nbatches wrap the call. ``content_type`` may be empty — the backend\nfalls back to the response's ``Content-Type`` header in that case.\n\nOnly HTTPS URLs are accepted. The backend additionally runs a DNS+IP\nSSRF guard before the fetch — URLs whose hostname resolves to a\nnon-globally-routable IP (per IANA ``is_global``: loopback, RFC1918,\nlink-local incl. cloud-metadata 169.254.169.254, IPv6 ULA, multicast,\nreserved, IPv4-mapped IPv6) are refused. Enforcing the scheme at the\ngateway means malformed requests fail fast without traversing the\nbackend."},"DatasetUploadFileV3":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the file (hyphenated UUID).","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e2"]},"name":{"type":"string","title":"Name","description":"Filename the file is stored under.","examples":["invoice.pdf"]},"original_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Original Name","description":"The name you uploaded, present only when the file was auto-renamed (`on_conflict=rename` resolving a collision). `null` when the stored `name` is the name you sent."}},"type":"object","required":["id","name"],"title":"DatasetUploadFileV3","description":"Per-file entry in a dataset-upload response."},"DatasetUploadResponseV3":{"properties":{"document_packet_id":{"type":"string","title":"Document Packet Id","description":"Unique identifier of the created dataset document packet (hyphenated UUID).","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e1"]},"files":{"items":{"$ref":"#/components/schemas/DatasetUploadFileV3"},"type":"array","title":"Files","description":"Files in the packet, in the order they were provided."},"ground_truth_saved":{"type":"boolean","title":"Ground Truth Saved","description":"Whether ground truth was supplied and saved for this document packet."}},"type":"object","required":["document_packet_id","files","ground_truth_saved"],"title":"DatasetUploadResponseV3","description":"Response for `POST /v3/workflows/{workflow_id}/dataset/upload/`.\n\nOne dataset document packet, all-or-nothing. `document_packet_id` is the\nstable handle for the deferred ground-truth-edit follow-up."},"DateCheck":{"properties":{"type":{"type":"string","const":"date","title":"Type"},"field":{"type":"string","minLength":1,"title":"Field","description":"persistent_id of the date field."},"earliest":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Earliest"},"latest":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Latest"}},"additionalProperties":false,"type":"object","required":["type","field"],"title":"DateCheck"},"DateField":{"properties":{"persistent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Persistent Id","description":"Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit for new fields; when omitted on an update, the server matches the field to the prior version by name."},"name":{"type":"string","minLength":1,"title":"Name","description":"Field name. Used as the key in the extraction response."},"description":{"type":"string","title":"Description","description":"Free-form description shown to the extraction model.","default":""},"source":{"type":"string","enum":["extraction","smart_lookup","lookup_if_missing"],"title":"Source","description":"How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).","default":"extraction"},"data_type":{"type":"string","const":"date","title":"Data Type"}},"additionalProperties":false,"type":"object","required":["name","data_type"],"title":"DateField"},"DatetimeField":{"properties":{"persistent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Persistent Id","description":"Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit for new fields; when omitted on an update, the server matches the field to the prior version by name."},"name":{"type":"string","minLength":1,"title":"Name","description":"Field name. Used as the key in the extraction response."},"description":{"type":"string","title":"Description","description":"Free-form description shown to the extraction model.","default":""},"source":{"type":"string","enum":["extraction","smart_lookup","lookup_if_missing"],"title":"Source","description":"How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).","default":"extraction"},"data_type":{"type":"string","const":"datetime","title":"Data Type"}},"additionalProperties":false,"type":"object","required":["name","data_type"],"title":"DatetimeField"},"DocumentPacketCreatedFileV3":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the file (hyphenated UUID).","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e2"]},"name":{"type":"string","title":"Name","description":"Filename the file is stored under. Filenames are unique within a workflow: a name that collides with an existing file is auto-renamed by inserting a ` (n)` counter before the extension (e.g. `invoice.pdf` → `invoice (1).pdf`).","examples":["invoice.pdf"]},"original_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Original Name","description":"The name you uploaded, present only when the file was auto-renamed to avoid a duplicate name in the workflow. `null` when `name` is the name you uploaded.","examples":["invoice.pdf"]}},"type":"object","required":["id","name"],"title":"DocumentPacketCreatedFileV3","description":"Per-file entry in an upload/create response.\n\nAdds ``original_name`` on top of the slim projection: the name the caller\nuploaded, surfaced only when the file was auto-renamed to avoid a duplicate\nname in the workflow. The original name is not persisted alongside the\nstored ``name``, so this only appears on the response to the request that\ncreated the file — later reads expose ``name`` alone."},"DocumentPacketCreatedV3":{"properties":{"document_packet_id":{"type":"string","title":"Document Packet Id","description":"Unique identifier of the newly created document packet (hyphenated UUID).","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e1"]},"workflow_id":{"type":"string","title":"Workflow Id","description":"The workflow the packet was created under (hyphenated UUID).","examples":["0686bb97-8c30-70f0-8000-97669e000eb8"]},"files":{"items":{"$ref":"#/components/schemas/DocumentPacketCreatedFileV3"},"type":"array","title":"Files","description":"Files in the packet, in the order they were provided."}},"type":"object","required":["document_packet_id","workflow_id","files"],"title":"DocumentPacketCreatedV3","description":"Response for the packet-creating uploads (multipart and from-url)."},"DocumentPacketDetailV3":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the document packet (hyphenated UUID).","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e1"]},"workflow_id":{"type":"string","title":"Workflow Id","description":"The workflow this packet belongs to (hyphenated UUID).","examples":["0686bb97-8c30-70f0-8000-97669e000eb8"]},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Human-readable name of the packet."},"status":{"$ref":"#/components/schemas/DocumentPacketStatus","description":"Processing status. Non-terminal: `not_started`, `queued`, `in_progress`. Terminal: `processed` (success), `error`, `cancelled`.","examples":["processed"]},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At","description":"Timestamp when the packet was created (ISO 8601)."},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At","description":"Timestamp when the packet was last updated (ISO 8601)."},"files":{"items":{"$ref":"#/components/schemas/DocumentPacketFileV3"},"type":"array","title":"Files","description":"Files in this packet."},"latest_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Latest Run Id","description":"Id of the packet's most recent run (hyphenated UUID); `null` until the packet has been run."},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata","description":"Free-form JSON supplied at packet creation. No schema is enforced; the extract operator may source datapoints from a top-level key whose name matches a schema field. `null` when no metadata was attached."}},"type":"object","required":["id","workflow_id","status","files"],"title":"DocumentPacketDetailV3","description":"A packet with its per-file breakdown and latest run reference."},"DocumentPacketFileV3":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the file (hyphenated UUID).","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e2"]},"name":{"type":"string","title":"Name","description":"Filename the file is stored under. Filenames are unique within a workflow: a name that collides with an existing file is auto-renamed by inserting a ` (n)` counter before the extension (e.g. `invoice.pdf` → `invoice (1).pdf`).","examples":["invoice.pdf"]}},"type":"object","required":["id","name"],"title":"DocumentPacketFileV3","description":"Slim per-file projection inside a packet."},"DocumentPacketFromUrlsRequest":{"properties":{"urls":{"items":{"type":"string"},"type":"array","maxItems":10,"minItems":1,"title":"Urls","description":"HTTPS URLs the backend fetches server-side (1..10). Each file is named by the response's `Content-Disposition` filename when present, else by the last segment of the URL's path.","examples":[["https://example.com/invoices/april.pdf"]]},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata","description":"Free-form JSON to attach to the packet. No schema is enforced; the extract operator may source datapoints from a top-level key whose name matches a schema field."},"on_conflict":{"type":"string","enum":["error","rename"],"title":"On Conflict","description":"How to handle an uploaded filename that already exists in the workflow (filenames are unique within a workflow). `error` (the default) rejects the whole request with `409` and lists the conflicting names, so a rename is never silent — the caller must opt in. `rename` accepts the collision and lets the server auto-rename the file by inserting a ` (n)` counter before the extension (`invoice.pdf` → `invoice (1).pdf`).","default":"error"}},"type":"object","required":["urls"],"title":"DocumentPacketFromUrlsRequest","description":"Body for ``POST /v3/workflows/{workflow_id}/upload/from-url/``.\n\nEvery URL imports into a single packet atomically — any fetch or\nvalidation failure means nothing is persisted.","examples":[{"urls":["https://example.com/invoices/april.pdf","https://example.com/invoices/april-annex.pdf"]}]},"DocumentPacketListPageV3":{"properties":{"items":{"items":{"$ref":"#/components/schemas/DocumentPacketSummaryV3"},"type":"array","title":"Items","description":"Packets on this page, newest first."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Opaque token to fetch the next page; pass it back as `?cursor=`. `null` on the last page."}},"type":"object","required":["items"],"title":"DocumentPacketListPageV3","description":"One keyset page of document packets.\n\nFixed ``(-created_at, -id)`` order. No totals or page numbers —\niterate by following ``next_cursor`` until it is null."},"DocumentPacketStatus":{"type":"string","enum":["not_started","queued","in_progress","processed","error","cancelled"],"title":"DocumentPacketStatus","description":"Extraction lifecycle of a packet. Non-terminal: ``not_started``\n(no run yet), ``queued``, ``in_progress``. Terminal: ``processed``\n(success), ``error``, ``cancelled``."},"DocumentPacketSummaryV3":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the document packet (hyphenated UUID).","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e1"]},"workflow_id":{"type":"string","title":"Workflow Id","description":"The workflow this packet belongs to (hyphenated UUID).","examples":["0686bb97-8c30-70f0-8000-97669e000eb8"]},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Human-readable name of the packet."},"status":{"$ref":"#/components/schemas/DocumentPacketStatus","description":"Processing status. Non-terminal: `not_started`, `queued`, `in_progress`. Terminal: `processed` (success), `error`, `cancelled`.","examples":["processed"]},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At","description":"Timestamp when the packet was created (ISO 8601)."},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At","description":"Timestamp when the packet was last updated (ISO 8601)."}},"type":"object","required":["id","workflow_id","status"],"title":"DocumentPacketSummaryV3","description":"Slim packet projection returned by list pages."},"Edge":{"properties":{"source":{"type":"string","minLength":1,"title":"Source"},"target":{"type":"string","minLength":1,"title":"Target"},"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Branch","description":"Source-port label for branch routing. Required when leaving a classify or splitter node by category/rule."}},"additionalProperties":false,"type":"object","required":["source","target"],"title":"Edge","description":"A directed edge between two nodes. ``branch`` carries the source-port label\nused for routing out of ``classify`` (category id) or ``splitter`` (rule id) nodes."},"Edit":{"properties":{"file_id":{"type":"string","title":"File Id","description":"The UUID of the file this form was filled from."},"file_name":{"type":"string","title":"File Name","description":"The file's display name."},"fields":{"items":{"$ref":"#/components/schemas/EditFormField"},"type":"array","title":"Fields","description":"Every form field detected in the document, filled or not, in document order."},"unmatched_instructions":{"items":{"type":"string"},"type":"array","title":"Unmatched Instructions","description":"Instruction fragments, quoted verbatim, that matched no field in this document."},"download_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Download Url","description":"Presigned link to the filled PDF, valid for 15 minutes from the moment this response was built. Re-read the results endpoint for a fresh link. `null` when no filled PDF was stored."}},"type":"object","required":["file_id","file_name"],"title":"Edit","description":"One edit node's filled form for one file of the collection: the values\nwritten into the document's fields, plus a short-lived link to the filled\nPDF. One entry per file the edit node processed."},"EditFormField":{"properties":{"form_field_id":{"type":"string","title":"Form Field Id","description":"Stable identifier for this form field within the document, in the form `p<page>_f<index>`."},"label":{"type":"string","title":"Label","description":"The field's own printed caption, verbatim from the document."},"kind":{"type":"string","title":"Kind","description":"`checkbox` for a tick target, `text` for anything else."},"state":{"type":"string","title":"State","description":"`empty` if the field was blank in the source document and therefore fillable, `prefilled` if the document already carried a value. Prefilled fields are never overwritten, so they always read back with `value: null`."},"page":{"type":"integer","title":"Page","description":"1-indexed page number the field sits on."},"bbox":{"additionalProperties":{"type":"number"},"type":"object","title":"Bbox","description":"The field's fillable area as a normalised bounding box in [0, 1] page coordinates, keys `x0`/`y0`/`x1`/`y1`."},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value","description":"The value written into the field — the literal string `true`/`false` for a `checkbox`. `null` when no instruction addressed this field."},"confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Confidence","description":"Raw, uncalibrated 0-100 match score for pairing an instruction with this field. It grades how surely the instruction addresses the field, not whether the written value is correct, and it is not a probability. `null` when no instruction addressed this field, because nothing was measured."}},"type":"object","required":["form_field_id","label","kind","state","page","bbox","value","confidence"],"title":"EditFormField","description":"One form field the edit node detected, with the value it wrote in."},"EditReferenceDocumentV3":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the reference document (hyphenated UUID). This is the value to put in an Edit node's `reference_document_ids`.","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e2"]},"name":{"type":"string","title":"Name","description":"Filename the reference is stored under.","examples":["company-profile.csv"]},"status":{"type":"string","enum":["pending","ready","failed"],"title":"Status","description":"`ready`: usable by a run. `pending`: a PDF still being parsed — text formats are never pending. `failed`: parsing did not complete; `error` says why. A run whose Edit node names a reference that is not `ready` is refused rather than filled from a partial reference."},"truncated":{"type":"boolean","title":"Truncated","description":"Whether the parsed text was cut at the per-reference size cap. The document is still usable; the tail of it simply is not part of what the node fills from."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Why parsing failed. `null` unless `status` is `failed`."},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","name","status","truncated","created_at","updated_at"],"title":"EditReferenceDocumentV3"},"EditReferenceListResponseV3":{"properties":{"documents":{"items":{"$ref":"#/components/schemas/EditReferenceDocumentV3"},"type":"array","title":"Documents","description":"Reference documents on this workflow, newest last."}},"type":"object","required":["documents"],"title":"EditReferenceListResponseV3","description":"Response for the upload and list endpoints alike.\n\nThe same shape both ways so a caller can poll the list endpoint with the\nexact model it got back from the upload."},"EnumField":{"properties":{"persistent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Persistent Id","description":"Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit for new fields; when omitted on an update, the server matches the field to the prior version by name."},"name":{"type":"string","minLength":1,"title":"Name","description":"Field name. Used as the key in the extraction response."},"description":{"type":"string","title":"Description","description":"Free-form description shown to the extraction model.","default":""},"source":{"type":"string","enum":["extraction","smart_lookup","lookup_if_missing"],"title":"Source","description":"How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).","default":"extraction"},"data_type":{"type":"string","const":"enum","title":"Data Type"},"enum_options":{"items":{"$ref":"#/components/schemas/EnumOption"},"type":"array","minItems":1,"title":"Enum Options"}},"additionalProperties":false,"type":"object","required":["name","data_type","enum_options"],"title":"EnumField"},"EnumOption":{"properties":{"name":{"type":"string","minLength":1,"title":"Name"},"description":{"type":"string","minLength":1,"title":"Description","description":"Free-form description shown to the model."}},"additionalProperties":false,"type":"object","required":["name","description"],"title":"EnumOption"},"EvalDetailV3":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the eval (hyphenated UUID); equals the launch's `eval_id`.","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4f9"]},"run_number":{"type":"integer","title":"Run Number","description":"Per-workflow run counter (#1, #2, …) for this eval.","examples":[3]},"version_id":{"type":"string","title":"Version Id","description":"Workflow version the eval scored.","examples":["abcdef1234"]},"status":{"$ref":"#/components/schemas/EvalStatus","description":"Grading status. Non-terminal: `in_progress`. Terminal: `processed`, `error`.","examples":["processed"]},"accuracy":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Accuracy","description":"Headline accuracy in [0, 1]; `null` while `in_progress` and on a `processed` eval with a 0 graded denominator.","examples":[0.94]},"matched":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Matched","description":"Fields that matched ground truth; `null` while `in_progress`."},"mismatched":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Mismatched","description":"Fields that mismatched ground truth; `null` while `in_progress`."},"ungraded":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ungraded","description":"Fields with no ground truth to grade against; `null` while `in_progress`."},"file_count":{"type":"integer","title":"File Count","description":"Number of dataset documents in the eval's realized cohort.","examples":[42]},"failed_count":{"type":"integer","title":"Failed Count","description":"Number of dataset documents that failed to enqueue for this run.","examples":[0]},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At","description":"Timestamp when the eval was created (ISO 8601)."}},"type":"object","required":["id","run_number","version_id","status","file_count","failed_count"],"title":"EvalDetailV3","description":"One eval's frozen headline — the poll target for a launched run.\n\n``id`` here is the same identifier the launch returned as ``eval_id``. The\nheadline fields (``accuracy``, ``matched``, ``mismatched``, ``ungraded``)\nare ``null`` while ``status`` is ``in_progress``; ``accuracy`` stays ``null``\non a ``processed`` eval whose graded denominator is 0."},"EvalLaunchRequest":{"properties":{"version_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version Id","description":"Workflow version to evaluate. Omit to run against the workflow's current version; pass a value to override.","examples":["abcdef1234"]}},"type":"object","title":"EvalLaunchRequest","description":"Body for ``POST /v3/workflows/{workflow_id}/evals/`` (JSON, optional).\n\nSend ``{}`` (or no body) to evaluate the workflow's current version."},"EvalLaunchedV3":{"properties":{"eval_id":{"type":"string","title":"Eval Id","description":"Unique identifier of the new eval (hyphenated UUID); the poll handle.","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4f9"]},"run_number":{"type":"integer","title":"Run Number","description":"Per-workflow run counter (#1, #2, …) for this eval.","examples":[3]},"enqueued_count":{"type":"integer","title":"Enqueued Count","description":"Number of dataset documents whose extraction was enqueued for this run.","examples":[42]},"failed_count":{"type":"integer","title":"Failed Count","description":"Number of dataset documents that failed to enqueue. Read the eval for the failed document ids.","examples":[0]}},"type":"object","required":["eval_id","run_number","enqueued_count","failed_count"],"title":"EvalLaunchedV3","description":"202 response: the eval was created and its cohort enqueued.\n\nExposes counts, never the internal extraction/file ids. Read the eval by\n``eval_id`` for the per-document breakdown (including which documents\nfailed to enqueue)."},"EvalListPageV3":{"properties":{"items":{"items":{"$ref":"#/components/schemas/EvalDetailV3"},"type":"array","title":"Items","description":"Evals on this page, newest first."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Opaque token to fetch the next page; pass it back as `?cursor=`. `null` on the last page."}},"type":"object","required":["items"],"title":"EvalListPageV3","description":"One keyset page of evals.\n\nFixed ``(-created_at, -id)`` order. No totals or page numbers — iterate by\nfollowing ``next_cursor`` until it is null."},"EvalStatus":{"type":"string","enum":["in_progress","processed","error"],"title":"EvalStatus","description":"Grading lifecycle of an eval. Non-terminal: ``in_progress`` (the headline\nfields are null). Terminal: ``processed`` (graded) and ``error``."},"Evidence":{"properties":{"text":{"type":"string","title":"Text","description":"The exact source-text snippet that supports the extracted value."},"page_number":{"type":"integer","title":"Page Number","description":"1-indexed page number where the snippet was found."}},"type":"object","required":["text","page_number"],"title":"Evidence","description":"A snippet of source text supporting an extracted value, with the page it came from.\n\nWhen ``text`` starts with ``metadata.``, the value was sourced from the\npacket's caller-supplied metadata (not the document): the remainder is\nthe JSON path into that metadata, and ``page_number`` is ``0``. Encoded\nin ``text`` on purpose — same wire shape as document evidence, no schema\nchange for SDK consumers."},"ExpressionCheck":{"properties":{"type":{"type":"string","const":"expression","title":"Type"},"expression":{"type":"string","maxLength":1000,"minLength":1,"title":"Expression"}},"additionalProperties":false,"type":"object","required":["type","expression"],"title":"ExpressionCheck","description":"A CEL expression over the whole extraction, evaluated in a sandbox.\n\nThe expression reads one root variable ``data`` and addresses fields by\nextracted name (``data.total``, ``data.lineas.map(l, l.importe)``), never by\n``persistent_id`` — so ``field_ids`` returns ``[]`` for it, and a field\nrename silently breaks the rule. An expression the evaluator cannot parse,\ncannot answer with a boolean, or prices above its evaluation budget reports\n``inconclusive``.\n\nADR platform/0036 records why the CEL parser stays out of this package, so\n``expression`` is unvalidated here."},"ExtractedField":{"properties":{"value":{"anyOf":[{},{"type":"null"}],"title":"Value","description":"The extracted value. Type depends on the field's `data_type` (string, number, date, etc.). `null` when extraction could not produce a value."},"value_override":{"anyOf":[{},{"type":"null"}],"title":"Value Override","description":"A human-supplied override of the extracted `value`, if one was set during verification. `null` when no override exists."},"verification_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verification Status","description":"Verification state for this datapoint (e.g. `not_verified`, `verified`). `null` when not yet reviewed."},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence","description":"Model confidence in the extracted value, on a 0-100 scale. `null` when the backend did not produce a confidence (e.g. manual entry)."},"evidence":{"items":{"$ref":"#/components/schemas/Evidence"},"type":"array","title":"Evidence","description":"Source-text snippets the model used to derive this value."}},"type":"object","required":["value"],"title":"ExtractedField","description":"One extracted field's value, confidence, and supporting evidence."},"Extraction":{"properties":{"split_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Split Name","description":"The split category this extraction belongs to. `null` for linear workflows."},"partition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partition","description":"The partition value within the split. `null` when the split has no partitions."},"fields":{"additionalProperties":{"anyOf":[{"$ref":"#/components/schemas/ExtractedField"},{"items":{"additionalProperties":{"$ref":"#/components/schemas/ExtractedField"},"type":"object"},"type":"array"}]},"type":"object","title":"Fields","description":"Extracted fields keyed by field name. Same shape as the legacy top-level `extraction`."},"validations":{"items":{"$ref":"#/components/schemas/Validation"},"type":"array","title":"Validations","description":"Verdicts of the validate node that ran on this extraction, one per rule. Empty when the workflow has no validate node."}},"type":"object","required":["fields"],"title":"Extraction","description":"One unit of extracted data. For linear (parse->extract) workflows there\nis exactly one entry with `split_name=null` and `partition=null`. For split\nworkflows there is one entry per (split, partition) pair; join with\n`splits[]` by `split_name` to look up geometry."},"ExtractionSchema":{"properties":{"fields":{"items":{"oneOf":[{"$ref":"#/components/schemas/StringField"},{"$ref":"#/components/schemas/IntegerField"},{"$ref":"#/components/schemas/FloatField"},{"$ref":"#/components/schemas/BooleanField"},{"$ref":"#/components/schemas/DateField"},{"$ref":"#/components/schemas/DatetimeField"},{"$ref":"#/components/schemas/EnumField"},{"$ref":"#/components/schemas/MultiSelectField"},{"$ref":"#/components/schemas/ObjectField"}],"discriminator":{"propertyName":"data_type","mapping":{"boolean":"#/components/schemas/BooleanField","date":"#/components/schemas/DateField","datetime":"#/components/schemas/DatetimeField","enum":"#/components/schemas/EnumField","float":"#/components/schemas/FloatField","integer":"#/components/schemas/IntegerField","multi_select":"#/components/schemas/MultiSelectField","object":"#/components/schemas/ObjectField","string":"#/components/schemas/StringField"}}},"type":"array","minItems":1,"title":"Fields","description":"Field definitions making up this extract's output."}},"additionalProperties":false,"type":"object","required":["fields"],"title":"ExtractionSchema","description":"Schema describing what an extract node produces.\n\nModeled as a typed object (not a bare ``list[AnyField]``) so metadata\ncan be added later (versioning, derived flags, output-shape hints)\nwithout another wire-format break. At least one field is required."},"FileItem":{"properties":{"filename":{"type":"string","title":"Filename","description":"Name the file was stored under. Two files in the same workflow can't share a name — if the uploaded name collides with an existing file, it is auto-renamed by inserting a ` (n)` counter before the extension (e.g. `invoice.pdf` -> `invoice (1).pdf`). When that happens, `original_filename` holds the name you uploaded.","examples":["invoice.pdf"]},"original_filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Original Filename","description":"The name you uploaded, present only when the file was auto-renamed to avoid a duplicate name in the workflow. `null` when `filename` is the name you uploaded.","examples":["invoice.pdf"]},"status":{"type":"string","title":"Status","description":"Initial status of the file at the moment the response is returned. Multipart upload (`POST .../files/`) returns `uploaded` or `failed` synchronously. URL ingestion (`POST .../files/from-url/`) returns `pending` while the server fetches the bytes asynchronously. The file listing's `status` field reflects extraction state, not upload state — trigger a workflow run on the returned collection to drive the file through the `queued` / `in_progress` / `processed` lifecycle.","examples":["uploaded"]}},"type":"object","required":["filename","status"],"title":"FileItem","description":"A single file within a collection, showing its name and upload status."},"FilePages":{"properties":{"file_id":{"type":"string","title":"File Id","description":"The file's UUID."},"file_name":{"type":"string","title":"File Name","description":"The file's display name."},"pages":{"items":{"type":"integer"},"type":"array","title":"Pages","description":"1-indexed page numbers from this file."}},"type":"object","required":["file_id","file_name","pages"],"title":"FilePages","description":"A file's contribution of pages to a split or partition. 1-indexed."},"FloatField":{"properties":{"persistent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Persistent Id","description":"Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit for new fields; when omitted on an update, the server matches the field to the prior version by name."},"name":{"type":"string","minLength":1,"title":"Name","description":"Field name. Used as the key in the extraction response."},"description":{"type":"string","title":"Description","description":"Free-form description shown to the extraction model.","default":""},"source":{"type":"string","enum":["extraction","smart_lookup","lookup_if_missing"],"title":"Source","description":"How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).","default":"extraction"},"data_type":{"type":"string","const":"float","title":"Data Type"}},"additionalProperties":false,"type":"object","required":["name","data_type"],"title":"FloatField"},"GroundTruthErrorDetail":{"properties":{"errors":{"items":{"$ref":"#/components/schemas/GroundTruthErrorItem"},"type":"array","title":"Errors","description":"One entry per offending ground-truth key."}},"type":"object","required":["errors"],"title":"GroundTruthErrorDetail","description":"`detail` body of a `422 GT_INVALID` error."},"GroundTruthErrorItem":{"properties":{"field":{"type":"string","title":"Field","description":"Dotted path to the offending ground-truth key.","examples":["line_items.0.sku"]},"msg":{"type":"string","title":"Msg","description":"Human-readable reason the value was rejected."}},"type":"object","required":["field","msg"],"title":"GroundTruthErrorItem","description":"One ground-truth validation error.\n\nStable public remap of the backend's pydantic `{type, loc, msg}`: `field`\nis the dotted path from `loc`, `msg` is kept, the raw pydantic `type` is\ndropped so the public contract never leaks the validator name."},"GroundTruthInvalidError":{"properties":{"error":{"type":"string","title":"Error","examples":["Ground truth validation failed"]},"detail":{"$ref":"#/components/schemas/GroundTruthErrorDetail"},"error_code":{"type":"string","const":"GT_INVALID","title":"Error Code","default":"GT_INVALID"},"retryable":{"type":"boolean","title":"Retryable","default":false},"request_id":{"type":"string","title":"Request Id","description":"Correlates this response with the server logs."}},"type":"object","required":["error","detail","request_id"],"title":"GroundTruthInvalidError","description":"`422 GT_INVALID` error envelope: the supplied ground truth failed validation.\n\n`detail.errors` lists each offending key. The other 422 reasons on this route\n(unsupported bytes, an unresolved extract node, an invalid request) reuse the\nstandard error envelope with a string `detail`."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthCheckResponse":{"properties":{"message":{"type":"string","title":"Message","description":"Status message. Returns `\"ok\"` when the service is healthy.","examples":["ok"]}},"type":"object","required":["message"],"title":"HealthCheckResponse","description":"Health check response confirming the API is operational."},"Hyperlink":{"properties":{"text":{"type":"string","title":"Text","description":"The display text of the link."},"uri":{"type":"string","title":"Uri","description":"The link target (URL, mailto:, etc.)."}},"type":"object","required":["text","uri"],"title":"Hyperlink","description":"A hyperlink found inside a block's content."},"IntegerField":{"properties":{"persistent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Persistent Id","description":"Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit for new fields; when omitted on an update, the server matches the field to the prior version by name."},"name":{"type":"string","minLength":1,"title":"Name","description":"Field name. Used as the key in the extraction response."},"description":{"type":"string","title":"Description","description":"Free-form description shown to the extraction model.","default":""},"source":{"type":"string","enum":["extraction","smart_lookup","lookup_if_missing"],"title":"Source","description":"How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).","default":"extraction"},"data_type":{"type":"string","const":"integer","title":"Data Type"}},"additionalProperties":false,"type":"object","required":["name","data_type"],"title":"IntegerField"},"KeyCheckResponse":{"properties":{"valid":{"type":"boolean","title":"Valid","description":"Always `true` — a failed check returns the standard error envelope with `error_code` `MISSING_API_KEY` or `INVALID_API_KEY`.","examples":[true]},"organization_id":{"type":"string","title":"Organization Id","description":"UUID of the organization the key belongs to.","examples":["7f4a1c2e-0000-4000-8000-000000000001"]},"organization_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organization Name","description":"Display name of the owning organization, when the backend surfaces it.","examples":["Acme Corp"]},"scopes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Scopes","description":"Scopes granted to the key (`read`, `write`). `null` when the backend does not report them.","examples":[["read","write"]]}},"type":"object","required":["valid","organization_id"],"title":"KeyCheckResponse","description":"Confirms the API key is valid and names its owning organization."},"KnowledgeNode":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable identifier for this node within the graph."},"type":{"type":"string","const":"knowledge","title":"Type"}},"additionalProperties":false,"type":"object","required":["id","type"],"title":"KnowledgeNode","description":"Terminal knowledge sink — its presence opts the workflow into the\nknowledge base (priced separately, so absent by default).\n\nThe backend reacts to parse callbacks by ingesting parsed markdown into\nthe workflow's navigable corpus; core never executes this node — the\nexecution builder keeps it and its edges off the worker message. Emits\nnothing downstream."},"LookupFileUpload":{"properties":{"filename":{"type":"string","minLength":1,"title":"Filename"},"content":{"type":"string","minLength":1,"title":"Content","description":"Base64-encoded file bytes."}},"additionalProperties":false,"type":"object","required":["filename","content"],"title":"LookupFileUpload","description":"Inline lookup-file content carried on the typed create call.\n\nThe backend reads ``filename`` + ``content`` (base64-encoded bytes),\nuploads the file, and stores the resulting URI in\n``ExtractNode.lookup_files``. Create-input only — not persisted on\nthe node after upload."},"MultiSelectField":{"properties":{"persistent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Persistent Id","description":"Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit for new fields; when omitted on an update, the server matches the field to the prior version by name."},"name":{"type":"string","minLength":1,"title":"Name","description":"Field name. Used as the key in the extraction response."},"description":{"type":"string","title":"Description","description":"Free-form description shown to the extraction model.","default":""},"source":{"type":"string","enum":["extraction","smart_lookup","lookup_if_missing"],"title":"Source","description":"How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).","default":"extraction"},"data_type":{"type":"string","const":"multi_select","title":"Data Type"},"enum_options":{"items":{"$ref":"#/components/schemas/EnumOption"},"type":"array","minItems":1,"title":"Enum Options"}},"additionalProperties":false,"type":"object","required":["name","data_type","enum_options"],"title":"MultiSelectField"},"ObjectField":{"properties":{"persistent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Persistent Id","description":"Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit for new fields; when omitted on an update, the server matches the field to the prior version by name."},"name":{"type":"string","minLength":1,"title":"Name","description":"Field name. Used as the key in the extraction response."},"description":{"type":"string","title":"Description","description":"Free-form description shown to the extraction model.","default":""},"source":{"type":"string","enum":["extraction","smart_lookup","lookup_if_missing"],"title":"Source","description":"How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).","default":"extraction"},"data_type":{"type":"string","const":"object","title":"Data Type"},"nested_fields":{"items":{"oneOf":[{"$ref":"#/components/schemas/StringField"},{"$ref":"#/components/schemas/IntegerField"},{"$ref":"#/components/schemas/FloatField"},{"$ref":"#/components/schemas/BooleanField"},{"$ref":"#/components/schemas/DateField"},{"$ref":"#/components/schemas/DatetimeField"},{"$ref":"#/components/schemas/EnumField"},{"$ref":"#/components/schemas/MultiSelectField"}],"discriminator":{"propertyName":"data_type","mapping":{"boolean":"#/components/schemas/BooleanField","date":"#/components/schemas/DateField","datetime":"#/components/schemas/DatetimeField","enum":"#/components/schemas/EnumField","float":"#/components/schemas/FloatField","integer":"#/components/schemas/IntegerField","multi_select":"#/components/schemas/MultiSelectField","string":"#/components/schemas/StringField"}}},"type":"array","minItems":1,"title":"Nested Fields","description":"Child fields of this object. Only one level of nesting is supported — an object field's children must be non-object types."}},"additionalProperties":false,"type":"object","required":["name","data_type","nested_fields"],"title":"ObjectField"},"OneOfCheck":{"properties":{"type":{"type":"string","const":"one_of","title":"Type"},"field":{"type":"string","minLength":1,"title":"Field"},"allowed":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Allowed"},"case_sensitive":{"type":"boolean","title":"Case Sensitive","default":false}},"additionalProperties":false,"type":"object","required":["type","field","allowed"],"title":"OneOfCheck"},"PaginatedResponse_CollectionListItem_":{"properties":{"results":{"items":{"$ref":"#/components/schemas/CollectionListItem"},"type":"array","title":"Results","description":"List of items for the current page."},"count":{"type":"integer","title":"Count","description":"Total number of items matching the query."},"page":{"type":"integer","title":"Page","description":"Deprecated. Current page number when using offset pagination. Prefer `next_cursor`.","deprecated":true},"page_size":{"type":"integer","title":"Page Size","description":"Number of results per page."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Opaque token to fetch the next page in keyset order. Present when the caller sent a `cursor` query param and more rows may follow; `null` on the last page. Ignore unless you're using cursor pagination — offset pagination via `page` is unaffected."}},"type":"object","required":["results","count","page","page_size"],"title":"PaginatedResponse[CollectionListItem]"},"ParseFromUrlRequest":{"properties":{"url":{"type":"string","title":"Url","description":"HTTPS URL the backend fetches server-side. The file is named by the response's `Content-Disposition` filename when present, else by the last segment of the URL's path.","examples":["https://example.com/invoices/april.pdf"]}},"type":"object","required":["url"],"title":"ParseFromUrlRequest","description":"Body for ``POST /v3/parse/from-url/``.","examples":[{"url":"https://example.com/invoices/april.pdf"}]},"ParseJobResponse":{"properties":{"job_id":{"type":"string","title":"Job Id","description":"Opaque handle for this parse job."},"status":{"type":"string","title":"Status","description":"Job status; 'pending' immediately after submission."}},"type":"object","required":["job_id","status"],"title":"ParseJobResponse","description":"202 handle for a parse job. Poll ``GET /v2/operations/parse/{job_id}``."},"ParseResult":{"properties":{"markdown":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Markdown","description":"Document content rendered as structured markdown. Each block is preceded by an empty `<a id=\"p{page}_b{idx}\"></a>` anchor (invisible in any markdown renderer; the id joins to `blocks[].id` and can be used as an in-page link target). Image hydration for picture/figure blocks happens client-side. `null` if parsing failed."},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text","description":"Plain markdown with structural HTML removed — `<DOCUMENT>` framing, block anchors, `<img>` tags, and `<figure-content>` wrappers stripped. Useful when feeding the parsed output into an LLM or a search index that doesn't need the block-level metadata. `null` if `markdown` is null."},"layout_confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Layout Confidence","description":"Document-level YOLO layout confidence on a 0-100 scale, char-weighted mean across all blocks. `null` if no annotated sections."},"parse_confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Parse Confidence","description":"Document-level parse confidence on a 0-100 scale, char-weighted mean of per-block LLM logprob scores. `null` when no blocks have logprob-based confidence."},"blocks":{"items":{"$ref":"#/components/schemas/Block"},"type":"array","title":"Blocks","description":"Structured per-block representation of the parsed document. One entry per `<a id></a>` anchor in document order, with type-specific structured data (`rows` for tables, `image_base64` for pictures) surfaced as first-class fields so consumers don't have to HTML-parse."}},"type":"object","required":["markdown"],"title":"ParseResult","description":"Parsed markdown for a file."},"ParseResultResponse":{"properties":{"status":{"type":"string","title":"Status","description":"One of: processing | done | error."},"markdown":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Markdown","description":"Parsed document markdown; null until status is 'done'."}},"type":"object","required":["status"],"title":"ParseResultResponse","description":"Parse job status, with the parsed markdown inline once ready."},"PublicEditNode":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable identifier for this node within the graph."},"type":{"type":"string","const":"edit","title":"Type"},"instructions":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instructions","description":"Free-text values to map onto the fillable fields detected on the upstream parse's PDF, e.g. 'Name: ACME SL; Date: 2026-01-01; I accept the terms: yes'. Takes precedence over a reference document where both address the same field."},"reference_document_ids":{"items":{"type":"string"},"type":"array","title":"Reference Document Ids","description":"Ids of reference documents this node fills from, uploaded to the workflow beforehand. Every id must belong to this workflow and be fully resolved, or the run is refused rather than filled from a partial reference."},"font":{"type":"string","enum":["sans","serif","mono"],"title":"Font","description":"Typeface the filled values are written in.","default":"sans"},"output_mode":{"type":"string","enum":["flattened","editable"],"title":"Output Mode","description":"'flattened' paints the values on and the PDF is final. 'editable' leaves each value in a live form field a reviewer can correct in any PDF viewer.","default":"flattened"}},"additionalProperties":false,"type":"object","required":["id","type"],"title":"PublicEditNode","description":"Terminal form-filler. ``reference_uris`` is resolved server-side at run\ntime from ``reference_document_ids`` — omitted here, and any client-supplied\nvalue is discarded rather than trusted."},"PublicExtractNode":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable identifier for this node within the graph."},"type":{"type":"string","const":"extract","title":"Type"},"mode":{"type":"string","enum":["standard","agentic","lite"],"title":"Mode","description":"Extraction tier. 'standard' (default): single-pass extraction — the best balance for simple documents and layouts. 'agentic': multi-step extraction that maps every table to the schema and reasons across sections — for dense or cross-page tables; extra cost per page. 'lite' (shown as 'Fast' in the app): standard extraction, faster and cheaper; quality may vary on complex layouts.","default":"standard"},"extraction_schema":{"$ref":"#/components/schemas/ExtractionSchema","description":"Schema for the fields this node extracts. Required."},"lookup_files":{"items":{"type":"string"},"type":"array","title":"Lookup Files","description":"Smart-lookup reference document URIs persisted on the extract node."},"lookup_suggestion":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lookup Suggestion","description":"Free-form hint shown to the smart-lookup matcher."},"lookup_reasoning_effort":{"anyOf":[{"type":"string","enum":["minimal","low","medium","high"]},{"type":"null"}],"title":"Lookup Reasoning Effort","description":"Reasoning effort for the smart-lookup matcher (gpt-5 family): minimal | low | medium | high. None = model default. Higher effort improves match reliability on noisy join keys at higher latency/cost."},"lookup_file_uploads":{"items":{"$ref":"#/components/schemas/LookupFileUpload"},"type":"array","title":"Lookup File Uploads","description":"Inline lookup-file content for the typed create call. Each entry is uploaded and the resulting URI is appended to ``lookup_files``; this field is create-input only."},"use_images":{"type":"boolean","title":"Use Images","description":"Standard/lite modes: send each PDF page's rendered image alongside its parsed text so the model can read layout the text missed — adds vision cost on every page.","default":false}},"additionalProperties":false,"type":"object","required":["id","type","extraction_schema"],"title":"PublicExtractNode"},"PublicIfElseNode":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable identifier for this node within the graph."},"type":{"type":"string","const":"if_else","title":"Type"},"condition":{"oneOf":[{"$ref":"#/components/schemas/RangeCheck"},{"$ref":"#/components/schemas/DateCheck"},{"$ref":"#/components/schemas/ArithmeticCheck"},{"$ref":"#/components/schemas/ComparisonCheck"},{"$ref":"#/components/schemas/OneOfCheck"},{"$ref":"#/components/schemas/RegexCheck"},{"$ref":"#/components/schemas/RequiredCheck"},{"$ref":"#/components/schemas/ConfidenceCheck"},{"$ref":"#/components/schemas/ExpressionCheck"},{"$ref":"#/components/schemas/ValidationCheck"},{"$ref":"#/components/schemas/AllOfCheck"},{"$ref":"#/components/schemas/AnyOfCheck"}],"title":"Condition","discriminator":{"propertyName":"type","mapping":{"all_of":"#/components/schemas/AllOfCheck","any_of":"#/components/schemas/AnyOfCheck","arithmetic":"#/components/schemas/ArithmeticCheck","comparison":"#/components/schemas/ComparisonCheck","confidence":"#/components/schemas/ConfidenceCheck","date":"#/components/schemas/DateCheck","expression":"#/components/schemas/ExpressionCheck","one_of":"#/components/schemas/OneOfCheck","range":"#/components/schemas/RangeCheck","regex":"#/components/schemas/RegexCheck","required":"#/components/schemas/RequiredCheck","validation":"#/components/schemas/ValidationCheck"}}}},"additionalProperties":false,"type":"object","required":["id","type","condition"],"title":"PublicIfElseNode"},"PublicParseNode":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable identifier for this node within the graph."},"type":{"type":"string","const":"parse","title":"Type"},"mode":{"type":"string","enum":["standard","agentic","lite","flash"],"title":"Mode","description":"Parse tier. 'standard' (default): page-by-page parsing with reading-order correction — the best quality/speed balance for most documents and tables. 'agentic': adaptive parsing that works hardest on dense tables (50+ rows, many columns) — highest fidelity on complex documents; extra cost per page. 'lite' (shown as 'Fast' in the app): OCR-only tier — accurate OCR, no LLM call; use standard or agentic when the output needs LLM correction. 'flash': the PDF's own text layer plus layout grounding, no model call — the cheapest and fastest tier; a page with no text layer is OCR'd by default (see scanned_pages).","default":"standard"},"prompt_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt Hint","description":"Free-form hint that biases the parse output. Standard and agentic modes only; ignored in lite."},"figure_enhancement":{"type":"boolean","title":"Figure Enhancement","description":"Standard mode: extract structured data from charts and images — extra processing per figure. Ignored in agentic and in lite.","default":false},"cache":{"type":"boolean","title":"Cache","description":"Reuse parsed output when the same file was already parsed with the same mode and settings — a hit skips the whole parse. Disable to force a fresh parse.","default":true},"effort":{"type":"string","enum":["low","mid","accurate"],"title":"Effort","description":"Agentic mode: quality/cost preset. 'low' = several times cheaper but more errors on dense or low-contrast tables, 'mid' (default) = balanced, 'accurate' = highest fidelity. (Distinct from lite `ocr_effort`.)","default":"mid"},"ocr_effort":{"type":"string","enum":["medium","high"],"title":"Ocr Effort","description":"Lite mode: 'high' (default) = the strongest OCR — best accuracy on complex layouts, tables, and handwriting. 'medium' = faster and cheaper, for clean digital documents. (Distinct from agentic `effort`.)","default":"high"},"scanned_pages":{"type":"string","enum":["ocr","skip","fail"],"title":"Scanned Pages","description":"Flash mode: what to do with a page whose text layer produced no words. 'ocr' (default): OCR the page and parse it like any other, at no extra model cost. 'skip': serve it blank and flag it, don't fail the parse. 'fail': raise, naming the page numbers.","default":"ocr"}},"additionalProperties":false,"type":"object","required":["id","type"],"title":"PublicParseNode"},"PublicSlackAlertNode":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable identifier for this node within the graph."},"type":{"type":"string","const":"slack_alert","title":"Type"},"channel_id":{"type":"string","minLength":1,"title":"Channel Id"},"channel_name":{"type":"string","minLength":1,"title":"Channel Name"},"message_template":{"type":"string","minLength":1,"title":"Message Template"},"severity":{"type":"string","enum":["info","warning","critical"],"title":"Severity","default":"info"}},"additionalProperties":false,"type":"object","required":["id","type","channel_id","channel_name","message_template"],"title":"PublicSlackAlertNode","description":"Terminal alert-sink. ``field_index`` is executor-injected — omitted here."},"PublicValidateNode":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable identifier for this node within the graph."},"type":{"type":"string","const":"validate","title":"Type"},"rules":{"items":{"$ref":"#/components/schemas/ValidationRule"},"type":"array","minItems":1,"title":"Rules"}},"additionalProperties":false,"type":"object","required":["id","type","rules"],"title":"PublicValidateNode"},"RangeCheck":{"properties":{"type":{"type":"string","const":"range","title":"Type"},"field":{"type":"string","minLength":1,"title":"Field","description":"persistent_id of the bounded numeric field."},"min":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min"},"max":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max"}},"additionalProperties":false,"type":"object","required":["type","field"],"title":"RangeCheck"},"RegexCheck":{"properties":{"type":{"type":"string","const":"regex","title":"Type"},"field":{"type":"string","minLength":1,"title":"Field"},"pattern":{"type":"string","minLength":1,"title":"Pattern","description":"Evaluated with google-re2 (linear time); never stdlib re."}},"additionalProperties":false,"type":"object","required":["type","field","pattern"],"title":"RegexCheck"},"RejectedFileItem":{"properties":{"filename":{"type":"string","title":"Filename","description":"Name of the rejected file.","examples":["trojan.pdf"]},"reason":{"type":"string","title":"Reason","description":"Human-readable reason from the backend upload validator.","examples":["File contents are not a supported file type (detected: application/x-msdownload)."]}},"type":"object","required":["filename","reason"],"title":"RejectedFileItem","description":"A file the backend rejected either upfront (unsupported filename) or\nafter inspecting its bytes (disguised content). No ``DocumentPacket``\nwas created for these: the backend deletes the raw bytes that reached\nS3, and the ``upload-status=pending`` lifecycle rule expires whatever\nthat delete missed."},"RequiredCheck":{"properties":{"type":{"type":"string","const":"required","title":"Type"},"field":{"type":"string","minLength":1,"title":"Field"}},"additionalProperties":false,"type":"object","required":["type","field"],"title":"RequiredCheck"},"ResultsResponse":{"properties":{"collection_id":{"type":"string","title":"Collection Id","description":"The file collection's UUID. Same value as the `id` returned by `POST /v2/workflows/{wid}/run/`. Also emitted as `document_packet_id` — same value, v3 canonical name."},"document_packet_id":{"type":"string","title":"Document Packet Id","description":"The document packet's UUID — v3 canonical name for `collection_id`. Same value; both fields are always present.","default":""},"verification_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verification Url","description":"Link to the AnyFormat dashboard for human review of this collection's results. `null` if the dashboard URL cannot be constructed (e.g. no files in the collection, or the deployment has no frontend URL configured)."},"parse":{"anyOf":[{"$ref":"#/components/schemas/ParseResult"},{"type":"null"}],"description":"Parse-node output (rendered markdown). `null` when the workflow has no parse node. Always present in the response."},"classifications":{"items":{"$ref":"#/components/schemas/ClassificationResult"},"type":"array","title":"Classifications","description":"Per-classifier-node verdicts. Empty when the workflow has no classifier."},"splits":{"items":{"$ref":"#/components/schemas/SplitResult"},"type":"array","title":"Splits","description":"Splitter output: category-level geometry with optional partitions. Empty when the workflow has no splitter."},"extractions":{"items":{"$ref":"#/components/schemas/Extraction"},"type":"array","title":"Extractions","description":"Flat list of extraction datapoints. Linear workflows produce one entry with `split_name=null` and `partition=null`. Split workflows produce one entry per (split, partition). Empty when no extraction has run yet."},"edits":{"items":{"$ref":"#/components/schemas/Edit"},"type":"array","title":"Edits","description":"Filled-form output, one entry per file an edit node processed. Empty when the workflow has no edit node."},"extraction":{"anyOf":[{"additionalProperties":{"anyOf":[{"$ref":"#/components/schemas/ExtractedField"},{"items":{"additionalProperties":{"$ref":"#/components/schemas/ExtractedField"},"type":"object"},"type":"array"}]},"type":"object"},{"type":"null"}],"title":"Extraction","description":"**Deprecated** — use `extractions` instead. Extracted fields keyed by field name, populated only for linear workflows (single extract node, no splitter). `null` for split workflows; read `extractions[]` instead.","deprecated":true}},"type":"object","required":["collection_id","document_packet_id"],"title":"ResultsResponse","description":"Canonical response shape for the file-collection results endpoint.\n\nReturned with HTTP 200 once processing completes. Returns 412 while processing is\nin progress; poll until 200, or use webhooks."},"ResultsResponseV3":{"properties":{"document_packet_id":{"type":"string","title":"Document Packet Id","description":"The document packet's UUID — v3 canonical name for `collection_id`. Same value; both fields are always present.","default":""},"verification_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verification Url","description":"Link to the AnyFormat dashboard for human review of this collection's results. `null` if the dashboard URL cannot be constructed (e.g. no files in the collection, or the deployment has no frontend URL configured)."},"parse":{"anyOf":[{"$ref":"#/components/schemas/ParseResult"},{"type":"null"}],"description":"Parse-node output (rendered markdown). `null` when the workflow has no parse node. Always present in the response."},"classifications":{"items":{"$ref":"#/components/schemas/ClassificationResult"},"type":"array","title":"Classifications","description":"Per-classifier-node verdicts. Empty when the workflow has no classifier."},"splits":{"items":{"$ref":"#/components/schemas/SplitResult"},"type":"array","title":"Splits","description":"Splitter output: category-level geometry with optional partitions. Empty when the workflow has no splitter."},"extractions":{"items":{"$ref":"#/components/schemas/Extraction"},"type":"array","title":"Extractions","description":"Flat list of extraction datapoints. Linear workflows produce one entry with `split_name=null` and `partition=null`. Split workflows produce one entry per (split, partition). Empty when no extraction has run yet."},"edits":{"items":{"$ref":"#/components/schemas/Edit"},"type":"array","title":"Edits","description":"Filled-form output, one entry per file an edit node processed. Empty when the workflow has no edit node."},"extraction":{"anyOf":[{"additionalProperties":{"anyOf":[{"$ref":"#/components/schemas/ExtractedField"},{"items":{"additionalProperties":{"$ref":"#/components/schemas/ExtractedField"},"type":"object"},"type":"array"}]},"type":"object"},{"type":"null"}],"title":"Extraction","description":"**Deprecated** — use `extractions` instead. Extracted fields keyed by field name, populated only for linear workflows (single extract node, no splitter). `null` for split workflows; read `extractions[]` instead.","deprecated":true}},"type":"object","required":["document_packet_id"],"title":"ResultsResponseV3","description":"v3-scoped results envelope — same shape as ``ResultsResponse`` minus the\nlegacy ``collection_id`` alias. v3 emits only ``document_packet_id``."},"RunDetailV3":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the run (hyphenated UUID).","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4f9"]},"workflow_id":{"type":"string","title":"Workflow Id","description":"The workflow this run executed (hyphenated UUID).","examples":["0686bb97-8c30-70f0-8000-97669e000eb8"]},"document_packet_id":{"type":"string","title":"Document Packet Id","description":"The document packet the run executed on (hyphenated UUID).","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e1"]},"status":{"$ref":"#/components/schemas/RunStatus","description":"Execution status. Non-terminal: `queued`, `in_progress`. Terminal: `processed` (success), `error`, `cancelled`.","examples":["processed"]},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At","description":"Timestamp when the run was triggered (ISO 8601)."},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At","description":"Timestamp of the run's last status change (ISO 8601)."},"results":{"anyOf":[{"$ref":"#/components/schemas/ResultsResponseV3"},{"type":"null"}],"description":"Extraction results envelope; `null` until `status` is `processed`. Same shape as the v2 results endpoint."}},"type":"object","required":["id","workflow_id","document_packet_id","status"],"title":"RunDetailV3","description":"Flat single-run read: lifecycle status plus results inline.\n\n`results` is `null` until the run reaches `processed`, then carries the\nsame results envelope `GET /v2/workflows/{id}/files/{id}/results/`\nreturns — no separate results endpoint, no 412 while in flight."},"RunListPageV3":{"properties":{"items":{"items":{"$ref":"#/components/schemas/RunSummaryV3"},"type":"array","title":"Items","description":"Runs on this page, newest first."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Opaque token to fetch the next page; pass it back as `?cursor=`. `null` on the last page."}},"type":"object","required":["items"],"title":"RunListPageV3","description":"One keyset page of runs.\n\nFixed ``(-created_at, -id)`` order. No totals or page numbers —\niterate by following ``next_cursor`` until it is null."},"RunStatus":{"type":"string","enum":["queued","in_progress","processed","error","cancelled"],"title":"RunStatus","description":"Execution lifecycle of a run. Non-terminal: ``queued``,\n``in_progress``. Terminal: ``processed`` (success), ``error``,\n``cancelled``."},"RunSummaryV3":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the run (hyphenated UUID).","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4f9"]},"document_packet_id":{"type":"string","title":"Document Packet Id","description":"The document packet the run executes on (hyphenated UUID).","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e1"]},"status":{"$ref":"#/components/schemas/RunStatus","description":"Execution status. Non-terminal: `queued`, `in_progress`. Terminal: `processed` (success), `error`, `cancelled`.","examples":["processed"]},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At","description":"Timestamp when the run was triggered (ISO 8601)."},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At","description":"Timestamp of the run's last status change (ISO 8601)."}},"type":"object","required":["id","document_packet_id","status"],"title":"RunSummaryV3","description":"Slim run projection returned by list pages."},"RunTriggeredV3":{"properties":{"run_id":{"type":"string","title":"Run Id","description":"Unique identifier of the new run (hyphenated UUID).","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4f9"]},"document_packet_id":{"type":"string","title":"Document Packet Id","description":"The document packet the run executes on (hyphenated UUID).","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e1"]},"workflow_id":{"type":"string","title":"Workflow Id","description":"The workflow being run (hyphenated UUID).","examples":["0686bb97-8c30-70f0-8000-97669e000eb8"]},"status":{"$ref":"#/components/schemas/RunStatus","description":"Status at acceptance time — normally `queued`.","examples":["queued"]}},"type":"object","required":["run_id","document_packet_id","workflow_id","status"],"title":"RunTriggeredV3","description":"202 response for both run triggers (`upload/run/` and\n`document-packets/{id}/run/`)."},"SplitPartition":{"properties":{"name":{"type":"string","title":"Name","description":"The partition value (free-form string)."},"files":{"items":{"$ref":"#/components/schemas/FilePages"},"type":"array","title":"Files"},"confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Confidence","description":"0-100 minimum confidence across the partition's ranges. `null` when the partition holds no page, because nothing was measured."}},"type":"object","required":["name","files","confidence"],"title":"SplitPartition","description":"A partition value within a split (e.g. `1234-5678` under `Account Holdings`)."},"SplitResult":{"properties":{"name":{"type":"string","title":"Name","description":"The split's category name."},"files":{"items":{"$ref":"#/components/schemas/FilePages"},"type":"array","title":"Files","description":"Per-file page lists, union of all partitions."},"confidence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Confidence","description":"0-100 aggregate confidence (min across partitions). `null` when the category matched no page, because nothing was measured."},"partitions":{"items":{"$ref":"#/components/schemas/SplitPartition"},"type":"array","title":"Partitions"}},"type":"object","required":["name","files","confidence"],"title":"SplitResult","description":"A category-level split: which pages of which files fall under it, plus\nany partitions inside it. Extraction data lives under `extractions[]` —\njoin by `split_name`."},"SplitterNode":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable identifier for this node within the graph."},"type":{"type":"string","const":"splitter","title":"Type"},"rules":{"items":{"$ref":"#/components/schemas/SplitterRule"},"type":"array","minItems":1,"title":"Rules"}},"additionalProperties":false,"type":"object","required":["id","type","rules"],"title":"SplitterNode"},"SplitterRule":{"properties":{"id":{"type":"string","minLength":1,"title":"Id"},"name":{"type":"string","minLength":1,"title":"Name"},"description":{"type":"string","minLength":1,"title":"Description"},"partition_key":{"type":"string","title":"Partition Key","description":"Field that further partitions this category into separate sub-documents (e.g. invoice_number): each distinct value becomes its own split, extracted independently. Empty = routing-only, the whole category flows on as one document.","default":""}},"additionalProperties":false,"type":"object","required":["id","name","description"],"title":"SplitterRule"},"StringField":{"properties":{"persistent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Persistent Id","description":"Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit for new fields; when omitted on an update, the server matches the field to the prior version by name."},"name":{"type":"string","minLength":1,"title":"Name","description":"Field name. Used as the key in the extraction response."},"description":{"type":"string","title":"Description","description":"Free-form description shown to the extraction model.","default":""},"source":{"type":"string","enum":["extraction","smart_lookup","lookup_if_missing"],"title":"Source","description":"How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).","default":"extraction"},"data_type":{"type":"string","const":"string","title":"Data Type"}},"additionalProperties":false,"type":"object","required":["name","data_type"],"title":"StringField"},"SuggestFieldDescriptionRequest":{"properties":{"workflow_id":{"type":"string","title":"Workflow Id"},"file_collection_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Collection Id"},"field_name":{"type":"string","title":"Field Name","default":""},"field_description":{"type":"string","title":"Field Description","default":""}},"type":"object","required":["workflow_id"],"title":"SuggestFieldDescriptionRequest"},"SuggestFieldDescriptionResponse":{"properties":{"description":{"type":"string","title":"Description"},"metadata":{"$ref":"#/components/schemas/_Metadata"}},"type":"object","required":["description"],"title":"SuggestFieldDescriptionResponse"},"SuggestFieldsRequest":{"properties":{"workflow_id":{"type":"string","title":"Workflow Id"},"file_collection_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Collection Id"},"images":{"items":{"type":"string","maxLength":4500000},"type":"array","maxItems":3,"title":"Images"}},"type":"object","required":["workflow_id"],"title":"SuggestFieldsRequest"},"SuggestFieldsResponse":{"properties":{"fields":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Fields"},"metadata":{"$ref":"#/components/schemas/_Metadata"}},"type":"object","required":["fields"],"title":"SuggestFieldsResponse"},"SuggestWorkflowDescriptionRequest":{"properties":{"workflow_id":{"type":"string","title":"Workflow Id"}},"type":"object","required":["workflow_id"],"title":"SuggestWorkflowDescriptionRequest"},"SuggestWorkflowDescriptionResponse":{"properties":{"description":{"type":"string","title":"Description"},"metadata":{"$ref":"#/components/schemas/_Metadata"}},"type":"object","required":["description"],"title":"SuggestWorkflowDescriptionResponse"},"SuggestWorkflowNameRequest":{"properties":{"workflow_description":{"type":"string","title":"Workflow Description"},"file_collection_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Collection Id"},"images":{"items":{"type":"string","maxLength":4500000},"type":"array","maxItems":3,"title":"Images"}},"type":"object","required":["workflow_description"],"title":"SuggestWorkflowNameRequest"},"SuggestWorkflowNameResponse":{"properties":{"name":{"type":"string","title":"Name"},"metadata":{"$ref":"#/components/schemas/_Metadata"}},"type":"object","required":["name"],"title":"SuggestWorkflowNameResponse"},"UploadFileResponse":{"properties":{"status":{"type":"string","title":"Status","description":"Upload result: `uploaded` on success.","examples":["uploaded"]},"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename","description":"Name the file was stored under. Auto-renamed with a ` (n)` counter when it collides with an existing file in the workflow; `original_filename` then holds the name you uploaded.","examples":["invoice.pdf"]},"original_filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Original Filename","description":"The name you uploaded, present only when the file was auto-renamed to avoid a duplicate name in the workflow. `null` when `filename` is the name you uploaded.","examples":["invoice.pdf"]},"file_collection_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Collection Id","description":"The collection UUID the file was uploaded into. Use it to poll results via `GET /v2/workflows/{workflow_id}/files/{file_collection_id}/results/`.","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e1"]},"file_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Id","description":"The UUID of the uploaded file. Pass it to `POST /v2/workflows/{workflow_id}/files/{file_id}/run/` to start extraction.","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e2"]}},"type":"object","required":["status"],"title":"UploadFileResponse","description":"Confirmation that a file was uploaded successfully without triggering extraction."},"Validation":{"properties":{"rule_id":{"type":"string","title":"Rule Id","description":"The rule's `id` as declared on the validate node."},"description":{"type":"string","title":"Description","description":"The rule's natural-language description; empty for a deterministic rule.","default":""},"severity":{"type":"string","title":"Severity","description":"`error` or `warning`, as declared on the rule."},"status":{"type":"string","title":"Status","description":"`pass`, `fail`, or `inconclusive` — the last one when the rule could not be evaluated (no data, an unanswerable expression)."},"detail":{"type":"string","title":"Detail","description":"Human-readable explanation of the verdict.","default":""},"compared_values":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Compared Values","description":"The field values the rule looked at, keyed by field name. `null` when nothing was compared."},"source_fields":{"items":{"type":"string"},"type":"array","title":"Source Fields","description":"`persistent_id`s of the fields the rule declared as its inputs."}},"type":"object","required":["rule_id","severity","status"],"title":"Validation","description":"One validate-node rule's verdict on the extraction it sits beside."},"ValidationCheck":{"properties":{"type":{"type":"string","const":"validation","title":"Type"},"rule_id":{"type":"string","minLength":1,"title":"Rule Id","description":"Stable id of the upstream ValidationRule to route on."},"status":{"type":"string","enum":["fail","pass","inconclusive"],"title":"Status","description":"Outcome to match. ``fail`` (default) is the common case for routing to an alert branch.","default":"fail"}},"additionalProperties":false,"type":"object","required":["type","rule_id"],"title":"ValidationCheck","description":"Routes on the outcome of a named validation rule already run upstream.\n\nReads from ``state.validation_results`` (populated by an upstream\n``ValidateNode``), filtered to the current partition (``split_id``) so\nper-partition IfElse routing matches per-partition rule outcomes. The\n``status`` values mirror the worker enum\n(``anyformat_core.operations.validate_rules`` — ``pass`` / ``fail`` /\n``inconclusive``) verbatim: no translation layer, so template tokens\nlike ``${validation.<rule_id>.status}`` render the same three strings\nthe enum uses.\n\nUnlike every other ``Check`` variant this consumes no extracted fields\n(``field_ids`` returns ``[]``); the rule identity is the entire input.\nA ``rule_id`` with no matching entry evaluates to ``inconclusive`` — the\nrule didn't run for this partition, so the outcome is unknown."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"ValidationRule":{"properties":{"id":{"type":"string","minLength":1,"title":"Id","description":"Stable rule id; round-trips through validation results."},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Optional human-readable rule name. Round-trips through the config endpoint so renames are preserved."},"kind":{"type":"string","enum":["ai","deterministic"],"title":"Kind","description":"'deterministic' = a structured check run in code — instant, free, reproducible; 'ai' = a model judges the rule description against the extraction. Prefer deterministic whenever the condition is exact and testable.","default":"ai"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Natural-language description sent to the LLM. Required when kind == 'ai'."},"check":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/RangeCheck"},{"$ref":"#/components/schemas/DateCheck"},{"$ref":"#/components/schemas/ArithmeticCheck"},{"$ref":"#/components/schemas/ComparisonCheck"},{"$ref":"#/components/schemas/OneOfCheck"},{"$ref":"#/components/schemas/RegexCheck"},{"$ref":"#/components/schemas/RequiredCheck"},{"$ref":"#/components/schemas/ConfidenceCheck"},{"$ref":"#/components/schemas/ExpressionCheck"},{"$ref":"#/components/schemas/ValidationCheck"},{"$ref":"#/components/schemas/AllOfCheck"},{"$ref":"#/components/schemas/AnyOfCheck"}],"discriminator":{"propertyName":"type","mapping":{"all_of":"#/components/schemas/AllOfCheck","any_of":"#/components/schemas/AnyOfCheck","arithmetic":"#/components/schemas/ArithmeticCheck","comparison":"#/components/schemas/ComparisonCheck","confidence":"#/components/schemas/ConfidenceCheck","date":"#/components/schemas/DateCheck","expression":"#/components/schemas/ExpressionCheck","one_of":"#/components/schemas/OneOfCheck","range":"#/components/schemas/RangeCheck","regex":"#/components/schemas/RegexCheck","required":"#/components/schemas/RequiredCheck","validation":"#/components/schemas/ValidationCheck"}}},{"type":"null"}],"title":"Check","description":"Structured deterministic check. Required when kind == 'deterministic'."},"severity":{"type":"string","enum":["error","warning"],"title":"Severity","description":"How a failed rule is labelled in results. Display-level only — it never blocks the run.","default":"error"},"source_fields":{"items":{"type":"string"},"type":"array","title":"Source Fields","description":"Persistent ids of fields this rule references."}},"additionalProperties":false,"type":"object","required":["id"],"title":"ValidationRule"},"WorkflowCreateRequest":{"properties":{"name":{"type":"string","minLength":1,"title":"Name","examples":["Invoice or receipt"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","default":""},"nodes":{"items":{"oneOf":[{"$ref":"#/components/schemas/PublicParseNode"},{"$ref":"#/components/schemas/ClassifyNode"},{"$ref":"#/components/schemas/SplitterNode"},{"$ref":"#/components/schemas/PublicExtractNode"},{"$ref":"#/components/schemas/PublicValidateNode"},{"$ref":"#/components/schemas/PublicIfElseNode"},{"$ref":"#/components/schemas/PublicSlackAlertNode"},{"$ref":"#/components/schemas/PublicEditNode"},{"$ref":"#/components/schemas/KnowledgeNode"}],"discriminator":{"propertyName":"type","mapping":{"classify":"#/components/schemas/ClassifyNode","edit":"#/components/schemas/PublicEditNode","extract":"#/components/schemas/PublicExtractNode","if_else":"#/components/schemas/PublicIfElseNode","knowledge":"#/components/schemas/KnowledgeNode","parse":"#/components/schemas/PublicParseNode","slack_alert":"#/components/schemas/PublicSlackAlertNode","splitter":"#/components/schemas/SplitterNode","validate":"#/components/schemas/PublicValidateNode"}}},"type":"array","minItems":1,"title":"Nodes"},"edges":{"items":{"$ref":"#/components/schemas/Edge"},"type":"array","title":"Edges"}},"additionalProperties":false,"type":"object","required":["name","nodes"],"title":"WorkflowCreateRequest","description":"Public-surface workflow create body — typed graph of parse / classify / splitter / extract / validate nodes.\n\nA ``validate`` node carries ``rules``; each rule is either AI-evaluated\n(``kind=\"ai\"`` + a natural-language ``description``) or deterministic\n(``kind=\"deterministic\"`` + a structured ``check``, evaluated in pure\nPython with no model call).\n\nUses ``PublicNode`` (public request models with only the fields callers\nmay set); the domain ``AnyNode`` also carries ``filter`` (worker-only)\nand executor-injected / staff-only fields, so the public bodies pin a\nstricter node schema. Call :meth:`to_domain` before validating topology\nor forwarding to the backend.","examples":[{"description":"Pull the invoice number and total from each document.","edges":[{"source":"parse","target":"extract"}],"name":"Invoice totals","nodes":[{"id":"parse","mode":"standard","type":"parse"},{"extraction_schema":{"fields":[{"data_type":"string","description":"Invoice number as printed on the document.","name":"invoice_number"},{"data_type":"float","description":"Invoice total in the document's currency.","name":"total_amount"}]},"id":"extract","mode":"standard","type":"extract"}]}]},"WorkflowDetailV3":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the workflow (hyphenated UUID).","examples":["0686bb97-8c30-70f0-8000-97669e000eb8"]},"name":{"type":"string","title":"Name","description":"Human-readable name of the workflow.","examples":["Invoice Processing"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Optional description of what this workflow extracts.","examples":["A workflow for processing invoices and retrieving invoice details."]},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At","description":"Timestamp when the workflow was created (ISO 8601)."},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At","description":"Timestamp when the workflow was last modified (ISO 8601)."},"nodes":{"items":{"oneOf":[{"$ref":"#/components/schemas/PublicParseNode"},{"$ref":"#/components/schemas/ClassifyNode"},{"$ref":"#/components/schemas/SplitterNode"},{"$ref":"#/components/schemas/PublicExtractNode"},{"$ref":"#/components/schemas/PublicValidateNode"},{"$ref":"#/components/schemas/PublicIfElseNode"},{"$ref":"#/components/schemas/PublicSlackAlertNode"},{"$ref":"#/components/schemas/PublicEditNode"},{"$ref":"#/components/schemas/KnowledgeNode"}],"discriminator":{"propertyName":"type","mapping":{"classify":"#/components/schemas/ClassifyNode","edit":"#/components/schemas/PublicEditNode","extract":"#/components/schemas/PublicExtractNode","if_else":"#/components/schemas/PublicIfElseNode","knowledge":"#/components/schemas/KnowledgeNode","parse":"#/components/schemas/PublicParseNode","slack_alert":"#/components/schemas/PublicSlackAlertNode","splitter":"#/components/schemas/SplitterNode","validate":"#/components/schemas/PublicValidateNode"}}},"type":"array","title":"Nodes","description":"Typed graph nodes (parse / classify / splitter / extract / validate / if_else)."},"edges":{"items":{"$ref":"#/components/schemas/Edge"},"type":"array","title":"Edges","description":"Directed edges between the graph nodes."}},"type":"object","required":["id","name","nodes"],"title":"WorkflowDetailV3","description":"A workflow with its complete typed graph inline.\n\n``{name, description, nodes, edges}`` is the exact shape\n``POST /v3/workflows/`` accepts — mutate it and feed it back to edit."},"WorkflowListPageV3":{"properties":{"items":{"items":{"$ref":"#/components/schemas/WorkflowSummaryV3"},"type":"array","title":"Items","description":"Workflows on this page, newest first."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Opaque token to fetch the next page; pass it back as `?cursor=`. `null` on the last page."}},"type":"object","required":["items"],"title":"WorkflowListPageV3","description":"One keyset page of workflows.\n\nFixed ``(-created_at, -id)`` order. No totals or page numbers by design\n(ANY-1608) — iterate by following ``next_cursor`` until it is null."},"WorkflowListResponse":{"properties":{"results":{"items":{"$ref":"#/components/schemas/WorkflowResponse"},"type":"array","title":"Results","description":"List of workflows for the current page."},"count":{"type":"integer","title":"Count","description":"Total number of workflows matching the query.","examples":[4]},"page":{"type":"integer","title":"Page","description":"Current page number.","examples":[1]},"page_size":{"type":"integer","title":"Page Size","description":"Number of results per page.","examples":[20]}},"type":"object","required":["results","count","page","page_size"],"title":"WorkflowListResponse","description":"Paginated list of workflows."},"WorkflowResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the workflow (UUID).","examples":["0686bb97-8c30-70f0-8000-97669e000eb8"]},"name":{"type":"string","title":"Name","description":"Human-readable name of the workflow.","examples":["Invoice Processing"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Optional description of what this workflow extracts.","examples":["A workflow for processing invoices and retrieving invoice details."]},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At","description":"Timestamp when the workflow was created (ISO 8601)."},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At","description":"Timestamp when the workflow was last modified (ISO 8601)."},"fields":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Fields","description":"List of extraction field definitions configured for this workflow. `null` if not yet configured."}},"type":"object","required":["id","name"],"title":"WorkflowResponse","description":"A workflow defines the extraction template — what fields to extract from documents, their types, and validation rules."},"WorkflowRunListItem":{"properties":{"id":{"type":"string","title":"Id","description":"The collection UUID for this run. Use this ID with `GET /v2/workflows/{workflow_id}/files/{id}/results/` to fetch results.","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e1"]},"status":{"type":"string","enum":["not_started","queued","in_progress","processed","error","cancelled"],"title":"Status","description":"Processing status. Non-terminal: `not_started` (no extraction yet), `queued`, `in_progress`. Terminal: `processed` (success), `error`, `cancelled`.","examples":["processed"]},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At","description":"Timestamp when the run started (ISO 8601)."},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At","description":"Timestamp when the run status was last updated (ISO 8601)."}},"type":"object","required":["id","status"],"title":"WorkflowRunListItem","description":"An extraction run entry, representing one execution of a workflow on a file collection."},"WorkflowRunListResponse":{"properties":{"results":{"items":{"$ref":"#/components/schemas/WorkflowRunListItem"},"type":"array","title":"Results","description":"List of runs for the current page."},"count":{"type":"integer","title":"Count","description":"Total number of runs for this workflow.","examples":[3]},"page":{"type":"integer","title":"Page","description":"Deprecated. Current page number when using offset pagination. Prefer `next_cursor`.","deprecated":true,"examples":[1]},"page_size":{"type":"integer","title":"Page Size","description":"Number of results per page.","examples":[20]},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Opaque token to fetch the next page in keyset order. Present when the caller sent a `cursor` query param and more rows may follow; `null` on the last page."}},"type":"object","required":["results","count","page","page_size"],"title":"WorkflowRunListResponse","description":"Paginated list of workflow runs."},"WorkflowRunResponseV2":{"properties":{"id":{"type":"string","title":"Id","description":"The collection UUID for this run. Use this ID to poll for results via `GET /v2/workflows/{workflow_id}/files/{id}/results/`.","examples":["069dcc2c-e14c-7606-8000-2ee4fb17b4e1"]},"status":{"type":"string","enum":["not_started","queued","in_progress","processed","error","cancelled"],"title":"Status","description":"Initial status of the run: `queued` (the run was accepted and enqueued, not that extraction is complete). Use `GET /v2/workflows/{workflow_id}/files/{id}/results/` to poll the run through its `in_progress` / `processed` lifecycle.","examples":["queued"]},"workflow_id":{"type":"string","title":"Workflow Id","description":"The UUID of the workflow that was executed.","examples":["0686bb97-8c30-70f0-8000-97669e000eb8"]},"version_id":{"type":"string","title":"Version Id","description":"The workflow version this run was bound to (the latest version at submission time). Lets callers verify which schema produced the results — useful right after an edit.","examples":["FGaV4I2JAA"]}},"type":"object","required":["id","status","workflow_id","version_id"],"title":"WorkflowRunResponseV2","description":"Response after triggering a workflow run. Contains the collection ID to use for polling extraction results."},"WorkflowSummaryV3":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier of the workflow (hyphenated UUID).","examples":["0686bb97-8c30-70f0-8000-97669e000eb8"]},"name":{"type":"string","title":"Name","description":"Human-readable name of the workflow.","examples":["Invoice Processing"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Optional description of what this workflow extracts.","examples":["A workflow for processing invoices and retrieving invoice details."]},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At","description":"Timestamp when the workflow was created (ISO 8601)."},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At","description":"Timestamp when the workflow was last modified (ISO 8601)."}},"type":"object","required":["id","name"],"title":"WorkflowSummaryV3","description":"Slim workflow projection returned by create and list."},"WorkflowUpdateRequest":{"properties":{"name":{"type":"string","minLength":1,"title":"Name","examples":["Invoice or receipt"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","default":""},"nodes":{"items":{"oneOf":[{"$ref":"#/components/schemas/PublicParseNode"},{"$ref":"#/components/schemas/ClassifyNode"},{"$ref":"#/components/schemas/SplitterNode"},{"$ref":"#/components/schemas/PublicExtractNode"},{"$ref":"#/components/schemas/PublicValidateNode"},{"$ref":"#/components/schemas/PublicIfElseNode"},{"$ref":"#/components/schemas/PublicSlackAlertNode"},{"$ref":"#/components/schemas/PublicEditNode"},{"$ref":"#/components/schemas/KnowledgeNode"}],"discriminator":{"propertyName":"type","mapping":{"classify":"#/components/schemas/ClassifyNode","edit":"#/components/schemas/PublicEditNode","extract":"#/components/schemas/PublicExtractNode","if_else":"#/components/schemas/PublicIfElseNode","knowledge":"#/components/schemas/KnowledgeNode","parse":"#/components/schemas/PublicParseNode","slack_alert":"#/components/schemas/PublicSlackAlertNode","splitter":"#/components/schemas/SplitterNode","validate":"#/components/schemas/PublicValidateNode"}}},"type":"array","minItems":1,"title":"Nodes"},"edges":{"items":{"$ref":"#/components/schemas/Edge"},"type":"array","title":"Edges"}},"additionalProperties":false,"type":"object","required":["name","nodes"],"title":"WorkflowUpdateRequest","description":"Public-surface workflow update body — full replacement of the typed graph.\n\nEcho each existing field's ``persistent_id`` (from ``GET``) unchanged —\nincluding across renames — to keep the field's identity; omit it for\nnew fields. Restricts the node union to the public types (see\n``WorkflowCreateRequest``). Call :meth:`to_domain` before validating\ntopology or forwarding to the backend.","examples":[{"description":"Pull the invoice number and total from each document.","edges":[{"source":"parse","target":"extract"}],"name":"Invoice totals","nodes":[{"id":"parse","mode":"standard","type":"parse"},{"extraction_schema":{"fields":[{"data_type":"string","description":"Invoice number as printed on the document.","name":"invoice_number","persistent_id":"0686bb97-8c30-70f0-8000-97669e00aaaa"},{"data_type":"float","description":"Invoice total in the document's currency.","name":"total_amount"}]},"id":"extract","mode":"standard","type":"extract"}]}]},"WorkflowVersionListPageV3":{"properties":{"items":{"items":{"$ref":"#/components/schemas/WorkflowVersionSummaryV3"},"type":"array","title":"Items","description":"Versions on this page, newest first."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Opaque token to fetch the next page; pass it back as `?cursor=`. `null` on the last page."}},"type":"object","required":["items"],"title":"WorkflowVersionListPageV3","description":"One keyset page of a workflow's versions, newest first.\n\nItem 0 of the first page is the version runs use. Follow ``next_cursor``\nuntil it is null; there are no totals or page numbers."},"WorkflowVersionSummaryV3":{"properties":{"version_id":{"type":"string","title":"Version Id","description":"Identifier of the version; pass it as `?version=` on `GET /v3/workflows/{workflow_id}/`.","examples":["FGaV4I2JAA"]},"version":{"type":"string","title":"Version","description":"Display number, `major.minor.patch`.","examples":["1.2.0"]},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At","description":"Timestamp when the version was created (ISO 8601)."}},"type":"object","required":["version_id","version"],"title":"WorkflowVersionSummaryV3","description":"One entry in a workflow's version history.\n\nVersions are read-only: they exist for comparison and audit, and runs\nalways use the latest version. Pass ``version_id`` as\n``GET /v3/workflows/{workflow_id}/?version=`` to read that version's graph."},"_FieldOperand":{"properties":{"source":{"type":"string","const":"field","title":"Source"},"field":{"type":"string","minLength":1,"title":"Field","description":"persistent_id of the compared field."}},"additionalProperties":false,"type":"object","required":["source","field"],"title":"_FieldOperand"},"_LiteralOperand":{"properties":{"source":{"type":"string","const":"literal","title":"Source"},"value":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}],"title":"Value"}},"additionalProperties":false,"type":"object","required":["source","value"],"title":"_LiteralOperand"},"_Metadata":{"properties":{"success":{"type":"boolean","title":"Success","default":true}},"type":"object","title":"_Metadata"},"ErrorEnvelope":{"type":"object","title":"ErrorEnvelope","description":"Uniform error response. `retryable=true` means the same request may succeed on retry (with backoff); `retryable=false` means the caller must change the request before retrying.","required":["error","detail","error_code","retryable","request_id"],"properties":{"error":{"type":"string","description":"Short human-readable summary."},"detail":{"description":"Machine-readable detail. String for most errors; list of field errors for validation failures.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"object"}}]},"error_code":{"type":"string","description":"Stable identifier for programmatic handling.","examples":["VALIDATION_ERROR","AUTH_FAILED","NOT_FOUND","PRECONDITION_FAILED","RATE_LIMITED","INTERNAL_ERROR","GATEWAY_TIMEOUT"]},"retryable":{"type":"boolean","description":"True when the caller should retry (with backoff for 429/412/5xx)."},"request_id":{"type":"string","description":"Correlates this response with server logs."}}}},"securitySchemes":{"ApiKeyAuth":{"type":"http","description":"API key issued from app.anyformat.ai/api-key. Send as `Authorization: Bearer <key>`.","scheme":"bearer"}}},"tags":[{"name":"workflows","description":"Workflows define extraction templates — what fields to extract from documents. Create workflows, upload files, run extractions, and fetch results."},{"name":"files","description":"File collections group uploaded documents and track their extraction progress. Upload files, check status, and retrieve extraction results."},{"name":"suggestions","description":"AI-powered schema and workflow suggestion endpoints for the AnyFormat webapp. Authenticated with a Cognito JWT rather than an API key."},{"name":"document-packets","description":"Document packets group uploaded documents for a workflow (v3). Address a packet directly to (re-)run its workflow."},{"name":"runs","description":"Extraction runs — the v3 first-class result entity. Each run is a single execution of a workflow against a document packet; fetch its status and results flat by run id."},{"name":"parse","description":"Parse a single document with the platform's fast lite parse — a one-call shortcut over the workflow upload + run primitives, backed by your organization's system parse workflow."},{"name":"health","description":"Health check endpoints to verify API availability."}]}