{"openapi":"3.1.0","info":{"title":"Klaaro API","version":"1.0.0","description":"Klaaro developer API — upload documents, read extracted data, and automate your document pipeline.\n\n## Authentication\n\nAll v1 endpoints require an API key passed as a Bearer token.\n\n```\nAuthorization: Bearer sk_<your-api-key>\n```\n\nCreate API keys under **Team → API keys**.\nSession auth (cookies, OAuth JWT) is not accepted on /api/v1 — use the dashboard for session-based access.\n\n### Scopes\n\n| Scope | What it does |\n| --- | --- |\n| `read` | List, get, query |\n| `write` | Upload, create, manage |\n| `export` | Export data, push to destination |\n\n## Conventions\n\n| | |\n| --- | --- |\n| **Naming** | All JSON fields are `camelCase`. |\n| **Collections** | `{ data: T[], meta: { nextCursor, hasMore } }` — cursor-based, opaque base64 cursors. |\n| **Errors** | `{ error: { code, message, param?, requestId } }` — consistent on every route. |\n| **List cursors** | `?limit=50&cursor=...` — max 200, default 50. Cursor state in response `meta` (`nextCursor`, `hasMore`). |\n| **Idempotency** | `Idempotency-Key: <uuid>` on uploads and mutations. 24-hour dedup window. Replayed responses include `Idempotency-Replay: true` header. |\n| **Datasets** | Identified by UUID `id` in paths (`/datasets/{id}`) and `datasetId` in request bodies/query params. `datasetSlug` is display-only on responses. |\n| **Classes** | Identified by `slug` (unique per dataset). Documents expose `class: { slug, name }`; records add pinned `schemaHash` / `classHash` on `class`. |\n| **Webhooks** | `Klaaro-Signature: t=...,v1=<hmac_sha256>` — validate with your signing secret. |\n| **Rate limits** | `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` headers. 429 with `Retry-After` on breach. |\n\n## Public identifiers\n\n| Resource | Public ID | Notes |\n| --- | --- | --- |\n| Team | `slug` | Human-readable, e.g. `acme-corp` |\n| Dataset | `id` (UUID) | Use `id` from `GET /datasets` as `datasetId` in paths and request inputs; `slug` is human-readable metadata on responses |\n| Class | `slug` | Unique per dataset, e.g. `invoice` — use in `?class=` filters and `class.slug` on resources |\n| Document | UUID | The `id` field IS the public identifier |\n| Record | UUID | The `id` field IS the public identifier |\n\n## Record list endpoints\n\nThree dataset record list endpoints share pagination and filters (`limit`, `cursor`, `class`, `approval`, date filters):\n\n| Endpoint | Shape | Use case |\n| --- | --- | --- |\n| `GET /datasets/{id}/records` | JSON | Export / analytics — `{ id, documentId, class, data }` with pure extracted values per class schema |\n| `GET /datasets/{id}/records-flat` | flat | Review / automation — field-centric `FieldView` keyed by path |\n| `GET /datasets/{id}/records-nested` | nested | UI / structured access — container + leaf `FieldView`s in `data`, no flat `fields` map |\n\n`records-flat` and `records-nested` support `?include=events,comments` (optional sidecars; not yet fully wired).\n\n**Single record:** `GET /records/{id}` (JSON), `GET /records-flat/{id}` (flat), `GET /records-nested/{id}` (nested).\n\n**Document records:** `GET /documents/{id}/records` (JSON), `GET /documents/{id}/records-flat` (flat), `GET /documents/{id}/records-nested` (nested) — each returns `{ records, class }`; document variants also support `?includeUnapproved`.\n\n```json\n{\n  \"id\": \"2c0c2e50-5df6-4b1e-9a5e-c4b6e7a6c1b4\",\n  \"documentId\": \"b6d2a7f6-0f44-44c8-8cc2-1d2e2bd7a5d5\",\n  \"datasetId\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n  \"datasetSlug\": \"invoices-2026\",\n  \"class\": {\n    \"slug\": \"invoice\",\n    \"name\": \"Invoice\",\n    \"schemaHash\": \"9b7c7b2f6f9f0c52d32a1a6d0d1f3c747c1f9e8b132a4d2e2b9a7c6f0e1d2c3b\",\n    \"classHash\": \"a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456\"\n  },\n  \"approval\": { \"status\": \"pending\", \"triggeredBy\": [\"unsure\"] },\n  \"fields\": {\n    \"line_items[0].amount\": {\n      \"path\": \"line_items[0].amount\",\n      \"fieldRoot\": \"line_items.amount\",\n      \"value\": 120.0,\n      \"schema\": { \"type\": \"currency\", \"required\": true },\n      \"extraction\": { \"evidence\": \"120.00\", \"modelUnsure\": true, \"modelNote\": \"Handwriting ambiguous\" },\n      \"review\": { \"isUnsure\": true, \"commentCount\": 1, \"eventCount\": 0, \"lastAt\": \"2026-05-22T13:00:00Z\" },\n      \"validation\": { \"violations\": [], \"hasViolations\": false }\n    }\n  },\n  \"crossField\": { \"validation\": { \"violations\": [] } },\n  \"comments\": { \"count\": 0, \"preview\": [] }\n}\n```","contact":{"email":"hello@klaaro.ai"}},"servers":[{"url":"https://klaaro.ai/api/v1","description":"Klaaro API v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key (sk_...) from Team → API keys."}},"responses":{"Unauthorized401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"notAuthenticated":{"summary":"Missing or invalid API key","value":{"error":{"code":"not_authenticated","message":"Authentication required. Provide a valid API key via Authorization: Bearer <key>.","requestId":"2f5960e4-4a48-4d03-8b47-1411c30f8b61"}}},"apiKeyRequired":{"summary":"Session auth rejected for /api/v1","value":{"error":{"code":"api_key_required","message":"This endpoint requires an API key. Session auth is not accepted on /api/v1.","requestId":"2f5960e4-4a48-4d03-8b47-1411c30f8b61"}}}}}}},"Forbidden403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"insufficientScope":{"summary":"API key missing required scope","value":{"error":{"code":"insufficient_scope","message":"API key does not have the 'write' scope required for this action.","param":"scope","requestId":"2f5960e4-4a48-4d03-8b47-1411c30f8b61"}}}}}}},"NotFound404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"notFound":{"summary":"Resource not found","value":{"error":{"code":"dataset_not_found","message":"Dataset 'invoices-2026' not found or not accessible.","param":"id","requestId":"2f5960e4-4a48-4d03-8b47-1411c30f8b61"}}}}}}},"RateLimited429":{"description":"Rate limited","headers":{"Retry-After":{"description":"Number of seconds to wait before retrying.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Total requests allowed in the window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rateLimited":{"summary":"Rate limited","value":{"error":{"code":"rate_limited","message":"Too many requests. Slow down and retry after the Retry-After interval.","requestId":"2f5960e4-4a48-4d03-8b47-1411c30f8b61"}}}}}}}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Client-generated UUID. If a request with this key was already processed within 24 h, the original response is returned without re-processing. Response includes `Idempotency-Replay: true` header when served from cache."}},"schemas":{"Error":{"type":"object","required":["error"],"example":{"error":{"code":"dataset_not_found","message":"Dataset not found","requestId":"2f5960e4-4a48-4d03-8b47-1411c30f8b61"}},"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"dataset_not_found"},"message":{"type":"string"},"param":{"type":"string"},"requestId":{"type":"string","format":"uuid"}}}}},"ListMeta":{"type":"object","required":["nextCursor","hasMore"],"example":{"nextCursor":"Q1VSU09SOjI=","hasMore":false},"properties":{"nextCursor":{"type":"string","nullable":true},"hasMore":{"type":"boolean"}}},"Dataset":{"type":"object","required":["id","slug","name","description","documentCount","createdAt","updatedAt"],"example":{"id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","slug":"invoices-2026","name":"Invoices","description":"AP invoices for Q1 processing","documentCount":128,"createdAt":"2026-05-01T10:12:00Z","updatedAt":"2026-05-22T13:00:00Z"},"properties":{"id":{"type":"string","format":"uuid","description":"Stable dataset UUID. Use as datasetId in uploads and filters."},"slug":{"type":"string","description":"Human-readable identifier, unique within your team (display only; use `id` in API paths).","example":"invoices-2026"},"name":{"type":"string"},"description":{"type":"string"},"documentCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Class":{"type":"object","required":["slug","name","schemaHash","classHash","fields"],"example":{"slug":"invoice","name":"Invoice","description":"Invoice fields extracted from PDF invoices","color":"#0ea5e9","schemaHash":"9b7c7b2f6f9f0c52d32a1a6d0d1f3c747c1f9e8b132a4d2e2b9a7c6f0e1d2c3b","classHash":"a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456","fields":[{"name":"invoice_number","type":"string","description":"Invoice number","required":true},{"name":"invoice_date","type":"date","description":"Invoice date","required":true},{"name":"total_amount","type":"currency","description":"Total amount","required":true},{"name":"line_items","type":"array","description":"Line items","required":false,"arrayItemFields":[{"name":"description","type":"string","required":true},{"name":"quantity","type":"number","required":false},{"name":"amount","type":"currency","required":true}]}],"createdAt":"2026-05-22T13:00:00Z","updatedAt":"2026-05-22T13:00:00Z"},"properties":{"slug":{"type":"string","description":"URL-safe identifier, unique per dataset.","example":"invoice"},"name":{"type":"string","description":"Human-readable display name.","example":"Invoice"},"description":{"type":"string"},"color":{"type":"string"},"schemaHash":{"type":"string","description":"SHA-256 of field definitions only. Changes on structural field changes."},"classHash":{"type":"string","description":"SHA-256 of full class definition (schema + display + behavior). Changes on any modification."},"fields":{"type":"array","items":{"$ref":"#/components/schemas/SchemaField"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"SchemaField":{"type":"object","required":["name","type","required"],"example":{"name":"total_amount","type":"currency","description":"Total invoice amount","required":true},"properties":{"name":{"type":"string"},"type":{"type":"string","enum":["string","number","boolean","date","enum","array","object","currency","percentage","email","phone","url","address"]},"description":{"type":"string"},"required":{"type":"boolean"},"children":{"type":"array","items":{"$ref":"#/components/schemas/SchemaField"}},"arrayItemType":{"type":"string"},"arrayItemFields":{"type":"array","items":{"$ref":"#/components/schemas/SchemaField"}},"enumValues":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"number"}]}}}},"DocumentClassRef":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string","nullable":true,"description":"Class slug, e.g. invoice"},"name":{"type":"string","nullable":true,"description":"Display name at read time"}}},"RecordClassRef":{"type":"object","required":["slug","name","schemaHash","classHash"],"properties":{"slug":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"schemaHash":{"type":"string","nullable":true,"description":"SHA-256 of field definitions at extraction time (pinned on record)."},"classHash":{"type":"string","nullable":true,"description":"SHA-256 of full class definition at extraction time (pinned on record)."}}},"Document":{"type":"object","required":["id","datasetId","datasetSlug","filename","fileType","fileSize","status","currentStep","class","createdAt","updatedAt"],"example":{"id":"b6d2a7f6-0f44-44c8-8cc2-1d2e2bd7a5d5","datasetId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","datasetSlug":"invoices-2026","filename":"invoice_2026-0001.pdf","fileType":"application/pdf","fileSize":248312,"status":"completed","currentStep":"extract","class":{"slug":"invoice","name":"Invoice"},"error":null,"ingestSourceDisplay":"Upload","pipeline":{"lastRunId":null,"lastFinishedAt":null,"fromStep":null},"createdAt":"2026-05-22T12:58:00Z","updatedAt":"2026-05-22T13:00:00Z"},"properties":{"id":{"type":"string","format":"uuid"},"datasetId":{"type":"string","format":"uuid","description":"UUID of the dataset this document belongs to"},"datasetSlug":{"type":"string","description":"Slug of the dataset this document belongs to"},"filename":{"type":"string"},"fileType":{"type":"string"},"fileSize":{"type":"integer"},"status":{"type":"string","enum":["queued","processing","completed","failed","cancelled"]},"currentStep":{"$ref":"#/components/schemas/PipelineStep"},"class":{"$ref":"#/components/schemas/DocumentClassRef"},"error":{"type":"string","nullable":true},"ingestSourceDisplay":{"type":"string","nullable":true},"pipeline":{"type":"object","properties":{"lastRunId":{"type":"string","nullable":true},"lastFinishedAt":{"type":"string","format":"date-time","nullable":true},"fromStep":{"$ref":"#/components/schemas/PipelineStep","nullable":true}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"RecordBase":{"type":"object","required":["id","documentId","datasetId","datasetSlug","rowIndex","class","createdAt","updatedAt","crossField","comments"],"properties":{"id":{"type":"string","format":"uuid"},"documentId":{"type":"string","format":"uuid"},"datasetId":{"type":"string","format":"uuid","description":"UUID of the dataset this record belongs to"},"datasetSlug":{"type":"string","description":"Slug of the dataset this record belongs to"},"rowIndex":{"type":"integer"},"class":{"$ref":"#/components/schemas/RecordClassRef"},"sourcePage":{"type":"integer","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"approval":{"nullable":true,"type":"object","properties":{"status":{"type":"string","enum":["pending","approved","approved_with_changes","rejected"]},"triggeredBy":{"type":"array","items":{"type":"string"}}}},"crossField":{"type":"object","properties":{"validation":{"$ref":"#/components/schemas/FieldValidation"}}},"comments":{"type":"object","properties":{"count":{"type":"integer"},"preview":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}}}}}},"Record":{"description":"Field-centric record with flat fields map keyed by path (FieldView per field).","allOf":[{"$ref":"#/components/schemas/RecordBase"},{"type":"object","required":["fields"],"properties":{"fields":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/FieldView"},"description":"Keyed by field path (e.g. 'line_items[0].amount')"}}}],"example":{"id":"2c0c2e50-5df6-4b1e-9a5e-c4b6e7a6c1b4","documentId":"b6d2a7f6-0f44-44c8-8cc2-1d2e2bd7a5d5","datasetId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","datasetSlug":"invoices-2026","rowIndex":0,"class":{"slug":"invoice","name":"Invoice","schemaHash":"9b7c7b2f6f9f0c52d32a1a6d0d1f3c747c1f9e8b132a4d2e2b9a7c6f0e1d2c3b","classHash":"a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456"},"approval":{"status":"pending","triggeredBy":["unsure"]},"createdAt":"2026-05-22T13:00:00Z","updatedAt":"2026-05-22T13:00:00Z","fields":{"line_items[0].amount":{"path":"line_items[0].amount","fieldRoot":"line_items.amount","value":120,"schema":{"type":"currency","required":true},"extraction":{"evidence":"120.00","modelUnsure":true,"modelNote":"Handwriting ambiguous"},"review":{"isUnsure":true,"commentCount":1,"eventCount":0,"lastAt":"2026-05-22T13:00:00Z"},"validation":{"violations":[],"hasViolations":false}}},"crossField":{"validation":{"violations":[],"hasViolations":false}},"comments":{"count":0,"preview":[]}}},"RecordNested":{"description":"Record with nested data tree: container FieldView at schema object/array paths, leaf FieldView at scalars; no flat fields map.","allOf":[{"$ref":"#/components/schemas/RecordBase"},{"type":"object","required":["data"],"properties":{"data":{"description":"Nested extracted structure: container FieldView for object/array fields (expanded value), leaf FieldView for scalars."}}}]},"RecordClean":{"type":"object","required":["id","documentId","class","data"],"description":"Minimal record wrapper with pure extracted values (no field metadata).","example":{"id":"2c0c2e50-5df6-4b1e-9a5e-c4b6e7a6c1b4","documentId":"b6d2a7f6-0f44-44c8-8cc2-1d2e2bd7a5d5","class":{"slug":"invoice","name":"Invoice","schemaHash":"9b7c7b2f6f9f0c52d32a1a6d0d1f3c747c1f9e8b132a4d2e2b9a7c6f0e1d2c3b","classHash":"a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456"},"data":{"total":120,"line_items":[{"amount":120}]}},"properties":{"id":{"type":"string","format":"uuid"},"documentId":{"type":"string","format":"uuid"},"class":{"$ref":"#/components/schemas/RecordClassRef"},"data":{"type":"object","additionalProperties":true,"description":"Pure nested extracted values ordered by class schema (no FieldView wrappers)."}}},"FieldView":{"type":"object","required":["path","fieldRoot","value","extraction","review","validation"],"example":{"path":"line_items[0].amount","fieldRoot":"line_items.amount","value":120,"schema":{"type":"currency","required":true},"extraction":{"evidence":"120.00","modelUnsure":true,"modelNote":"Handwriting ambiguous"},"review":{"isUnsure":true,"commentCount":1,"eventCount":0,"lastAt":"2026-05-22T13:00:00Z"},"validation":{"violations":[],"hasViolations":false}},"properties":{"path":{"type":"string"},"fieldRoot":{"type":"string","description":"Path with array indices stripped, e.g. 'line_items.amount'"},"value":{"description":"Extracted value"},"schema":{"nullable":true,"type":"object","properties":{"type":{"type":"string"},"required":{"type":"boolean"},"description":{"type":"string"}}},"extraction":{"type":"object","properties":{"evidence":{"type":"string","nullable":true,"description":"Verbatim text quote from source document"},"modelUnsure":{"type":"boolean"},"modelNote":{"type":"string","nullable":true}}},"review":{"type":"object","properties":{"latestAnnotation":{"nullable":true,"type":"object"},"isUnsure":{"type":"boolean"},"openFlagId":{"type":"string","nullable":true},"commentCount":{"type":"integer"},"eventCount":{"type":"integer"},"lastActor":{"nullable":true,"type":"object"},"lastAt":{"type":"string","format":"date-time","nullable":true}}},"validation":{"$ref":"#/components/schemas/FieldValidation"}}},"FieldValidation":{"type":"object","example":{"violations":[],"hasViolations":false},"properties":{"violations":{"type":"array","items":{"$ref":"#/components/schemas/Violation"}},"hasViolations":{"type":"boolean"}}},"Violation":{"type":"object","example":{"ruleId":"required","ruleKind":"schema","status":"fail","message":"total_amount is required"},"properties":{"ruleId":{"type":"string"},"ruleKind":{"type":"string"},"status":{"type":"string","enum":["fail","error"]},"message":{"type":"string"}}},"Comment":{"type":"object","required":["id","body","author","createdAt","updatedAt"],"example":{"id":"e1f2a3b4-c5d6-7890-abcd-ef1234567890","body":"Please confirm this amount","author":{"kind":"user","id":null,"name":null},"createdAt":"2026-05-22T13:00:00Z","updatedAt":"2026-05-22T13:00:00Z"},"properties":{"id":{"type":"string","description":"UUID for native field_events rows; legacy rows use `legacy:comment:{uuid}`."},"body":{"type":"string"},"author":{"type":"object","properties":{"kind":{"type":"string","enum":["user","api_key"]},"id":{"type":"string","format":"uuid","nullable":true},"name":{"type":"string","nullable":true}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"source":{"type":"string","nullable":true,"description":"Present when sourced from legacy record_comments."}}},"Webhook":{"type":"object","required":["id","url","events","createdAt","updatedAt"],"example":{"id":"c0a8012d-3d0f-4c5f-8d5a-8e9dfb4a9b52","url":"https://example.com/klaaro/webhook","events":["document.uploaded","document.extraction_completed"],"description":"Production webhook endpoint","secretLast4":"a1b2","lastDeliveryAt":"2026-05-22T13:00:00Z","lastStatus":"delivered","createdAt":"2026-05-01T10:12:00Z","updatedAt":"2026-05-22T13:00:00Z"},"properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"}},"description":{"type":"string","nullable":true},"secretLast4":{"type":"string","nullable":true},"lastDeliveryAt":{"type":"string","format":"date-time","nullable":true},"lastStatus":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"WebhookCreated":{"allOf":[{"$ref":"#/components/schemas/Webhook"},{"type":"object","properties":{"signingSecret":{"type":"string","description":"HMAC signing secret — shown once on creation. Store securely; cannot be retrieved again."}}}]},"WebhookEvent":{"type":"string","enum":["document.uploaded","document.ocr_completed","document.extraction_completed","document.failed","record.updated","record.approved","evaluation.completed"],"description":"Webhook event type."},"WebhookPayload":{"oneOf":[{"$ref":"#/components/schemas/WebhookPayloadDocumentUploaded"},{"$ref":"#/components/schemas/WebhookPayloadDocumentOcrCompleted"},{"$ref":"#/components/schemas/WebhookPayloadDocumentExtractionCompleted"},{"$ref":"#/components/schemas/WebhookPayloadDocumentFailed"},{"$ref":"#/components/schemas/WebhookPayloadRecordUpdated"},{"$ref":"#/components/schemas/WebhookPayloadRecordApproved"},{"$ref":"#/components/schemas/WebhookPayloadEvaluationCompleted"}],"discriminator":{"propertyName":"type"}},"WebhookPayloadBase":{"type":"object","required":["type","webhookId","datasetId","datasetSlug","teamSlug","timestamp"],"properties":{"type":{"$ref":"#/components/schemas/WebhookEvent"},"webhookId":{"type":"string","format":"uuid"},"datasetId":{"type":"string","format":"uuid","description":"UUID of the dataset"},"datasetSlug":{"type":"string","description":"Slug of the dataset"},"teamSlug":{"type":"string","description":"Slug of the team"},"timestamp":{"type":"string","format":"date-time"}}},"WebhookPayloadDocumentUploaded":{"allOf":[{"$ref":"#/components/schemas/WebhookPayloadBase"},{"type":"object","required":["document"],"properties":{"type":{"type":"string","enum":["document.uploaded"]},"document":{"$ref":"#/components/schemas/Document"}}}]},"WebhookPayloadDocumentOcrCompleted":{"allOf":[{"$ref":"#/components/schemas/WebhookPayloadBase"},{"type":"object","required":["document"],"properties":{"type":{"type":"string","enum":["document.ocr_completed"]},"document":{"$ref":"#/components/schemas/Document"}}}]},"WebhookPayloadDocumentExtractionCompleted":{"allOf":[{"$ref":"#/components/schemas/WebhookPayloadBase"},{"type":"object","required":["document","records"],"properties":{"type":{"type":"string","enum":["document.extraction_completed"]},"document":{"$ref":"#/components/schemas/Document"},"records":{"type":"array","items":{"$ref":"#/components/schemas/Record"}}}}]},"WebhookPayloadDocumentFailed":{"allOf":[{"$ref":"#/components/schemas/WebhookPayloadBase"},{"type":"object","required":["document"],"properties":{"type":{"type":"string","enum":["document.failed"]},"document":{"$ref":"#/components/schemas/Document"},"error":{"type":"string","nullable":true}}}]},"WebhookPayloadRecordUpdated":{"allOf":[{"$ref":"#/components/schemas/WebhookPayloadBase"},{"type":"object","required":["record"],"properties":{"type":{"type":"string","enum":["record.updated"]},"record":{"$ref":"#/components/schemas/Record"}}}]},"WebhookPayloadRecordApproved":{"allOf":[{"$ref":"#/components/schemas/WebhookPayloadBase"},{"type":"object","required":["record"],"properties":{"type":{"type":"string","enum":["record.approved"]},"record":{"$ref":"#/components/schemas/Record"},"action":{"type":"string","enum":["approved","approved_with_changes","rejected"]}}}]},"WebhookPayloadEvaluationCompleted":{"allOf":[{"$ref":"#/components/schemas/WebhookPayloadBase"},{"type":"object","required":["documentId","evaluation"],"properties":{"type":{"type":"string","enum":["evaluation.completed"]},"documentId":{"type":"string","format":"uuid"},"evaluation":{"type":"object","required":["status","completedAt"],"properties":{"status":{"type":"string","enum":["completed","failed"]},"score":{"type":"number","nullable":true,"description":"Aggregate evaluation score when available."},"completedAt":{"type":"string","format":"date-time"}}}}}]},"PipelineStep":{"type":"string","enum":["ocr","classify","defineClass","extract","validate","approve"],"description":"Pipeline step identifier — used in currentStep (document state) and fromStep (re-run trigger)."},"RerunFromStep":{"type":"string","enum":["ocr","classify","defineClass","extract"],"description":"Pipeline step to re-run from. Subset of PipelineStep exposed on POST /documents/{id}/rerun."},"FieldEvent":{"type":"object","required":["id","recordId","fieldPath","kind","actorKind","createdAt","updatedAt"],"example":{"id":"d4e5f678-9012-3456-7890-abcdef123456","recordId":"2c0c2e50-5df6-4b1e-9a5e-c4b6e7a6c1b4","fieldPath":"line_items[0].amount","kind":"unsure_flagged","actorKind":"user","body":"Model unsure","priorValue":120,"newValue":120,"parentEventId":null,"metadata":{},"createdAt":"2026-05-22T13:00:00Z","updatedAt":"2026-05-22T13:00:00Z"},"properties":{"id":{"type":"string","description":"UUID for native field_events rows; legacy-mapped rows use `legacy:annotation:{uuid}` or `legacy:comment:{uuid}`."},"recordId":{"type":"string","format":"uuid"},"fieldPath":{"type":"string","description":"Empty string for record-level events (e.g. comments)."},"kind":{"type":"string","enum":["value_edit","unsure_flagged","unsure_resolved","confirmed","reviewed_unchanged","comment","evidence_added","validation_failed"]},"actorKind":{"type":"string","enum":["user","model","system","api_key"]},"body":{"type":"string","nullable":true},"priorValue":{},"newValue":{},"parentEventId":{"type":"string","format":"uuid","nullable":true},"metadata":{"type":"object","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ApprovalQueueItem":{"type":"object","required":["id","recordId","documentId","status","triggeredBy","createdAt","updatedAt"],"example":{"id":"0a4a06c3-2ed8-47a1-8c1b-0d8ab8df9b77","recordId":"2c0c2e50-5df6-4b1e-9a5e-c4b6e7a6c1b4","documentId":"b6d2a7f6-0f44-44c8-8cc2-1d2e2bd7a5d5","documentFilename":"invoice_2026-0001.pdf","class":"invoice","status":"pending","triggeredBy":["unsure"],"assignedReviewerId":null,"createdAt":"2026-05-22T13:00:00Z","updatedAt":"2026-05-22T13:00:00Z"},"properties":{"id":{"type":"string","format":"uuid"},"recordId":{"type":"string","format":"uuid"},"documentId":{"type":"string","format":"uuid","nullable":true},"documentFilename":{"type":"string","nullable":true},"class":{"type":"string","nullable":true,"description":"Class slug for the record (e.g. `invoice`)."},"status":{"type":"string","enum":["pending","approved","approved_with_changes","rejected"]},"triggeredBy":{"type":"array","items":{"type":"string"}},"assignedReviewerId":{"type":"string","format":"uuid","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ApprovalEvent":{"type":"object","required":["id","action","actor","createdAt"],"example":{"id":"f1a2b3c4-d5e6-7890-abcd-ef1234567890","action":"created_pending","actor":{"kind":"system","id":null,"name":null},"comment":null,"createdAt":"2026-05-22T13:00:00Z"},"properties":{"id":{"type":"string","format":"uuid"},"action":{"type":"string","enum":["created_pending","auto_approved","approved","approved_with_changes","rejected","reset_to_pending"]},"actor":{"type":"object","properties":{"kind":{"type":"string","enum":["user","api_key","system"]},"id":{"type":"string","format":"uuid","nullable":true},"name":{"type":"string","nullable":true}}},"comment":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}}}}},"paths":{"/datasets":{"get":{"tags":["Datasets"],"summary":"List datasets","operationId":"listDatasets","security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Dataset"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}},"examples":{"ok":{"summary":"OK","value":{"data":[{"id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","slug":"invoices-2026","name":"Invoices","description":"AP invoices for Q1","documentCount":128,"createdAt":"2026-05-01T10:12:00Z","updatedAt":"2026-05-22T13:00:00Z"}],"meta":{"nextCursor":null,"hasMore":false}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/datasets/{id}":{"get":{"tags":["Datasets"],"summary":"Get dataset","operationId":"getDataset","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Dataset UUID (from `GET /datasets`)."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Dataset"},"examples":{"ok":{"summary":"OK","value":{"id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","slug":"invoices-2026","name":"Invoices","description":"AP invoices for Q1","documentCount":128,"createdAt":"2026-05-01T10:12:00Z","updatedAt":"2026-05-22T13:00:00Z"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}},"delete":{"tags":["Datasets"],"summary":"Delete dataset","operationId":"deleteDataset","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Dataset UUID (from `GET /datasets`)."}],"responses":{"204":{"description":"Deleted"},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/datasets/{id}/classes":{"get":{"tags":["Datasets"],"summary":"List classes","operationId":"listClasses","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Dataset UUID (from `GET /datasets`)."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Class"}},"meta":{"$ref":"#/components/schemas/ListMeta"}},"required":["data","meta"]}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/datasets/{id}/classes/{class}":{"get":{"tags":["Datasets"],"summary":"Get class","operationId":"getClass","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Dataset UUID (from `GET /datasets`)."},{"name":"class","in":"path","required":true,"schema":{"type":"string"},"description":"Class slug (unique per dataset), e.g. `invoice`."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Class"}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/datasets/{id}/records":{"get":{"tags":["Datasets"],"summary":"Get records (JSON)","operationId":"listRecords","security":[{"bearerAuth":[]}],"description":"Returns minimal record wrappers with pure extracted data ordered by class schema. No field metadata. (JSON)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Dataset UUID (from `GET /datasets`)."},{"name":"classification","in":"query","schema":{"type":"string"}},{"name":"class","in":"query","schema":{"type":"string","description":"Alias for classification"}},{"name":"approval","in":"query","schema":{"type":"string","enum":["pending","approved","approved_with_changes","rejected"]}},{"name":"createdAfter","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"createdBefore","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"updatedAfter","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RecordClean"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/datasets/{id}/records-flat":{"get":{"tags":["Datasets"],"summary":"Get records (flat)","operationId":"listRecordsFlat","security":[{"bearerAuth":[]}],"description":"Field-centric record list with flat fields map keyed by path (FieldView per field). (flat)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Dataset UUID (from `GET /datasets`)."},{"name":"classification","in":"query","schema":{"type":"string"}},{"name":"class","in":"query","schema":{"type":"string","description":"Alias for classification"}},{"name":"approval","in":"query","schema":{"type":"string","enum":["pending","approved","approved_with_changes","rejected"]}},{"name":"createdAfter","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"createdBefore","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"updatedAfter","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"include","in":"query","schema":{"type":"string","description":"Comma-separated: events,comments"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Record"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/datasets/{id}/records-nested":{"get":{"tags":["Datasets"],"summary":"Get records (nested)","operationId":"listRecordsNested","security":[{"bearerAuth":[]}],"description":"Record list with nested data tree (container FieldView at object/array fields, leaf FieldView at scalars). No flat fields map. (nested)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Dataset UUID (from `GET /datasets`)."},{"name":"classification","in":"query","schema":{"type":"string"}},{"name":"class","in":"query","schema":{"type":"string","description":"Alias for classification"}},{"name":"approval","in":"query","schema":{"type":"string","enum":["pending","approved","approved_with_changes","rejected"]}},{"name":"createdAfter","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"createdBefore","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"updatedAfter","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"include","in":"query","schema":{"type":"string","description":"Comma-separated: events,comments"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RecordNested"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/documents":{"get":{"tags":["Documents"],"summary":"List documents","operationId":"listDocuments","security":[{"bearerAuth":[]}],"parameters":[{"name":"datasetId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter by dataset UUID (from `GET /datasets`). Omit to list across all datasets in your team."},{"name":"class","in":"query","schema":{"type":"string"},"description":"Filter by class slug."},{"name":"status","in":"query","schema":{"type":"string","enum":["queued","processing","completed","failed","cancelled"]}},{"name":"createdAfter","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"createdBefore","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Document"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}},"post":{"tags":["Documents"],"summary":"Upload a document","operationId":"uploadDocument","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["datasetId","file"],"properties":{"datasetId":{"type":"string","format":"uuid","description":"Dataset UUID (from `GET /datasets`)."},"file":{"type":"string","format":"binary"},"fixedClass":{"type":"string","description":"Lock class to this slug (e.g. `invoice`). Skips the classification step."},"replaceDocumentId":{"type":"string","format":"uuid","description":"Replace an existing document. New file supersedes the old; old document is marked superseded."}}}},"application/json":{"schema":{"type":"object","required":["datasetId","url"],"properties":{"datasetId":{"type":"string","format":"uuid","description":"Dataset UUID (from `GET /datasets`)."},"url":{"type":"string","format":"uri","description":"Public URL to fetch and ingest."},"fixedClass":{"type":"string","description":"Lock class to this slug (e.g. `invoice`). Skips the classification step."}}},"examples":{"urlUpload":{"summary":"Upload from URL","value":{"datasetId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","url":"https://example.com/invoice.pdf"}}}}}},"responses":{"201":{"description":"Document created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"},"examples":{"created":{"summary":"Created","value":{"id":"b6d2a7f6-0f44-44c8-8cc2-1d2e2bd7a5d5","datasetId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","datasetSlug":"invoices-2026","filename":"invoice_2026-0001.pdf","fileType":"application/pdf","fileSize":248312,"status":"queued","currentStep":"ocr","class":{"slug":null,"name":null},"error":null,"ingestSourceDisplay":"Upload","pipeline":{"lastRunId":null,"lastFinishedAt":null,"fromStep":null},"createdAt":"2026-05-22T12:58:00Z","updatedAt":"2026-05-22T12:58:00Z"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/documents/{id}":{"get":{"tags":["Documents"],"summary":"Get document","operationId":"getDocument","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"include","in":"query","schema":{"type":"string","description":"Comma-separated: records,ocr,file,approval"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}},"delete":{"tags":["Documents"],"summary":"Delete document","operationId":"deleteDocument","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/documents/{id}/rerun":{"post":{"tags":["Documents"],"summary":"Re-run document pipeline","operationId":"rerunDocument","security":[{"bearerAuth":[]}],"description":"Re-triggers pipeline processing for an existing document from a given step. Returns the document with status `processing`. Defaults to `classify` when fromStep is omitted.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"fromStep":{"$ref":"#/components/schemas/RerunFromStep","description":"Step to re-run from. Defaults to `classify`."},"fixedClass":{"type":"string","description":"Lock class to this slug on re-run (e.g. `invoice`). Skips classification when set."}}},"examples":{"defaultRerun":{"summary":"Re-run from classify (default)","value":{}},"fromOcr":{"summary":"Re-run from OCR","value":{"fromStep":"ocr"}}}}}},"responses":{"200":{"description":"Pipeline re-triggered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"},"examples":{"processing":{"summary":"Processing","value":{"id":"b6d2a7f6-0f44-44c8-8cc2-1d2e2bd7a5d5","datasetId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","datasetSlug":"invoices-2026","filename":"invoice_2026-0001.pdf","fileType":"application/pdf","fileSize":248312,"status":"processing","currentStep":"classify","class":{"slug":"invoice","name":"Invoice"},"error":null,"ingestSourceDisplay":"Upload","pipeline":{"lastRunId":"run_abc123","lastFinishedAt":null,"fromStep":"classify"},"createdAt":"2026-05-22T12:58:00Z","updatedAt":"2026-05-22T13:05:00Z"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/documents/{id}/records":{"get":{"tags":["Documents"],"summary":"Get records (JSON)","operationId":"getDocumentRecords","security":[{"bearerAuth":[]}],"description":"Returns all records for a document with pure extracted values per class schema. (JSON)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"includeUnapproved","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"records":{"type":"array","items":{"$ref":"#/components/schemas/RecordClean"}},"class":{"$ref":"#/components/schemas/DocumentClassRef"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/documents/{id}/records-flat":{"get":{"tags":["Documents"],"summary":"Get records (flat)","operationId":"getDocumentRecordsFlat","security":[{"bearerAuth":[]}],"description":"Field-centric records for a document with flat fields map keyed by path. (flat)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"include","in":"query","schema":{"type":"string","description":"Comma-separated: events,comments"}},{"name":"includeUnapproved","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"records":{"type":"array","items":{"$ref":"#/components/schemas/Record"}},"class":{"$ref":"#/components/schemas/DocumentClassRef"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/documents/{id}/records-nested":{"get":{"tags":["Documents"],"summary":"Get records (nested)","operationId":"getDocumentRecordsNested","security":[{"bearerAuth":[]}],"description":"Records for a document with nested data tree (container FieldView at object/array fields, leaf FieldView at scalars). No flat fields map. (nested)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"include","in":"query","schema":{"type":"string","description":"Comma-separated: events,comments"}},{"name":"includeUnapproved","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"records":{"type":"array","items":{"$ref":"#/components/schemas/RecordNested"}},"class":{"$ref":"#/components/schemas/DocumentClassRef"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/records/{id}":{"get":{"tags":["Records"],"summary":"Get record (JSON)","operationId":"getRecord","security":[{"bearerAuth":[]}],"description":"Returns a minimal record wrapper with pure extracted values ordered by class schema. (JSON)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordClean"}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/records-flat/{id}":{"get":{"tags":["Records"],"summary":"Get record (flat)","operationId":"getRecordFlat","security":[{"bearerAuth":[]}],"description":"Field-centric record with flat fields map keyed by path (FieldView per field). (flat)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"include","in":"query","schema":{"type":"string","description":"Comma-separated: events,comments"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Record"}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/records-nested/{id}":{"get":{"tags":["Records"],"summary":"Get record (nested)","operationId":"getRecordNested","security":[{"bearerAuth":[]}],"description":"Record with nested data tree (container FieldView at object/array fields, leaf FieldView at scalars). No flat fields map. (nested)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"include","in":"query","schema":{"type":"string","description":"Comma-separated: events,comments"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordNested"}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/records/{id}/field-events":{"get":{"tags":["Records"],"summary":"List field events","operationId":"listFieldEvents","security":[{"bearerAuth":[]}],"description":"Field and record-level events for a record.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"fieldPath","in":"query","schema":{"type":"string"},"description":"Filter by field path. Alias: `field_path`. Use empty string for record-level only."},{"name":"kinds","in":"query","schema":{"type":"string","description":"Comma-separated event kinds"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FieldEvent"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/records/{id}/comments":{"get":{"tags":["Records"],"summary":"List record-level comments","operationId":"listRecordComments","security":[{"bearerAuth":[]}],"description":"Record-level comments only (`fieldPath` empty).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/records/{id}/approvals":{"get":{"tags":["Records"],"summary":"Get approval events","operationId":"listApprovalEvents","security":[{"bearerAuth":[]}],"description":"Returns approval audit events for the record. Empty `data` when the record has no approval record.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ApprovalEvent"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/datasets/{id}/approval-queue":{"get":{"tags":["Records"],"summary":"List approval queue","operationId":"listApprovalQueue","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Dataset UUID (from `GET /datasets`)."},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","approved","approved_with_changes","rejected"]}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ApprovalQueueItem"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhooks","operationId":"listWebhooks","security":[{"bearerAuth":[]}],"parameters":[{"name":"datasetId","in":"query","required":true,"schema":{"type":"string","format":"uuid"},"description":"Dataset UUID (from `GET /datasets`)."},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}},"post":{"tags":["Webhooks"],"summary":"Create webhook","operationId":"createWebhook","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["datasetId","url","events"],"properties":{"datasetId":{"type":"string","format":"uuid","description":"Dataset UUID (from `GET /datasets`)."},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"},"minItems":1},"description":{"type":"string"}}},"examples":{"createWebhook":{"summary":"Create webhook","value":{"datasetId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","url":"https://example.com/klaaro/webhook","events":["document.extraction_completed","document.failed"],"description":"Production webhook endpoint"}}}}}},"responses":{"201":{"description":"Created — signingSecret shown once","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreated"}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/webhooks/{webhookId}":{"patch":{"tags":["Webhooks"],"summary":"Update webhook","operationId":"patchWebhook","security":[{"bearerAuth":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["datasetId"],"properties":{"datasetId":{"type":"string","format":"uuid","description":"Dataset UUID (from `GET /datasets`)."},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"},"minItems":1},"description":{"type":"string","nullable":true,"description":"Max 255 chars"}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}},"delete":{"tags":["Webhooks"],"summary":"Delete webhook","operationId":"deleteWebhook","security":[{"bearerAuth":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["datasetId"],"properties":{"datasetId":{"type":"string","format":"uuid","description":"Dataset UUID (from `GET /datasets`)."}}}}}},"responses":{"204":{"description":"Deleted"},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}},"/webhooks/{webhookId}/rotate-secret":{"post":{"tags":["Webhooks"],"summary":"Rotate signing secret","operationId":"rotateWebhookSecret","security":[{"bearerAuth":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["datasetId"],"properties":{"datasetId":{"type":"string","format":"uuid","description":"Dataset UUID (from `GET /datasets`)."}}}}}},"responses":{"200":{"description":"New signingSecret returned once","content":{"application/json":{"schema":{"type":"object","required":["signingSecret"],"properties":{"signingSecret":{"type":"string","description":"New HMAC signing secret — shown once. Store securely."}}}}}},"401":{"$ref":"#/components/responses/Unauthorized401"},"403":{"$ref":"#/components/responses/Forbidden403"},"404":{"$ref":"#/components/responses/NotFound404"},"429":{"$ref":"#/components/responses/RateLimited429"}}}}},"tags":[{"name":"Datasets","description":"Dataset management and configuration"},{"name":"Documents","description":"Upload, ingest, and read documents"},{"name":"Records","description":"Extracted data — clean values, flat fields, or nested FieldView tree"},{"name":"Webhooks","description":"Outbound webhook management"}]}