@talonic/docs 0.20.26 → 0.20.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/content.js +224 -22
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/seo.js +128 -2
- package/openapi.json +166 -45
- package/package.json +1 -1
package/openapi.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "Talonic API",
|
|
5
5
|
"version": "1.0.0",
|
|
6
|
-
"description": "Structure any document into schema-validated data.\n\nThe Talonic API lets you extract structured data from documents (PDFs, images,\nDOCX, CSV, plain text), manage reusable extraction schemas, track async jobs,\nand organise documents through sources.\n\n## Quick Start\n\n**1. Get your API key**\n\nSign up at [app.talonic.com](https://app.talonic.com) \u2192 Settings \u2192 API Keys \u2192 Create key.\nKeys start with `tlnc_live_` (production) or `tlnc_test_` (sandbox).\nAll examples below use `tlnc_live_abc123` as a placeholder.\n\n**2. Extract your first document**\n\n```bash\ncurl -X POST https://api.talonic.com/v1/extract \\\n -H \"Authorization: Bearer tlnc_live_abc123\" \\\n -F \"file=@invoice.pdf\" \\\n -F 'schema={\"properties\":{\"vendor_name\":{\"type\":\"string\"},\"total_amount\":{\"type\":\"number\"},\"invoice_date\":{\"type\":\"string\"}}}'\n```\n\n**Python:**\n```python\nimport requests\nresp = requests.post(\"https://api.talonic.com/v1/extract\",\n headers={\"Authorization\": \"Bearer tlnc_live_abc123\"},\n files={\"file\": open(\"invoice.pdf\", \"rb\")},\n data={\"schema\": '{\"properties\":{\"vendor_name\":{\"type\":\"string\"},\"total_amount\":{\"type\":\"number\"},\"invoice_date\":{\"type\":\"string\"}}}'})\nprint(resp.json()[\"data\"])\n```\n\n**TypeScript:**\n```typescript\nconst form = new FormData();\nform.append(\"file\", fs.createReadStream(\"invoice.pdf\"));\nform.append(\"schema\", '{\"properties\":{\"vendor_name\":{\"type\":\"string\"},\"total_amount\":{\"type\":\"number\"},\"invoice_date\":{\"type\":\"string\"}}}');\nconst res = await fetch(\"https://api.talonic.com/v1/extract\", {\n method: \"POST\",\n headers: { Authorization: \"Bearer tlnc_live_abc123\" },\n body: form,\n}).then(r => r.json());\nconsole.log(res.data);\n```\n\n**3. What you get back**\n\n```json\n{\n \"extraction_id\": \"d1a2b3c4-5678-9abc-def0-1234567890ab\",\n \"request_id\": \"req_x7y8z9a0b1c2d3e4\",\n \"status\": \"complete\",\n \"document\": {\n \"id\": \"f0e1d2c3-b4a5-9687-8765-432109876543\",\n \"filename\": \"invoice.pdf\",\n \"pages\": 2,\n \"size_bytes\": 184320,\n \"type_detected\": \"Invoice\",\n \"language_detected\": \"en\"\n },\n \"data\": {\n \"vendor_name\": \"Acme GmbH\",\n \"total_amount\": 14250.00,\n \"invoice_date\": \"2025-03-15\"\n },\n \"confidence\": {\n \"overall\": 0.96,\n \"fields\": {\n \"vendor_name\": 0.97,\n \"total_amount\": 0.94,\n \"invoice_date\": 0.99\n }\n },\n \"processing\": {\n \"duration_ms\": 1840,\n \"pages_processed\": 2,\n \"region\": \"eu-west\"\n },\n \"links\": {\n \"self\": \"/v1/extractions/d1a2b3c4-5678-9abc-def0-1234567890ab\",\n \"document\": \"/v1/documents/f0e1d2c3-b4a5-9687-8765-432109876543\"\n }\n}\n```\n\n- **`data`** \u2014 extracted fields as key-value pairs matching your schema.\n- **`confidence.fields`** \u2014 per-field score from 0 to 1. Above 0.9 is high confidence; below 0.7 flags for review.\n- **`extraction_id`** \u2014 use this to retrieve, correct, or deliver results later.\n- Full response schema: [ExtractSyncResponse](#/components/schemas/ExtractSyncResponse)\n\n**4. Next steps**\n\n- **50+ pages?** Use async mode \u2014 see [Async Extraction Flow](#section/Async-Extraction-Flow) below.\n- **Reusable schemas** \u2014 save field definitions with `POST /v1/schemas`, then pass `schema_id` on future extractions.\n- **Receive results via webhook** \u2014 configure a delivery destination and listen for `document.extracted` events. See the [Delivery](#tag/Delivery) tag.\n\n---\n\n## Authentication\n\nAll requests require a Bearer token in the `Authorization` header.\nAPI keys are prefixed with `tlnc_` and scoped per customer.\n\n```\nAuthorization: Bearer tlnc_live_abc123...\n```\n\n## Async Extraction Pattern\n\nSmall documents (\u22645 pages) are processed synchronously and return a `200`\nwith the extracted data immediately. Larger documents return a `202 Accepted`\nwith a `poll_url` \u2014 poll `GET /v1/documents/{id}` until `status` transitions\nto `completed`, then fetch results via `GET /v1/documents/{id}/extractions`.\n\nYou can force async processing by passing `options: {\"async\": true}` on\nany extraction request. Combine with webhooks for a fully event-driven flow:\nconfigure a webhook destination under Delivery and listen for the\n`extraction.complete` event.\n\n**Job status lifecycle:** `pending` \u2192 `processing` \u2192 `complete` | `failed`\n\n## Rate Limits\n\nRequests are metered per calendar day (UTC). Limits depend on your plan tier:\n\n| Tier | Extract | Platform | Ingest |\n|------------|---------|----------|--------|\n| Free | 50/day | 500/day | 50/day |\n| Pro | 2,000 | 10,000 | 2,000 |\n| Enterprise | Unlimited | Unlimited | Unlimited |\n\nEvery response includes rate-limit headers:\n- `X-RateLimit-Limit` \u2014 daily cap for the namespace\n- `X-RateLimit-Remaining` \u2014 requests left today\n- `X-RateLimit-Reset` \u2014 ISO 8601 timestamp when the window resets (midnight UTC)\n\n## Pagination\n\nList endpoints use cursor-based pagination. Pass `limit` (1\u2013100, default 20),\n`cursor` (opaque token from `pagination.next_cursor`), and `order` (`asc` or `desc`, default `desc`).\n\n## Errors\n\nAll errors return a JSON body with `error` (machine-readable code) and `message`\n(human-readable explanation). Additional fields vary by error type.\n\n| Code | Error | Description |\n|------|--------------------|------------------------------------------|\n| 400 | validation_error | Request body is malformed or invalid |\n| 401 | unauthorized | Missing or invalid API key |\n| 403 | insufficient_scope | API key lacks the required scope |\n| 404 | not_found | Resource does not exist |\n| 409 | conflict | Resource state conflict |\n| 413 | payload_too_large | File exceeds 500 MB limit |\n| 422 | extraction_failed | Document could not be processed |\n| 429 | rate_limit_exceeded| Daily rate limit reached |\n| 500 | internal_error | Unexpected server error (retryable) |\n\nEvery error response follows this envelope:\n\n```json\n{\n \"statusCode\": 400,\n \"code\": \"VALIDATION_ERROR\",\n \"error\": \"Bad Request\",\n \"message\": \"name is required.\",\n \"retryable\": false,\n \"timestamp\": \"2026-04-25T14:30:00.000Z\",\n \"path\": \"/v1/schemas\"\n}\n```\n\nThe `code` field is one of: `VALIDATION_ERROR`, `AUTH_REQUIRED`, `TOKEN_EXPIRED`,\n`INSUFFICIENT_PERMISSIONS`, `RESOURCE_NOT_FOUND`, `QUOTA_EXCEEDED`,\n`INSUFFICIENT_CREDITS`, `LLM_RATE_LIMITED`, `LLM_TIMEOUT`, `LLM_UNAVAILABLE`,\n`OCR_FAILED`, `EXTRACTION_FAILED`, `EXTRACTION_TIMEOUT`, `FILE_TOO_LARGE`,\n`DUPLICATE_RESOURCE`, `DATASPACE_RUN_FAILED`, `INTERNAL_ERROR`.\n\n## Async Extraction Flow\n\nDocuments \u22645 pages return results synchronously (`200`). Larger documents\n\u2014 or any request with `options: {\"async\": true}` \u2014 return `202 Accepted`.\n\n**1. Submit extraction:**\n\n```bash\ncurl -X POST https://api.talonic.com/v1/extract \\\n -H \"Authorization: Bearer tlnc_live_abc123\" \\\n -F \"file=@contract.pdf\" \\\n -F 'options={\"async\": true}'\n```\n\nResponse `202`:\n```json\n{\n \"request_id\": \"req_x7y8z9a0\",\n \"status\": \"processing\",\n \"document\": { \"id\": \"f0e1d2c3-b4a5-9687-8765-432109876543\" },\n \"poll_url\": \"/v1/documents/f0e1d2c3-b4a5-9687-8765-432109876543\"\n}\n```\n\n**2. Poll until complete:**\n\n```bash\ncurl https://api.talonic.com/v1/documents/f0e1d2c3-b4a5-9687-8765-432109876543 \\\n -H \"Authorization: Bearer tlnc_live_abc123\"\n```\n\nWhile processing: `{ \"status\": \"processing\" }`\nWhen done: `{ \"status\": \"completed\" }`\n\n**3. Retrieve results:**\n\n```bash\ncurl https://api.talonic.com/v1/documents/f0e1d2c3-b4a5-9687-8765-432109876543/extractions \\\n -H \"Authorization: Bearer tlnc_live_abc123\"\n```\n\n**Python \u2014 complete async flow with exponential backoff:**\n\n```python\nimport time\nimport requests\n\nAPI_KEY = \"tlnc_live_...\"\nBASE = \"https://api.talonic.com/v1\"\nHEADERS = {\"Authorization\": f\"Bearer {API_KEY}\"}\n\n# Step 1: Submit async extraction\nresp = requests.post(f\"{BASE}/extract\",\n headers=HEADERS,\n files={\"file\": open(\"contract.pdf\", \"rb\")},\n data={\"options\": '{\"async\": true}'})\ndoc_id = resp.json()[\"document\"][\"id\"]\n\n# Step 2: Poll with exponential backoff (2s \u2192 4s \u2192 8s \u2192 16s \u2192 30s cap)\ndelay = 2\nfor _ in range(20):\n time.sleep(delay)\n doc = requests.get(f\"{BASE}/documents/{doc_id}\", headers=HEADERS).json()\n if doc[\"status\"] == \"completed\":\n break\n if doc[\"status\"] == \"error\":\n raise Exception(f\"Extraction failed: {doc.get('error')}\")\n delay = min(delay * 2, 30)\n\n# Step 3: Retrieve extracted data\nextractions = requests.get(\n f\"{BASE}/documents/{doc_id}/extractions\", headers=HEADERS).json()\ndata = extractions[\"data\"][0][\"data\"]\nconfidence = extractions[\"data\"][0][\"confidence\"][\"overall\"]\nprint(f\"Extracted {len(data)} fields (confidence: {confidence})\")\nprint(data)\n# \u2192 {\"vendor_name\": \"Acme Corp\", \"total_amount\": 1250.00, ...}\n```\n\n**TypeScript \u2014 same flow:**\n\n```typescript\nconst API_KEY = \"tlnc_live_...\";\nconst BASE = \"https://api.talonic.com/v1\";\nconst headers = { Authorization: `Bearer ${API_KEY}` };\n\n// Step 1: Submit async extraction\nconst form = new FormData();\nform.append(\"file\", fs.createReadStream(\"contract.pdf\"));\nform.append(\"options\", '{\"async\": true}');\nconst { document } = await fetch(`${BASE}/extract`, {\n method: \"POST\", headers, body: form,\n}).then((r) => r.json());\n\n// Step 2: Poll with exponential backoff\nlet delay = 2000;\nlet doc: any;\nfor (let i = 0; i < 20; i++) {\n await new Promise((r) => setTimeout(r, delay));\n doc = await fetch(`${BASE}/documents/${document.id}`, { headers }).then((r) => r.json());\n if (doc.status === \"completed\") break;\n if (doc.status === \"error\") throw new Error(`Extraction failed: ${doc.error}`);\n delay = Math.min(delay * 2, 30_000);\n}\n\n// Step 3: Retrieve extracted data\nconst { data: extractions } = await fetch(\n `${BASE}/documents/${document.id}/extractions`, { headers }\n).then((r) => r.json());\nconsole.log(extractions[0].data);\n// \u2192 { vendor_name: \"Acme Corp\", total_amount: 1250.00, ... }\n```\n\nRecommended polling: 2s initial, exponential backoff (2\u21924\u21928\u219216\u219230s cap),\ntimeout after 5 minutes.\n\n**Alternative \u2014 Webhooks:** Configure a delivery destination and listen for\n`document.extracted` events. See the Delivery tag.\n\n**Job status state machine:**\n`pending` \u2192 `queued` \u2192 `processing` \u2192 `complete` | `failed`\n\n## Performance\n\n| Document size | Expected latency | Max timeout |\n|---------------|------------------|-------------|\n| 1\u20135 pages | Sync, <3s | 30s |\n| 6\u201350 pages | <30s average | 5 min |\n| 50+ pages | <5 min average | 30 min |\n\n**Uptime SLA:** 99.5% (Pro), custom (Enterprise).\n\n**Max file size:** 500 MB. JSON request bodies (schemas, jobs): 1 MB.\n\n**Idempotency:** Pass `Idempotency-Key` header on POST requests. Keys are\nvalid for 24 hours and scoped per API key. Duplicates return the cached\nresponse with `cached: true`.\n",
|
|
6
|
+
"description": "Structure any document into schema-validated data.\n\nThe Talonic API lets you extract structured data from documents (PDFs, images,\nDOCX, CSV, plain text), manage reusable extraction schemas, track async jobs,\nand organise documents through sources.\n\n## Quick Start\n\n**1. Get your API key**\n\nSign up at [app.talonic.com](https://app.talonic.com) → Settings → API Keys → Create key.\nKeys start with `tlnc_live_` (production) or `tlnc_test_` (sandbox).\nAll examples below use `tlnc_live_abc123` as a placeholder.\n\n**2. Extract your first document**\n\n```bash\ncurl -X POST https://api.talonic.com/v1/extract \\\n -H \"Authorization: Bearer tlnc_live_abc123\" \\\n -F \"file=@invoice.pdf\" \\\n -F 'schema={\"properties\":{\"vendor_name\":{\"type\":\"string\"},\"total_amount\":{\"type\":\"number\"},\"invoice_date\":{\"type\":\"string\"}}}'\n```\n\n**Python:**\n```python\nimport requests\nresp = requests.post(\"https://api.talonic.com/v1/extract\",\n headers={\"Authorization\": \"Bearer tlnc_live_abc123\"},\n files={\"file\": open(\"invoice.pdf\", \"rb\")},\n data={\"schema\": '{\"properties\":{\"vendor_name\":{\"type\":\"string\"},\"total_amount\":{\"type\":\"number\"},\"invoice_date\":{\"type\":\"string\"}}}'})\nprint(resp.json()[\"data\"])\n```\n\n**TypeScript:**\n```typescript\nconst form = new FormData();\nform.append(\"file\", fs.createReadStream(\"invoice.pdf\"));\nform.append(\"schema\", '{\"properties\":{\"vendor_name\":{\"type\":\"string\"},\"total_amount\":{\"type\":\"number\"},\"invoice_date\":{\"type\":\"string\"}}}');\nconst res = await fetch(\"https://api.talonic.com/v1/extract\", {\n method: \"POST\",\n headers: { Authorization: \"Bearer tlnc_live_abc123\" },\n body: form,\n}).then(r => r.json());\nconsole.log(res.data);\n```\n\n**3. What you get back**\n\n```json\n{\n \"extraction_id\": \"d1a2b3c4-5678-9abc-def0-1234567890ab\",\n \"request_id\": \"req_x7y8z9a0b1c2d3e4\",\n \"status\": \"complete\",\n \"document\": {\n \"id\": \"f0e1d2c3-b4a5-9687-8765-432109876543\",\n \"filename\": \"invoice.pdf\",\n \"pages\": 2,\n \"size_bytes\": 184320,\n \"type_detected\": \"Invoice\",\n \"language_detected\": \"en\"\n },\n \"data\": {\n \"vendor_name\": \"Acme GmbH\",\n \"total_amount\": 14250.00,\n \"invoice_date\": \"2025-03-15\"\n },\n \"confidence\": {\n \"overall\": 0.96,\n \"fields\": {\n \"vendor_name\": 0.97,\n \"total_amount\": 0.94,\n \"invoice_date\": 0.99\n }\n },\n \"processing\": {\n \"duration_ms\": 1840,\n \"pages_processed\": 2,\n \"region\": \"eu-west\"\n },\n \"links\": {\n \"self\": \"/v1/extractions/d1a2b3c4-5678-9abc-def0-1234567890ab\",\n \"document\": \"/v1/documents/f0e1d2c3-b4a5-9687-8765-432109876543\"\n }\n}\n```\n\n- **`data`** — extracted fields as key-value pairs matching your schema.\n- **`confidence.fields`** — per-field score from 0 to 1. Above 0.9 is high confidence; below 0.7 flags for review.\n- **`extraction_id`** — use this to retrieve, correct, or deliver results later.\n- Full response schema: [ExtractSyncResponse](#/components/schemas/ExtractSyncResponse)\n\n**4. Next steps**\n\n- **50+ pages?** Use async mode — see [Async Extraction Flow](#section/Async-Extraction-Flow) below.\n- **Reusable schemas** — save field definitions with `POST /v1/schemas`, then pass `schema_id` on future extractions.\n- **Receive results via webhook** — configure a delivery destination and listen for `document.extracted` events. See the [Delivery](#tag/Delivery) tag.\n\n---\n\n## Authentication\n\nAll requests require a Bearer token in the `Authorization` header.\nAPI keys are prefixed with `tlnc_` and scoped per customer.\n\n```\nAuthorization: Bearer tlnc_live_abc123...\n```\n\n## Async Extraction Pattern\n\nSmall documents (≤5 pages) are processed synchronously and return a `200`\nwith the extracted data immediately. Larger documents return a `202 Accepted`\nwith a `poll_url` — poll `GET /v1/documents/{id}` until `status` transitions\nto `completed`, then fetch results via `GET /v1/documents/{id}/extractions`.\n\nYou can force async processing by passing `options: {\"async\": true}` on\nany extraction request. Combine with webhooks for a fully event-driven flow:\nconfigure a webhook destination under Delivery and listen for the\n`extraction.complete` event.\n\n**Job status lifecycle:** `pending` → `processing` → `complete` | `failed`\n\n## Rate Limits\n\nRequests are metered per calendar day (UTC). Limits depend on your plan tier:\n\n| Tier | Extract | Platform | Ingest |\n|------------|---------|----------|--------|\n| Free | 50/day | 500/day | 50/day |\n| Pro | 2,000 | 10,000 | 2,000 |\n| Enterprise | Unlimited | Unlimited | Unlimited |\n\nEvery response includes rate-limit headers:\n- `X-RateLimit-Limit` — daily cap for the namespace\n- `X-RateLimit-Remaining` — requests left today\n- `X-RateLimit-Reset` — ISO 8601 timestamp when the window resets (midnight UTC)\n\n## Pagination\n\nList endpoints use cursor-based pagination. Pass `limit` (1–100, default 20),\n`cursor` (opaque token from `pagination.next_cursor`), and `order` (`asc` or `desc`, default `desc`).\n\n## Errors\n\nAll errors return a JSON body with `error` (machine-readable code) and `message`\n(human-readable explanation). Additional fields vary by error type.\n\n| Code | Error | Description |\n|------|--------------------|------------------------------------------|\n| 400 | validation_error | Request body is malformed or invalid |\n| 401 | unauthorized | Missing or invalid API key |\n| 403 | insufficient_scope | API key lacks the required scope |\n| 404 | not_found | Resource does not exist |\n| 409 | conflict | Resource state conflict |\n| 413 | payload_too_large | File exceeds 500 MB limit |\n| 422 | extraction_failed | Document could not be processed |\n| 429 | rate_limit_exceeded| Daily rate limit reached |\n| 500 | internal_error | Unexpected server error (retryable) |\n\nEvery error response follows this envelope:\n\n```json\n{\n \"statusCode\": 400,\n \"code\": \"VALIDATION_ERROR\",\n \"error\": \"Bad Request\",\n \"message\": \"name is required.\",\n \"retryable\": false,\n \"timestamp\": \"2026-04-25T14:30:00.000Z\",\n \"path\": \"/v1/schemas\"\n}\n```\n\nThe `code` field is one of: `VALIDATION_ERROR`, `AUTH_REQUIRED`, `TOKEN_EXPIRED`,\n`INSUFFICIENT_PERMISSIONS`, `RESOURCE_NOT_FOUND`, `QUOTA_EXCEEDED`,\n`INSUFFICIENT_CREDITS`, `LLM_RATE_LIMITED`, `LLM_TIMEOUT`, `LLM_UNAVAILABLE`,\n`OCR_FAILED`, `EXTRACTION_FAILED`, `EXTRACTION_TIMEOUT`, `FILE_TOO_LARGE`,\n`DUPLICATE_RESOURCE`, `DATASPACE_RUN_FAILED`, `INTERNAL_ERROR`.\n\n## Async Extraction Flow\n\nDocuments ≤5 pages return results synchronously (`200`). Larger documents\n— or any request with `options: {\"async\": true}` — return `202 Accepted`.\n\n**1. Submit extraction:**\n\n```bash\ncurl -X POST https://api.talonic.com/v1/extract \\\n -H \"Authorization: Bearer tlnc_live_abc123\" \\\n -F \"file=@contract.pdf\" \\\n -F 'options={\"async\": true}'\n```\n\nResponse `202`:\n```json\n{\n \"request_id\": \"req_x7y8z9a0\",\n \"status\": \"processing\",\n \"document\": { \"id\": \"f0e1d2c3-b4a5-9687-8765-432109876543\" },\n \"poll_url\": \"/v1/documents/f0e1d2c3-b4a5-9687-8765-432109876543\"\n}\n```\n\n**2. Poll until complete:**\n\n```bash\ncurl https://api.talonic.com/v1/documents/f0e1d2c3-b4a5-9687-8765-432109876543 \\\n -H \"Authorization: Bearer tlnc_live_abc123\"\n```\n\nWhile processing: `{ \"status\": \"processing\" }`\nWhen done: `{ \"status\": \"completed\" }`\n\n**3. Retrieve results:**\n\n```bash\ncurl https://api.talonic.com/v1/documents/f0e1d2c3-b4a5-9687-8765-432109876543/extractions \\\n -H \"Authorization: Bearer tlnc_live_abc123\"\n```\n\n**Python — complete async flow with exponential backoff:**\n\n```python\nimport time\nimport requests\n\nAPI_KEY = \"tlnc_live_...\"\nBASE = \"https://api.talonic.com/v1\"\nHEADERS = {\"Authorization\": f\"Bearer {API_KEY}\"}\n\n# Step 1: Submit async extraction\nresp = requests.post(f\"{BASE}/extract\",\n headers=HEADERS,\n files={\"file\": open(\"contract.pdf\", \"rb\")},\n data={\"options\": '{\"async\": true}'})\ndoc_id = resp.json()[\"document\"][\"id\"]\n\n# Step 2: Poll with exponential backoff (2s → 4s → 8s → 16s → 30s cap)\ndelay = 2\nfor _ in range(20):\n time.sleep(delay)\n doc = requests.get(f\"{BASE}/documents/{doc_id}\", headers=HEADERS).json()\n if doc[\"status\"] == \"completed\":\n break\n if doc[\"status\"] == \"error\":\n raise Exception(f\"Extraction failed: {doc.get('error')}\")\n delay = min(delay * 2, 30)\n\n# Step 3: Retrieve extracted data\nextractions = requests.get(\n f\"{BASE}/documents/{doc_id}/extractions\", headers=HEADERS).json()\ndata = extractions[\"data\"][0][\"data\"]\nconfidence = extractions[\"data\"][0][\"confidence\"][\"overall\"]\nprint(f\"Extracted {len(data)} fields (confidence: {confidence})\")\nprint(data)\n# → {\"vendor_name\": \"Acme Corp\", \"total_amount\": 1250.00, ...}\n```\n\n**TypeScript — same flow:**\n\n```typescript\nconst API_KEY = \"tlnc_live_...\";\nconst BASE = \"https://api.talonic.com/v1\";\nconst headers = { Authorization: `Bearer ${API_KEY}` };\n\n// Step 1: Submit async extraction\nconst form = new FormData();\nform.append(\"file\", fs.createReadStream(\"contract.pdf\"));\nform.append(\"options\", '{\"async\": true}');\nconst { document } = await fetch(`${BASE}/extract`, {\n method: \"POST\", headers, body: form,\n}).then((r) => r.json());\n\n// Step 2: Poll with exponential backoff\nlet delay = 2000;\nlet doc: any;\nfor (let i = 0; i < 20; i++) {\n await new Promise((r) => setTimeout(r, delay));\n doc = await fetch(`${BASE}/documents/${document.id}`, { headers }).then((r) => r.json());\n if (doc.status === \"completed\") break;\n if (doc.status === \"error\") throw new Error(`Extraction failed: ${doc.error}`);\n delay = Math.min(delay * 2, 30_000);\n}\n\n// Step 3: Retrieve extracted data\nconst { data: extractions } = await fetch(\n `${BASE}/documents/${document.id}/extractions`, { headers }\n).then((r) => r.json());\nconsole.log(extractions[0].data);\n// → { vendor_name: \"Acme Corp\", total_amount: 1250.00, ... }\n```\n\nRecommended polling: 2s initial, exponential backoff (2→4→8→16→30s cap),\ntimeout after 5 minutes.\n\n**Alternative — Webhooks:** Configure a delivery destination and listen for\n`document.extracted` events. See the Delivery tag.\n\n**Job status state machine:**\n`pending` → `queued` → `processing` → `complete` | `failed`\n\n## Performance\n\n| Document size | Expected latency | Max timeout |\n|---------------|------------------|-------------|\n| 1–5 pages | Sync, <3s | 30s |\n| 6–50 pages | <30s average | 5 min |\n| 50+ pages | <5 min average | 30 min |\n\n**Uptime SLA:** 99.5% (Pro), custom (Enterprise).\n\n**Max file size:** 500 MB. JSON request bodies (schemas, jobs): 1 MB.\n\n**Idempotency:** Pass `Idempotency-Key` header on POST requests. Keys are\nvalid for 24 hours and scoped per API key. Duplicates return the cached\nresponse with `cached: true`.\n",
|
|
7
7
|
"contact": {
|
|
8
8
|
"name": "Talonic Support",
|
|
9
9
|
"email": "support@talonic.ai",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"name": "Delivery",
|
|
58
|
-
"description": "Outbound delivery pipeline
|
|
58
|
+
"description": "Outbound delivery pipeline — routing rules, delivery destinations (webhook, SFTP,\nS3, Azure Blob, Google Drive, OneDrive), bindings, filters, and the delivery\nhistory/DLQ/events log.\n\n## Webhook Contract\n\n**Event payload:**\n```json\n{\n \"event\": {\n \"event_type\": \"document.extracted\",\n \"event_id\": \"42\",\n \"binding_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"idempotency_key\": \"c9f3a7e1b2d4f6a8e0c2d4f6a8e0c2d4\",\n \"attempt\": 1,\n \"delivered_at\": \"2026-04-25T14:30:00.000Z\"\n },\n \"payload\": { \"document_id\": \"...\", \"data\": { \"...extracted fields...\" } }\n}\n```\n\n**Event types:** `document.extracted`, `document.extraction_failed`,\n`run.dataspace.completed`, `run.dataspace.failed`, `result.dataspace.completed`,\n`result.dataspace.failed`, `run.structuring.completed`, `run.structuring.failed`,\n`run.resolution.completed`, `run.resolution.failed`, `run.extraction.completed`,\n`run.extraction.failed`, `result.flagged`, `result.approved`, `result.rejected`,\n`delivery.item.completed`, `delivery.item.failed`.\n\n**Signature verification (HMAC-SHA256):**\n\nHeader: `X-Talonic-Signature: t=1714060200000,v1=abc123...`\n\n```javascript\nconst crypto = require('crypto');\nconst [tPart, vPart] = signature.split(',');\nconst timestamp = tPart.split('=')[1];\nconst received = vPart.split('=')[1];\nconst expected = crypto.createHmac('sha256', signingSecret)\n .update(timestamp + '.' + rawBody).digest('hex');\nconst valid = crypto.timingSafeEqual(\n Buffer.from(received), Buffer.from(expected));\n```\n\n**Retry policy:** Up to 7 attempts — 0s, 30s, 2m, 8m, 30m, 2h, 8h (~10.5h total).\nHTTP 429/5xx are retryable. HTTP 4xx (except 408) goes to DLQ immediately.\n\n**Dead-letter queue recovery:** When all retries are exhausted, the delivery\nlands in the DLQ. List failed deliveries with `GET /v1/delivery/dlq`\n(filterable by `binding_id` and `error_code`). Inspect a single entry with\n`GET /v1/delivery/dlq/{id}`. Replay with `POST /v1/delivery/dlq/{id}/replay`\n— this deletes the DLQ entry, re-signs the payload with the current\nsigning secret, resets the retry counter to attempt 1, and re-enqueues\nthe delivery through the full backoff ladder.\n"
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
61
|
"name": "Intelligence",
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
},
|
|
140
140
|
"options": {
|
|
141
141
|
"type": "string",
|
|
142
|
-
"description": "JSON string of extraction options.\n- `async` (boolean)
|
|
142
|
+
"description": "JSON string of extraction options.\n- `async` (boolean) — force async (`true`) or sync (`false`) processing.\n"
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
},
|
|
@@ -1950,7 +1950,7 @@
|
|
|
1950
1950
|
"batch"
|
|
1951
1951
|
],
|
|
1952
1952
|
"default": "realtime",
|
|
1953
|
-
"description": "\"realtime\" (default)
|
|
1953
|
+
"description": "\"realtime\" (default) — processed immediately.\n\"batch\" — 50% cost discount, results within 48 hours.\n"
|
|
1954
1954
|
}
|
|
1955
1955
|
}
|
|
1956
1956
|
}
|
|
@@ -2427,7 +2427,7 @@
|
|
|
2427
2427
|
"put": {
|
|
2428
2428
|
"operationId": "updateMatchingConfig",
|
|
2429
2429
|
"summary": "Update a matching configuration",
|
|
2430
|
-
"description": "Partial update
|
|
2430
|
+
"description": "Partial update — only provided keys are applied.",
|
|
2431
2431
|
"tags": [
|
|
2432
2432
|
"Intelligence"
|
|
2433
2433
|
],
|
|
@@ -3110,7 +3110,7 @@
|
|
|
3110
3110
|
"post": {
|
|
3111
3111
|
"operationId": "testDeliveryDestination",
|
|
3112
3112
|
"summary": "Live-ping a destination through the full transport envelope",
|
|
3113
|
-
"description": "Exercises the complete delivery envelope (SSRF guard, payload cap, rate\nlimit, retry ladder is disabled
|
|
3113
|
+
"description": "Exercises the complete delivery envelope (SSRF guard, payload cap, rate\nlimit, retry ladder is disabled — `max_attempts: 1`) with a tiny test\npayload. The returned `success` field reflects whether the connector's\n`deliver()` call returned a non-retryable success; check `httpStatus`\nand `message` for details.\n",
|
|
3114
3114
|
"tags": [
|
|
3115
3115
|
"Delivery"
|
|
3116
3116
|
],
|
|
@@ -3344,7 +3344,7 @@
|
|
|
3344
3344
|
"post": {
|
|
3345
3345
|
"operationId": "previewDeliveryBinding",
|
|
3346
3346
|
"summary": "Synthetic-signal dry-run preview",
|
|
3347
|
-
"description": "Builds a synthetic {DeliveryEvent} that matches the binding's\n`signal_filter.event_type` (overlaying any `signal_filter.match`\nconstraints), then walks the delivery pipeline up to
|
|
3347
|
+
"description": "Builds a synthetic {DeliveryEvent} that matches the binding's\n`signal_filter.event_type` (overlaying any `signal_filter.match`\nconstraints), then walks the delivery pipeline up to — but NOT\nincluding — `connector.deliver()`:\n`resolver.resolve(signal) → projectFieldMap → serializer.serialize`.\n\nWhen the resolver can load a real entity, `sample_mode` is `\"real\"`\nand `projected` / `serialized` / `wire_preview` are populated. If the\nresolver throws (typically `EntityMissingError` because the synthetic\nentity id doesn't exist in this tenant), the service falls back to\n`sample_mode: \"structural\"` — it returns the resolver's declared\n`shape` without concrete data. The preview never makes a network\ncall, never inserts a delivery row, and never touches the DLQ.\n",
|
|
3348
3348
|
"tags": [
|
|
3349
3349
|
"Delivery"
|
|
3350
3350
|
],
|
|
@@ -3355,7 +3355,7 @@
|
|
|
3355
3355
|
],
|
|
3356
3356
|
"responses": {
|
|
3357
3357
|
"200": {
|
|
3358
|
-
"description": "Preview response
|
|
3358
|
+
"description": "Preview response — real dry-run or structural fallback.",
|
|
3359
3359
|
"content": {
|
|
3360
3360
|
"application/json": {
|
|
3361
3361
|
"schema": {
|
|
@@ -3363,7 +3363,7 @@
|
|
|
3363
3363
|
},
|
|
3364
3364
|
"examples": {
|
|
3365
3365
|
"real": {
|
|
3366
|
-
"summary": "Real dry-run
|
|
3366
|
+
"summary": "Real dry-run — resolver loaded a synthetic entity and every pipeline stage ran.",
|
|
3367
3367
|
"value": {
|
|
3368
3368
|
"available": true,
|
|
3369
3369
|
"sample_mode": "real",
|
|
@@ -3399,7 +3399,7 @@
|
|
|
3399
3399
|
}
|
|
3400
3400
|
},
|
|
3401
3401
|
"structural": {
|
|
3402
|
-
"summary": "Structural fallback
|
|
3402
|
+
"summary": "Structural fallback — the resolver couldn't load the synthetic entity, so only the declared shape is returned.",
|
|
3403
3403
|
"value": {
|
|
3404
3404
|
"available": true,
|
|
3405
3405
|
"sample_mode": "structural",
|
|
@@ -3602,7 +3602,7 @@
|
|
|
3602
3602
|
"post": {
|
|
3603
3603
|
"operationId": "replayDeliveryItem",
|
|
3604
3604
|
"summary": "Re-enqueue a delivery attempt",
|
|
3605
|
-
"description": "Enqueues a new attempt for the binding/event pair. Generates a new\nidempotency key
|
|
3605
|
+
"description": "Enqueues a new attempt for the binding/event pair. Generates a new\nidempotency key — replays are new attempts, never mutations.\n",
|
|
3606
3606
|
"tags": [
|
|
3607
3607
|
"Delivery"
|
|
3608
3608
|
],
|
|
@@ -3771,7 +3771,7 @@
|
|
|
3771
3771
|
"post": {
|
|
3772
3772
|
"operationId": "replayDeliveryDlq",
|
|
3773
3773
|
"summary": "Re-enqueue a dead-letter row",
|
|
3774
|
-
"description": "Inserts a fresh BullMQ job for the binding/event pair. The DLQ row is\nleft in place (append-only history)
|
|
3774
|
+
"description": "Inserts a fresh BullMQ job for the binding/event pair. The DLQ row is\nleft in place (append-only history) — it stays readable until\nexplicitly dismissed.\n",
|
|
3775
3775
|
"tags": [
|
|
3776
3776
|
"Delivery"
|
|
3777
3777
|
],
|
|
@@ -3812,7 +3812,7 @@
|
|
|
3812
3812
|
"get": {
|
|
3813
3813
|
"operationId": "listDeliveryEvents",
|
|
3814
3814
|
"summary": "List outbox events",
|
|
3815
|
-
"description": "Raw outbox rows with their processing status. Filter by `event_type`
|
|
3815
|
+
"description": "Raw outbox rows with their processing status. Filter by `event_type` —\npagination via `limit` / `offset`.\n",
|
|
3816
3816
|
"tags": [
|
|
3817
3817
|
"Delivery"
|
|
3818
3818
|
],
|
|
@@ -3878,7 +3878,7 @@
|
|
|
3878
3878
|
"post": {
|
|
3879
3879
|
"operationId": "replayDeliveryEvent",
|
|
3880
3880
|
"summary": "Re-poll an outbox event",
|
|
3881
|
-
"description": "Clears `processed_at` and `processing_status` so the poller re-picks\nthe row on the next tick. The event ID is BIGSERIAL (string)
|
|
3881
|
+
"description": "Clears `processed_at` and `processing_status` so the poller re-picks\nthe row on the next tick. The event ID is BIGSERIAL (string) — no\nUUID validation.\n",
|
|
3882
3882
|
"tags": [
|
|
3883
3883
|
"Delivery"
|
|
3884
3884
|
],
|
|
@@ -4964,7 +4964,7 @@
|
|
|
4964
4964
|
"get": {
|
|
4965
4965
|
"operationId": "getCase",
|
|
4966
4966
|
"summary": "Get a case by key",
|
|
4967
|
-
"description": "Case keys are 8
|
|
4967
|
+
"description": "Case keys are 8–64 char hex strings (SHA-256 hash of the canonical\nentity-value set that defines the cluster). Returns the label,\nnarrative, linked documents, and anomaly count.\n",
|
|
4968
4968
|
"tags": [
|
|
4969
4969
|
"Intelligence"
|
|
4970
4970
|
],
|
|
@@ -5063,7 +5063,7 @@
|
|
|
5063
5063
|
"items": {
|
|
5064
5064
|
"type": "object",
|
|
5065
5065
|
"additionalProperties": true,
|
|
5066
|
-
"description": "Category
|
|
5066
|
+
"description": "Category → subcategory → types hierarchy. Shape is defined by `config/document-ontology.yaml`."
|
|
5067
5067
|
}
|
|
5068
5068
|
}
|
|
5069
5069
|
}
|
|
@@ -5466,7 +5466,7 @@
|
|
|
5466
5466
|
"items": {
|
|
5467
5467
|
"type": "object",
|
|
5468
5468
|
"additionalProperties": true,
|
|
5469
|
-
"description": "Row object
|
|
5469
|
+
"description": "Row object — keys match the dataset's column schema."
|
|
5470
5470
|
}
|
|
5471
5471
|
},
|
|
5472
5472
|
"pagination": {
|
|
@@ -7757,7 +7757,7 @@
|
|
|
7757
7757
|
"get": {
|
|
7758
7758
|
"operationId": "getTelemetrySchemaSummary",
|
|
7759
7759
|
"summary": "Get telemetry summary for a schema",
|
|
7760
|
-
"description": "Aggregate structuring metrics for a schema
|
|
7760
|
+
"description": "Aggregate structuring metrics for a schema — capture hit rate, synthesize rate, strategy distribution, tier funnel.",
|
|
7761
7761
|
"tags": [
|
|
7762
7762
|
"Platform"
|
|
7763
7763
|
],
|
|
@@ -7839,7 +7839,7 @@
|
|
|
7839
7839
|
"get": {
|
|
7840
7840
|
"operationId": "getTelemetrySchemaFields",
|
|
7841
7841
|
"summary": "Get per-field telemetry for a schema",
|
|
7842
|
-
"description": "Field-level structuring metrics
|
|
7842
|
+
"description": "Field-level structuring metrics — per-field state distribution, capture rates, and strategy breakdown.",
|
|
7843
7843
|
"tags": [
|
|
7844
7844
|
"Platform"
|
|
7845
7845
|
],
|
|
@@ -10362,7 +10362,7 @@
|
|
|
10362
10362
|
"get": {
|
|
10363
10363
|
"operationId": "getAgentContext",
|
|
10364
10364
|
"summary": "Get workspace context",
|
|
10365
|
-
"description": "Returns a snapshot of the workspace's current state for the embedded\nAI agent
|
|
10365
|
+
"description": "Returns a snapshot of the workspace's current state for the embedded\nAI agent — document counts, active schemas, recent jobs, and feature\nflags. Useful for bootstrapping agent conversations.\n",
|
|
10366
10366
|
"tags": [
|
|
10367
10367
|
"Platform"
|
|
10368
10368
|
],
|
|
@@ -14814,6 +14814,127 @@
|
|
|
14814
14814
|
}
|
|
14815
14815
|
}
|
|
14816
14816
|
}
|
|
14817
|
+
},
|
|
14818
|
+
"/v1/usage/credits": {
|
|
14819
|
+
"get": {
|
|
14820
|
+
"operationId": "getCreditUsageByFunction",
|
|
14821
|
+
"summary": "Per-function credit consumption",
|
|
14822
|
+
"description": "Credit consumption grouped by platform function (operation_type) from the customer-pay ledger, plus the window total. Shows where credits went (extraction vs structuring vs intelligence ops). Populates once metering is enforcing.",
|
|
14823
|
+
"tags": [
|
|
14824
|
+
"Usage"
|
|
14825
|
+
],
|
|
14826
|
+
"parameters": [
|
|
14827
|
+
{
|
|
14828
|
+
"name": "days",
|
|
14829
|
+
"in": "query",
|
|
14830
|
+
"required": false,
|
|
14831
|
+
"schema": {
|
|
14832
|
+
"type": "integer",
|
|
14833
|
+
"minimum": 1,
|
|
14834
|
+
"maximum": 365,
|
|
14835
|
+
"default": 30
|
|
14836
|
+
},
|
|
14837
|
+
"description": "Trailing reporting window in days (default 30)."
|
|
14838
|
+
}
|
|
14839
|
+
],
|
|
14840
|
+
"responses": {
|
|
14841
|
+
"200": {
|
|
14842
|
+
"description": "Per-function credit consumption.",
|
|
14843
|
+
"content": {
|
|
14844
|
+
"application/json": {
|
|
14845
|
+
"schema": {
|
|
14846
|
+
"type": "object",
|
|
14847
|
+
"properties": {
|
|
14848
|
+
"period_days": {
|
|
14849
|
+
"type": "integer"
|
|
14850
|
+
},
|
|
14851
|
+
"total_credits": {
|
|
14852
|
+
"type": "integer"
|
|
14853
|
+
},
|
|
14854
|
+
"by_function": {
|
|
14855
|
+
"type": "array",
|
|
14856
|
+
"items": {
|
|
14857
|
+
"type": "object",
|
|
14858
|
+
"properties": {
|
|
14859
|
+
"operation_type": {
|
|
14860
|
+
"type": "string"
|
|
14861
|
+
},
|
|
14862
|
+
"operations": {
|
|
14863
|
+
"type": "integer"
|
|
14864
|
+
},
|
|
14865
|
+
"credits": {
|
|
14866
|
+
"type": "integer"
|
|
14867
|
+
}
|
|
14868
|
+
}
|
|
14869
|
+
}
|
|
14870
|
+
}
|
|
14871
|
+
}
|
|
14872
|
+
}
|
|
14873
|
+
}
|
|
14874
|
+
}
|
|
14875
|
+
}
|
|
14876
|
+
}
|
|
14877
|
+
}
|
|
14878
|
+
},
|
|
14879
|
+
"/v1/pricing": {
|
|
14880
|
+
"get": {
|
|
14881
|
+
"operationId": "getPricing",
|
|
14882
|
+
"summary": "Credit pricing catalog",
|
|
14883
|
+
"description": "Public (unauthenticated) machine-readable credit pricing catalog: fixed per-unit credit rates, EUR equivalents, the credits-per-EUR conversion rate, and processing-mode multipliers (e.g. batch at 0.5x). Predict spend before running anything.",
|
|
14884
|
+
"tags": [
|
|
14885
|
+
"Pricing"
|
|
14886
|
+
],
|
|
14887
|
+
"responses": {
|
|
14888
|
+
"200": {
|
|
14889
|
+
"description": "The credit pricing catalog.",
|
|
14890
|
+
"content": {
|
|
14891
|
+
"application/json": {
|
|
14892
|
+
"schema": {
|
|
14893
|
+
"type": "object",
|
|
14894
|
+
"properties": {
|
|
14895
|
+
"currency": {
|
|
14896
|
+
"type": "string",
|
|
14897
|
+
"example": "EUR"
|
|
14898
|
+
},
|
|
14899
|
+
"credits_per_eur": {
|
|
14900
|
+
"type": "number"
|
|
14901
|
+
},
|
|
14902
|
+
"multipliers": {
|
|
14903
|
+
"type": "object",
|
|
14904
|
+
"additionalProperties": {
|
|
14905
|
+
"type": "number"
|
|
14906
|
+
}
|
|
14907
|
+
},
|
|
14908
|
+
"units": {
|
|
14909
|
+
"type": "array",
|
|
14910
|
+
"items": {
|
|
14911
|
+
"type": "object",
|
|
14912
|
+
"properties": {
|
|
14913
|
+
"unit": {
|
|
14914
|
+
"type": "string"
|
|
14915
|
+
},
|
|
14916
|
+
"label": {
|
|
14917
|
+
"type": "string"
|
|
14918
|
+
},
|
|
14919
|
+
"credits": {
|
|
14920
|
+
"type": "number"
|
|
14921
|
+
},
|
|
14922
|
+
"eur": {
|
|
14923
|
+
"type": "number"
|
|
14924
|
+
},
|
|
14925
|
+
"free": {
|
|
14926
|
+
"type": "boolean"
|
|
14927
|
+
}
|
|
14928
|
+
}
|
|
14929
|
+
}
|
|
14930
|
+
}
|
|
14931
|
+
}
|
|
14932
|
+
}
|
|
14933
|
+
}
|
|
14934
|
+
}
|
|
14935
|
+
}
|
|
14936
|
+
}
|
|
14937
|
+
}
|
|
14817
14938
|
}
|
|
14818
14939
|
},
|
|
14819
14940
|
"components": {
|
|
@@ -14846,7 +14967,7 @@
|
|
|
14846
14967
|
"maximum": 100,
|
|
14847
14968
|
"default": 20
|
|
14848
14969
|
},
|
|
14849
|
-
"description": "Maximum number of items to return (1
|
|
14970
|
+
"description": "Maximum number of items to return (1–100)."
|
|
14850
14971
|
},
|
|
14851
14972
|
"Cursor": {
|
|
14852
14973
|
"name": "cursor",
|
|
@@ -15178,7 +15299,7 @@
|
|
|
15178
15299
|
},
|
|
15179
15300
|
"attempt": {
|
|
15180
15301
|
"type": "integer",
|
|
15181
|
-
"description": "Delivery attempt number (1
|
|
15302
|
+
"description": "Delivery attempt number (1–7).",
|
|
15182
15303
|
"example": 1
|
|
15183
15304
|
},
|
|
15184
15305
|
"delivered_at": {
|
|
@@ -16103,7 +16224,7 @@
|
|
|
16103
16224
|
"integer",
|
|
16104
16225
|
"null"
|
|
16105
16226
|
],
|
|
16106
|
-
"description": "Percentage complete (0
|
|
16227
|
+
"description": "Percentage complete (0–100). Only present while `processing`.",
|
|
16107
16228
|
"example": 45
|
|
16108
16229
|
},
|
|
16109
16230
|
"estimated_seconds_remaining": {
|
|
@@ -16707,7 +16828,7 @@
|
|
|
16707
16828
|
},
|
|
16708
16829
|
"boolean_format": {
|
|
16709
16830
|
"type": "array",
|
|
16710
|
-
"description": "Exactly 2 strings
|
|
16831
|
+
"description": "Exactly 2 strings — `[true_value, false_value]`.",
|
|
16711
16832
|
"minItems": 2,
|
|
16712
16833
|
"maxItems": 2,
|
|
16713
16834
|
"items": {
|
|
@@ -16753,7 +16874,7 @@
|
|
|
16753
16874
|
},
|
|
16754
16875
|
"boolean_format": {
|
|
16755
16876
|
"type": "array",
|
|
16756
|
-
"description": "Exactly 2 strings
|
|
16877
|
+
"description": "Exactly 2 strings — `[true_value, false_value]`.",
|
|
16757
16878
|
"minItems": 2,
|
|
16758
16879
|
"maxItems": 2,
|
|
16759
16880
|
"items": {
|
|
@@ -16768,7 +16889,7 @@
|
|
|
16768
16889
|
},
|
|
16769
16890
|
"DialectUpdateRequest": {
|
|
16770
16891
|
"type": "object",
|
|
16771
|
-
"description": "Partial update
|
|
16892
|
+
"description": "Partial update — only supplied keys are patched.",
|
|
16772
16893
|
"properties": {
|
|
16773
16894
|
"name": {
|
|
16774
16895
|
"type": "string"
|
|
@@ -16800,7 +16921,7 @@
|
|
|
16800
16921
|
},
|
|
16801
16922
|
"MatchingFieldMapping": {
|
|
16802
16923
|
"type": "object",
|
|
16803
|
-
"description": "Field-mapping entry linking an extracted field to a reference-data column.\nThe shape below is illustrative
|
|
16924
|
+
"description": "Field-mapping entry linking an extracted field to a reference-data column.\nThe shape below is illustrative — the platform accepts any object shape and\napplies matching using the documented keys when present.\n",
|
|
16804
16925
|
"additionalProperties": true,
|
|
16805
16926
|
"properties": {
|
|
16806
16927
|
"extracted_field": {
|
|
@@ -16962,7 +17083,7 @@
|
|
|
16962
17083
|
},
|
|
16963
17084
|
"MatchingConfigUpdateRequest": {
|
|
16964
17085
|
"type": "object",
|
|
16965
|
-
"description": "Partial update
|
|
17086
|
+
"description": "Partial update — only provided keys are applied.",
|
|
16966
17087
|
"properties": {
|
|
16967
17088
|
"name": {
|
|
16968
17089
|
"type": "string"
|
|
@@ -17269,7 +17390,7 @@
|
|
|
17269
17390
|
},
|
|
17270
17391
|
"RoutingRuleUpdateRequest": {
|
|
17271
17392
|
"type": "object",
|
|
17272
|
-
"description": "Partial update
|
|
17393
|
+
"description": "Partial update — only supplied keys are patched.",
|
|
17273
17394
|
"properties": {
|
|
17274
17395
|
"name": {
|
|
17275
17396
|
"type": "string"
|
|
@@ -17323,7 +17444,7 @@
|
|
|
17323
17444
|
},
|
|
17324
17445
|
"type": {
|
|
17325
17446
|
"type": "string",
|
|
17326
|
-
"description": "Connector type discriminant
|
|
17447
|
+
"description": "Connector type discriminant — resolves to a registered connector. Live types are `webhook`, `sftp`, `s3`, `azure_blob`, `google_drive`, `onedrive`, `google_sheets`.",
|
|
17327
17448
|
"example": "webhook"
|
|
17328
17449
|
},
|
|
17329
17450
|
"config": {
|
|
@@ -17419,7 +17540,7 @@
|
|
|
17419
17540
|
},
|
|
17420
17541
|
"UpdateDestinationRequest": {
|
|
17421
17542
|
"type": "object",
|
|
17422
|
-
"description": "Partial update
|
|
17543
|
+
"description": "Partial update — every field optional. Only supplied fields are written.",
|
|
17423
17544
|
"properties": {
|
|
17424
17545
|
"name": {
|
|
17425
17546
|
"type": "string"
|
|
@@ -17517,7 +17638,7 @@
|
|
|
17517
17638
|
},
|
|
17518
17639
|
"FieldMap": {
|
|
17519
17640
|
"type": "object",
|
|
17520
|
-
"description": "Declarative projection applied between resolver output and serializer\ninput. Operations run in fixed order: drop
|
|
17641
|
+
"description": "Declarative projection applied between resolver output and serializer\ninput. Operations run in fixed order: drop → rename → static.\n",
|
|
17521
17642
|
"properties": {
|
|
17522
17643
|
"rules": {
|
|
17523
17644
|
"type": "array",
|
|
@@ -17540,7 +17661,7 @@
|
|
|
17540
17661
|
"static": {
|
|
17541
17662
|
"type": "object",
|
|
17542
17663
|
"additionalProperties": true,
|
|
17543
|
-
"description": "Literal key/value pairs added last
|
|
17664
|
+
"description": "Literal key/value pairs added last — always wins collisions."
|
|
17544
17665
|
},
|
|
17545
17666
|
"drop": {
|
|
17546
17667
|
"type": "array",
|
|
@@ -17700,7 +17821,7 @@
|
|
|
17700
17821
|
},
|
|
17701
17822
|
"UpdateBindingRequest": {
|
|
17702
17823
|
"type": "object",
|
|
17703
|
-
"description": "Partial update
|
|
17824
|
+
"description": "Partial update — every field optional.",
|
|
17704
17825
|
"properties": {
|
|
17705
17826
|
"name": {
|
|
17706
17827
|
"type": "string"
|
|
@@ -17874,7 +17995,7 @@
|
|
|
17874
17995
|
],
|
|
17875
17996
|
"format": "uuid",
|
|
17876
17997
|
"example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
|
|
17877
|
-
"description": "FK to the last DeliveryItem attempt (nullable
|
|
17998
|
+
"description": "FK to the last DeliveryItem attempt (nullable — `ON DELETE SET NULL`)."
|
|
17878
17999
|
},
|
|
17879
18000
|
"error_code": {
|
|
17880
18001
|
"type": "string",
|
|
@@ -17906,7 +18027,7 @@
|
|
|
17906
18027
|
"created_at",
|
|
17907
18028
|
"processing_attempts"
|
|
17908
18029
|
],
|
|
17909
|
-
"description": "Outbox record (not the typed producer DTO). Represents a single row in\nthe `delivery_events` table. `event_type` is a string discriminant
|
|
18030
|
+
"description": "Outbox record (not the typed producer DTO). Represents a single row in\nthe `delivery_events` table. `event_type` is a string discriminant —\nsee `/v1/delivery/catalog/signals` for the exhaustive list.\n",
|
|
17910
18031
|
"properties": {
|
|
17911
18032
|
"id": {
|
|
17912
18033
|
"type": "string",
|
|
@@ -17923,7 +18044,7 @@
|
|
|
17923
18044
|
"payload": {
|
|
17924
18045
|
"type": "object",
|
|
17925
18046
|
"additionalProperties": true,
|
|
17926
|
-
"description": "Entity IDs only
|
|
18047
|
+
"description": "Entity IDs only — deliverable resolvers load content at delivery time."
|
|
17927
18048
|
},
|
|
17928
18049
|
"dedup_key": {
|
|
17929
18050
|
"type": [
|
|
@@ -17991,7 +18112,7 @@
|
|
|
17991
18112
|
"items": {
|
|
17992
18113
|
"type": "string"
|
|
17993
18114
|
},
|
|
17994
|
-
"description": "Empty for slice-2 stub resolvers
|
|
18115
|
+
"description": "Empty for slice-2 stub resolvers — they appear in the list but never route."
|
|
17995
18116
|
},
|
|
17996
18117
|
"shape": {
|
|
17997
18118
|
"oneOf": [
|
|
@@ -18132,7 +18253,7 @@
|
|
|
18132
18253
|
},
|
|
18133
18254
|
"supports_kinds": {
|
|
18134
18255
|
"type": "array",
|
|
18135
|
-
"description": "Deliverable shape kinds this serializer accepts. Probed against a\nminimal synthetic shape per kind
|
|
18256
|
+
"description": "Deliverable shape kinds this serializer accepts. Probed against a\nminimal synthetic shape per kind — always reflects the current\nimplementation.\n",
|
|
18136
18257
|
"items": {
|
|
18137
18258
|
"type": "string",
|
|
18138
18259
|
"enum": [
|
|
@@ -18214,7 +18335,7 @@
|
|
|
18214
18335
|
"serialized",
|
|
18215
18336
|
"wire_preview"
|
|
18216
18337
|
],
|
|
18217
|
-
"description": "Output of `POST /v1/delivery/bindings/{id}/preview`. When the resolver\nsuccessfully loads a synthetic entity the full pipeline (`resolve
|
|
18338
|
+
"description": "Output of `POST /v1/delivery/bindings/{id}/preview`. When the resolver\nsuccessfully loads a synthetic entity the full pipeline (`resolve →\nprojectFieldMap → serialize`) runs and `sample_mode=\"real\"`. When the\nresolver throws (commonly `EntityMissingError` on a synthetic id) the\nservice falls back to `sample_mode=\"structural\"` and returns only the\nresolver's declared shape — `projected`, `serialized`, and\n`wire_preview` are `null` in that case.\n",
|
|
18218
18339
|
"properties": {
|
|
18219
18340
|
"available": {
|
|
18220
18341
|
"type": "boolean",
|
|
@@ -18229,7 +18350,7 @@
|
|
|
18229
18350
|
"real",
|
|
18230
18351
|
"structural"
|
|
18231
18352
|
],
|
|
18232
|
-
"description": "`real`
|
|
18353
|
+
"description": "`real` — the resolver loaded a synthetic entity and every pipeline\nstage ran. `structural` — the resolver threw (typically\n`entity_missing`) so only the declared shape is returned.\n"
|
|
18233
18354
|
},
|
|
18234
18355
|
"signal": {
|
|
18235
18356
|
"type": "object",
|
|
@@ -18389,7 +18510,7 @@
|
|
|
18389
18510
|
"additionalProperties": {
|
|
18390
18511
|
"type": "string"
|
|
18391
18512
|
},
|
|
18392
|
-
"description": "The `X-Talonic-*` headers that would ship on the wire. The\n`X-Talonic-Signature` header, when present, is rendered as\n`t=<preview>,v1=<preview>`
|
|
18513
|
+
"description": "The `X-Talonic-*` headers that would ship on the wire. The\n`X-Talonic-Signature` header, when present, is rendered as\n`t=<preview>,v1=<preview>` — the preview never computes a real\nHMAC so the signing secret is not exercised.\n"
|
|
18393
18514
|
}
|
|
18394
18515
|
}
|
|
18395
18516
|
},
|
|
@@ -18500,7 +18621,7 @@
|
|
|
18500
18621
|
}
|
|
18501
18622
|
},
|
|
18502
18623
|
"DestinationAuthConfig": {
|
|
18503
|
-
"description": "Destination credential payload. Write-only
|
|
18624
|
+
"description": "Destination credential payload. Write-only — server responses expose\nonly `has_auth_config: boolean`, never the credential values\nthemselves. The `type` field discriminates the concrete shape; valid\nvalues depend on the parent destination's connector `type` (see\n`/v1/delivery/catalog/connectors` for each connector's `auth_types`).\n",
|
|
18504
18625
|
"oneOf": [
|
|
18505
18626
|
{
|
|
18506
18627
|
"$ref": "#/components/schemas/AuthConfigPassword"
|
|
@@ -18748,7 +18869,7 @@
|
|
|
18748
18869
|
},
|
|
18749
18870
|
"operator": {
|
|
18750
18871
|
"type": "string",
|
|
18751
|
-
"description": "Operator identifier (free-form
|
|
18872
|
+
"description": "Operator identifier (free-form — e.g. `eq`, `contains`, `between`).",
|
|
18752
18873
|
"example": "between"
|
|
18753
18874
|
},
|
|
18754
18875
|
"value": {
|
|
@@ -21192,4 +21313,4 @@
|
|
|
21192
21313
|
}
|
|
21193
21314
|
}
|
|
21194
21315
|
}
|
|
21195
|
-
}
|
|
21316
|
+
}
|