{"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.","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).\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- ``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/CreateFileCollectionFromUrlRequest"}}}},"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/WorkflowDefinition"}}},"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"}}],"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"}}],"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.","operationId":"v3_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/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\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.","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."}],"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). Filenames are derived from each URL's path.","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}/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.","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`."}],"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."}],"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/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"}}}}}}}}}},"components":{"schemas":{"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"},"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":{"type":"number","title":"Layout Confidence","description":"0-100 YOLO layout detection confidence for this block."},"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","layout_confidence","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"}},"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_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."}},"type":"object","required":["files"],"title":"Body_v3_upload_and_run_workflow"},"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."}},"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":""},"lookup":{"type":"boolean","title":"Lookup","default":false},"lookup_only_if_missing":{"type":"boolean","title":"Lookup Only If Missing","description":"Only meaningful when lookup=True: extract the field too and let the lookup fill it only where extraction found no value, instead of always overwriting.","default":false},"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":{"type":"number","title":"Confidence","description":"0-100 model confidence in the verdict."},"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."},"CreateFileCollectionFromUrlRequest":{"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"]}},"type":"object","required":["url","filename"],"title":"CreateFileCollectionFromUrlRequest","description":"Payload for creating a file collection 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."},"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":""},"lookup":{"type":"boolean","title":"Lookup","default":false},"lookup_only_if_missing":{"type":"boolean","title":"Lookup Only If Missing","description":"Only meaningful when lookup=True: extract the field too and let the lookup fill it only where extraction found no value, instead of always overwriting.","default":false},"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":""},"lookup":{"type":"boolean","title":"Lookup","default":false},"lookup_only_if_missing":{"type":"boolean","title":"Lookup Only If Missing","description":"Only meaningful when lookup=True: extract the field too and let the lookup fill it only where extraction found no value, instead of always overwriting.","default":false},"data_type":{"type":"string","const":"datetime","title":"Data Type"}},"additionalProperties":false,"type":"object","required":["name","data_type"],"title":"DatetimeField"},"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/DocumentPacketFileV3"},"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."}},"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 recorded at upload.","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). The filename is derived from each URL's path.","examples":[["https://example.com/invoices/april.pdf"]]}},"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."},"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":""},"lookup":{"type":"boolean","title":"Lookup","default":false},"lookup_only_if_missing":{"type":"boolean","title":"Lookup Only If Missing","description":"Only meaningful when lookup=True: extract the field too and let the lookup fill it only where extraction found no value, instead of always overwriting.","default":false},"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"},"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."},"ExtractNode":{"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","max","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. 'max' (feature-gated): extracts table rows page by page with cross-page context tracking, then independently verifies row sums against document totals and re-extracts pages that don't reconcile — for multi-page invoices with complex row grouping. '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."},"lookup_schema":{"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","title":"Lookup Schema","description":"Typed schema of fields the smart-lookup pass should produce. Derived server-side from the workflow's smart-lookup fields; default empty for nodes without any."},"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. No effect in agentic/max modes or on non-PDF sources.","default":false},"row_extractor_enabled":{"type":"boolean","title":"Row Extractor Enabled","description":"Extract table rows page by page, carrying context across page breaks so rows stay in their group ('max' mode implies this).","default":false},"page_sum_verification_enabled":{"type":"boolean","title":"Page Sum Verification Enabled","description":"After row extraction, independently re-check each page's rows against document totals and re-extract pages that don't reconcile ('max' mode implies this).","default":false}},"additionalProperties":false,"type":"object","required":["id","type","extraction_schema"],"title":"ExtractNode"},"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`."}},"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 of the uploaded file.","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":""},"lookup":{"type":"boolean","title":"Lookup","default":false},"lookup_only_if_missing":{"type":"boolean","title":"Lookup Only If Missing","description":"Only meaningful when lookup=True: extract the field too and let the lookup fill it only where extraction found no value, instead of always overwriting.","default":false},"data_type":{"type":"string","const":"float","title":"Data Type"}},"additionalProperties":false,"type":"object","required":["name","data_type"],"title":"FloatField"},"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."},"IfElseNode":{"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"}],"title":"Condition","discriminator":{"propertyName":"type","mapping":{"arithmetic":"#/components/schemas/ArithmeticCheck","comparison":"#/components/schemas/ComparisonCheck","confidence":"#/components/schemas/ConfidenceCheck","date":"#/components/schemas/DateCheck","one_of":"#/components/schemas/OneOfCheck","range":"#/components/schemas/RangeCheck","regex":"#/components/schemas/RegexCheck","required":"#/components/schemas/RequiredCheck"}}},"field_index":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Field Index","description":"Executor-injected at run time (persistent_id → field name); never set by callers or persisted."}},"additionalProperties":false,"type":"object","required":["id","type","condition"],"title":"IfElseNode","description":"Conditional router — evaluates a ``Check`` against upstream extraction\nand forks to a ``\"then\"`` or ``\"else\"`` outgoing branch.\n\nAlerts and downstream operators attach on either branch; this node does\nnot transform data. The ``\"then\"`` branch is required; ``\"else\"`` may be\nunwired (flows to END)."},"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":""},"lookup":{"type":"boolean","title":"Lookup","default":false},"lookup_only_if_missing":{"type":"boolean","title":"Lookup Only If Missing","description":"Only meaningful when lookup=True: extract the field too and let the lookup fill it only where extraction found no value, instead of always overwriting.","default":false},"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."},"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":""},"lookup":{"type":"boolean","title":"Lookup","default":false},"lookup_only_if_missing":{"type":"boolean","title":"Lookup Only If Missing","description":"Only meaningful when lookup=True: extract the field too and let the lookup fill it only where extraction found no value, instead of always overwriting.","default":false},"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":""},"lookup":{"type":"boolean","title":"Lookup","default":false},"lookup_only_if_missing":{"type":"boolean","title":"Lookup Only If Missing","description":"Only meaningful when lookup=True: extract the field too and let the lookup fill it only where extraction found no value, instead of always overwriting.","default":false},"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]"},"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}``."},"ParseNode":{"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"],"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-first tier, fastest and cheapest — accurate OCR by default; set skip_routing_review=False to add a correction pass when reading order, figures, or text formatting matter.","default":"standard"},"prompt_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt Hint","description":"Free-form hint that biases the parse output. In lite mode it guides the correction pass, so it requires skip_routing_review=False."},"figure_enhancement":{"type":"boolean","title":"Figure Enhancement","description":"Standard mode: extract structured data from charts and images — extra processing per figure. Ignored in agentic (figures are already handled) and in lite (use `figures` instead).","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, and usually all a document needs. 'medium' = faster and cheaper, for clean digital documents. (Distinct from agentic `effort`.)","default":"high"},"region":{"type":"string","enum":["eu","global"],"title":"Region","description":"Lite mode: OCR data-residency. 'eu' keeps processing in-region; 'global' uses the hosted endpoint. Feature-flagged.","default":"eu"},"skip_routing_review":{"type":"boolean","title":"Skip Routing Review","description":"Lite mode: emit the OCR output as-is (the default — fastest and cheapest). Set False to add a correction pass that fixes reading order and OCR errors and rebuilds broken tables; while True, figures/text_formatting/routing_effort/prompt_hint are inert.","default":true},"figures":{"type":"boolean","title":"Figures","description":"Lite mode: the correction pass reads data points off charts/figures and reconstructs them as HTML tables (extra work on figure pages; needs skip_routing_review=False).","default":false},"text_formatting":{"type":"boolean","title":"Text Formatting","description":"Lite mode: the correction pass restores inline styling (bold/italic/superscript), code, and LaTeX math in text blocks (needs skip_routing_review=False).","default":false},"routing_effort":{"anyOf":[{"type":"string","enum":["minimal","low","medium","high"]},{"type":"null"}],"title":"Routing Effort","description":"Lite mode: effort of the correction pass's reading-order analysis — its dominant latency knob (None = the highest). Lower it to cut latency on simple layouts."}},"additionalProperties":false,"type":"object","required":["id","type"],"title":"ParseNode"},"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."},"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 ``FileCollection``\nwas created for these; the raw bytes (if any reached S3) age out via\nthe ``upload-status=pending`` lifecycle rule within 24 h."},"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/`."},"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."},"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"],"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."},"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/ResultsResponse"},{"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":{"type":"integer","title":"Confidence","description":"0-100 minimum confidence across the partition's ranges."}},"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":{"type":"integer","title":"Confidence","description":"0-100 aggregate confidence (min across partitions)."},"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":""},"lookup":{"type":"boolean","title":"Lookup","default":false},"lookup_only_if_missing":{"type":"boolean","title":"Lookup Only If Missing","description":"Only meaningful when lookup=True: extract the field too and let the lookup fill it only where extraction found no value, instead of always overwriting.","default":false},"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 of the uploaded file.","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."},"ValidateNode":{"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"},"field_index":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Field Index","description":"Executor-injected at run time (persistent_id → field name); never set by callers or persisted."}},"additionalProperties":false,"type":"object","required":["id","type","rules"],"title":"ValidateNode"},"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"}],"discriminator":{"propertyName":"type","mapping":{"arithmetic":"#/components/schemas/ArithmeticCheck","comparison":"#/components/schemas/ComparisonCheck","confidence":"#/components/schemas/ConfidenceCheck","date":"#/components/schemas/DateCheck","one_of":"#/components/schemas/OneOfCheck","range":"#/components/schemas/RangeCheck","regex":"#/components/schemas/RegexCheck","required":"#/components/schemas/RequiredCheck"}}},{"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/ParseNode"},{"$ref":"#/components/schemas/ClassifyNode"},{"$ref":"#/components/schemas/SplitterNode"},{"$ref":"#/components/schemas/ExtractNode"},{"$ref":"#/components/schemas/ValidateNode"},{"$ref":"#/components/schemas/IfElseNode"}],"discriminator":{"propertyName":"type","mapping":{"classify":"#/components/schemas/ClassifyNode","extract":"#/components/schemas/ExtractNode","if_else":"#/components/schemas/IfElseNode","parse":"#/components/schemas/ParseNode","splitter":"#/components/schemas/SplitterNode","validate":"#/components/schemas/ValidateNode"}}},"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\nDefined as a thin subclass so the FastAPI-generated OpenAPI components\nentry is named ``WorkflowCreateRequest`` (FastAPI uses the model's\n``__name__``). Behaviour is fully inherited from\n``WorkflowDefinition`` in ``anyformat.workflow``.","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"}]}]},"WorkflowDefinition":{"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/ParseNode"},{"$ref":"#/components/schemas/ClassifyNode"},{"$ref":"#/components/schemas/SplitterNode"},{"$ref":"#/components/schemas/ExtractNode"},{"$ref":"#/components/schemas/ValidateNode"},{"$ref":"#/components/schemas/IfElseNode"}],"discriminator":{"propertyName":"type","mapping":{"classify":"#/components/schemas/ClassifyNode","extract":"#/components/schemas/ExtractNode","if_else":"#/components/schemas/IfElseNode","parse":"#/components/schemas/ParseNode","splitter":"#/components/schemas/SplitterNode","validate":"#/components/schemas/ValidateNode"}}},"type":"array","minItems":1,"title":"Nodes"},"edges":{"items":{"$ref":"#/components/schemas/Edge"},"type":"array","title":"Edges"}},"additionalProperties":false,"type":"object","required":["name","nodes"],"title":"WorkflowDefinition","description":"Atomic workflow creation from a typed graph.\n\nTopology validation (``ExactlyOneParseNode``, edge predecessor rules,\nbranch routing, etc.) is **opt-in** via ``validate_topology()`` rather\nthan an ``@model_validator(mode=\"after\")``. Reason: the wire payload\nsometimes carries partial graphs (test setups, in-flight rewrites,\nexecutor-rehydrated subgraphs) that downstream consumers don't need\nto re-validate. Surfaces that *do* care — the v3 create endpoint and\nthe fluent ``WorkflowBuilder.build()`` — call ``validate_topology()``\nexplicitly after construction."},"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/ParseNode"},{"$ref":"#/components/schemas/ClassifyNode"},{"$ref":"#/components/schemas/SplitterNode"},{"$ref":"#/components/schemas/ExtractNode"},{"$ref":"#/components/schemas/ValidateNode"},{"$ref":"#/components/schemas/IfElseNode"}],"discriminator":{"propertyName":"type","mapping":{"classify":"#/components/schemas/ClassifyNode","extract":"#/components/schemas/ExtractNode","if_else":"#/components/schemas/IfElseNode","parse":"#/components/schemas/ParseNode","splitter":"#/components/schemas/SplitterNode","validate":"#/components/schemas/ValidateNode"}}},"type":"array","title":"Nodes","description":"Typed graph nodes (parse / classify / splitter / extract / validate)."},"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/ParseNode"},{"$ref":"#/components/schemas/ClassifyNode"},{"$ref":"#/components/schemas/SplitterNode"},{"$ref":"#/components/schemas/ExtractNode"},{"$ref":"#/components/schemas/ValidateNode"},{"$ref":"#/components/schemas/IfElseNode"}],"discriminator":{"propertyName":"type","mapping":{"classify":"#/components/schemas/ClassifyNode","extract":"#/components/schemas/ExtractNode","if_else":"#/components/schemas/IfElseNode","parse":"#/components/schemas/ParseNode","splitter":"#/components/schemas/SplitterNode","validate":"#/components/schemas/ValidateNode"}}},"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. Thin subclass for OpenAPI naming (``WorkflowUpdateRequest``).\nBehaviour is fully inherited from ``WorkflowDefinition`` in\n``anyformat.workflow``.","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"}]}]},"_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":"health","description":"Health check endpoints to verify API availability."}]}