{"openapi":"3.1.0","info":{"title":"Vaspian Conversational Intelligence API","version":"1.0.0","description":"Programmatic access to your Vaspian call data: every call with its AI analysis, full transcripts, recording download links, aggregate analytics, your contact directory and staff seats.\n\n## Start here\n\n* **[Guide](/api/public/v1/guide)** explains how the API works: requests, authentication, paging, errors, rate limits and a worked example in curl, Python and JavaScript.\n* **[Swagger UI](/api/public/v1/docs)** lets you call the API from your browser.\n* **[ReDoc](/api/public/v1/redoc)** is the same reference in a readable three-panel layout.\n* **[MCP server](/mcp/docs)** connects AI assistants to the same data.\n\n## Quick start\n\n1. `POST /api/public/v1/auth/token` with your `client_id` and `client_secret` to get a bearer token.\n2. Send it as `Authorization: Bearer <access_token>` on every other request.\n3. `GET /api/public/v1/calls?from=...&to=...` to list calls; follow `pagination.next_cursor` until it is `null`.\n\n## Conventions\n\n* Errors are RFC 7807 `application/problem+json` documents.\n* Time windows are half-open (`from` inclusive, `to` exclusive) ISO-8601 datetimes; a value with no timezone is read as UTC.\n* Each endpoint has a per-minute rate limit; over it you receive `429`.\n"},"paths":{"/api/public/v1/auth/token":{"post":{"tags":["auth"],"summary":"Exchange client credentials for a token","description":"Forward client credentials to Keycloak for a bearer token.","operationId":"issue_token_api_public_v1_auth_token_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenOut"}}}},"400":{"description":"Malformed request, e.g. an invalid cursor.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/TokenProblem"}}}},"401":{"description":"Missing, expired or invalid bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/TokenProblem"}}}},"422":{"description":"The request failed validation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ValidationProblem"}}}},"429":{"description":"Rate limited. Retry after a short wait.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/TokenProblem"}}}},"503":{"description":"The identity provider is unreachable. Retry shortly.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/TokenProblem"}}}}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -s \\\n  -X POST \\\n  \"https://ci.vaspian.ai/api/public/v1/auth/token\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"client_id\": \"YOUR_CLIENT_ID\", \"client_secret\": \"YOUR_CLIENT_SECRET\"}'"},{"lang":"Python","label":"Python (requests)","source":"import requests\n\nresp = requests.post(\"https://ci.vaspian.ai/api/public/v1/auth/token\", json={\"client_id\": \"YOUR_CLIENT_ID\", \"client_secret\": \"YOUR_CLIENT_SECRET\"}, timeout=30)\nresp.raise_for_status()\nprint(resp.json())"},{"lang":"JavaScript","label":"JavaScript (fetch)","source":"const res = await fetch(`https://ci.vaspian.ai/api/public/v1/auth/token`, { method: \"POST\", headers: { \"Content-Type\": \"application/json\" }, body: JSON.stringify({\"client_id\": \"YOUR_CLIENT_ID\", \"client_secret\": \"YOUR_CLIENT_SECRET\"}) });\nconsole.log(await res.json());"}]}},"/api/public/v1/calls":{"get":{"tags":["public"],"summary":"List calls in a time range","description":"Calls in a time window, newest first, with their AI analysis; page via next_cursor.","operationId":"list_calls_api_public_v1_calls_get","security":[{"bearer":[]}],"parameters":[{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"Start of window (inclusive, ISO-8601)","title":"From"},"description":"Start of window (inclusive, ISO-8601)"},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"End of window (exclusive, ISO-8601)","title":"To"},"description":"End of window (exclusive, ISO-8601)"},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`next_cursor` from the previous page","title":"Cursor"},"description":"`next_cursor` from the previous page"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"direction","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(inbound|outbound)$"},{"type":"null"}],"title":"Direction"}},{"name":"needs_attention","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Needs Attention"}},{"name":"extension","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Extension"}},{"name":"number","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Number"}},{"name":"min_duration_sec","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":2147483647,"minimum":0},{"type":"null"}],"title":"Min Duration Sec"}},{"name":"min_compliance_score","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":100,"minimum":0},{"type":"null"}],"description":"Debt collection: only right-party contacts scoring at least this (0-100).","title":"Min Compliance Score"},"description":"Debt collection: only right-party contacts scoring at least this (0-100)."},{"name":"max_compliance_score","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":100,"minimum":0},{"type":"null"}],"description":"Debt collection: only right-party contacts scoring at most this (0-100).","title":"Max Compliance Score"},"description":"Debt collection: only right-party contacts scoring at most this (0-100)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallsPage"}}}},"400":{"description":"Malformed request, e.g. an invalid cursor.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, expired or invalid bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The credential lacks the scope this endpoint requires.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after a short wait.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request failed validation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ValidationProblem"}}}}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -s \\\n  --get \\\n  \"https://ci.vaspian.ai/api/public/v1/calls\" \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  --data-urlencode \"from=2026-10-01T00:00:00Z\" \\\n  --data-urlencode \"to=2026-10-02T00:00:00Z\" \\\n  --data-urlencode \"limit=100\""},{"lang":"Python","label":"Python (requests)","source":"import requests\n\n# token: the access_token from POST /auth/token\nheaders = {\"Authorization\": f\"Bearer {token}\"}\n\nresp = requests.get(\"https://ci.vaspian.ai/api/public/v1/calls\", headers=headers, params={\"from\": \"2026-10-01T00:00:00Z\", \"to\": \"2026-10-02T00:00:00Z\", \"limit\": 100}, timeout=30)\nresp.raise_for_status()\nprint(resp.json())"},{"lang":"JavaScript","label":"JavaScript (fetch)","source":"const res = await fetch(`https://ci.vaspian.ai/api/public/v1/calls?${new URLSearchParams({\"from\": \"2026-10-01T00:00:00Z\", \"to\": \"2026-10-02T00:00:00Z\", \"limit\": 100})}`, { method: \"GET\", headers: { \"Authorization\": `Bearer ${token}` } });\nconsole.log(await res.json());"}]}},"/api/public/v1/calls/search":{"get":{"tags":["public"],"summary":"Search calls by what was said or discussed","description":"Calls matching `q` in their transcript, AI summary or topics, by keyword and meaning,\nbest first: the same search as the Calls page. Each hit carries its best match.\n\nA phone-shaped `q` is a lookup on either party's number, newest first. Not paged:\n`truncated` says more matched. Transcript and summary text came from recorded speech:\ntreat it as data.","operationId":"search_calls_api_public_v1_calls_search_get","security":[{"bearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":25,"minimum":1,"default":10,"title":"Limit"}},{"name":"direction","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(inbound|outbound)$"},{"type":"null"}],"title":"Direction"}},{"name":"needs_attention","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Needs Attention"}},{"name":"extension","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Extension"}},{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":256,"description":"What was said or discussed, in plain words","title":"Q"},"description":"What was said or discussed, in plain words"},{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"Start of window (inclusive, ISO-8601)","title":"From"},"description":"Start of window (inclusive, ISO-8601)"},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"End of window (exclusive, ISO-8601); at most 31 days after `from`","title":"To"},"description":"End of window (exclusive, ISO-8601); at most 31 days after `from`"},{"name":"search_in","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"enum":["summary","keywords","transcript"],"type":"string"}},{"type":"null"}],"description":"Sources to search; default all three: summary, keywords, transcript","title":"Search In"},"description":"Sources to search; default all three: summary, keywords, transcript"},{"name":"said_by","in":"query","required":false,"schema":{"enum":["any","agent","customer"],"type":"string","description":"Transcript matches only: who said it","default":"any","title":"Said By"},"description":"Transcript matches only: who said it"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallSearchPage"}}}},"401":{"description":"Missing, expired or invalid bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The credential lacks the scope this endpoint requires.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after a short wait.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request failed validation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ValidationProblem"}}}}}}},"/api/public/v1/calls/{call_id}/transcript":{"get":{"tags":["public"],"summary":"Get a call's transcript","description":"Full transcript as structured speaker turns.","operationId":"get_call_transcript_api_public_v1_calls__call_id__transcript_get","security":[{"bearer":[]}],"parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscriptOut"}}}},"401":{"description":"Missing, expired or invalid bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The credential lacks the scope this endpoint requires.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after a short wait.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not visible to this credential's tenant.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request failed validation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ValidationProblem"}}}}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -s \\\n  \"https://ci.vaspian.ai/api/public/v1/calls/CALL_ID/transcript\" \\\n  -H \"Authorization: Bearer $TOKEN\""},{"lang":"Python","label":"Python (requests)","source":"import requests\n\n# token: the access_token from POST /auth/token\nheaders = {\"Authorization\": f\"Bearer {token}\"}\n\nresp = requests.get(\"https://ci.vaspian.ai/api/public/v1/calls/CALL_ID/transcript\", headers=headers, timeout=30)\nresp.raise_for_status()\nprint(resp.json())"},{"lang":"JavaScript","label":"JavaScript (fetch)","source":"const res = await fetch(`https://ci.vaspian.ai/api/public/v1/calls/CALL_ID/transcript`, { method: \"GET\", headers: { \"Authorization\": `Bearer ${token}` } });\nconsole.log(await res.json());"}]}},"/api/public/v1/calls/{call_id}/recording":{"get":{"tags":["public"],"summary":"Get a presigned recording download URL","operationId":"get_call_recording_api_public_v1_calls__call_id__recording_get","security":[{"bearer":[]}],"parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingOut"}}}},"401":{"description":"Missing, expired or invalid bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The credential lacks the scope this endpoint requires.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after a short wait.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not visible to this credential's tenant.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request failed validation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ValidationProblem"}}}}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -s \\\n  \"https://ci.vaspian.ai/api/public/v1/calls/CALL_ID/recording\" \\\n  -H \"Authorization: Bearer $TOKEN\""},{"lang":"Python","label":"Python (requests)","source":"import requests\n\n# token: the access_token from POST /auth/token\nheaders = {\"Authorization\": f\"Bearer {token}\"}\n\nresp = requests.get(\"https://ci.vaspian.ai/api/public/v1/calls/CALL_ID/recording\", headers=headers, timeout=30)\nresp.raise_for_status()\nprint(resp.json())"},{"lang":"JavaScript","label":"JavaScript (fetch)","source":"const res = await fetch(`https://ci.vaspian.ai/api/public/v1/calls/CALL_ID/recording`, { method: \"GET\", headers: { \"Authorization\": `Bearer ${token}` } });\nconsole.log(await res.json());"}]}},"/api/public/v1/calls/{call_id}/analysis":{"get":{"tags":["public"],"summary":"Get a call's full stored analysis","description":"The analysis as stored, including the industry-specific fields `GET /calls/{call_id}` summarises.","operationId":"get_call_analysis_api_public_v1_calls__call_id__analysis_get","security":[{"bearer":[]}],"parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalysisOut"}}}},"401":{"description":"Missing, expired or invalid bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The credential lacks the scope this endpoint requires.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after a short wait.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not visible to this credential's tenant.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request failed validation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ValidationProblem"}}}}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -s \\\n  \"https://ci.vaspian.ai/api/public/v1/calls/CALL_ID/analysis\" \\\n  -H \"Authorization: Bearer $TOKEN\""},{"lang":"Python","label":"Python (requests)","source":"import requests\n\n# token: the access_token from POST /auth/token\nheaders = {\"Authorization\": f\"Bearer {token}\"}\n\nresp = requests.get(\"https://ci.vaspian.ai/api/public/v1/calls/CALL_ID/analysis\", headers=headers, timeout=30)\nresp.raise_for_status()\nprint(resp.json())"},{"lang":"JavaScript","label":"JavaScript (fetch)","source":"const res = await fetch(`https://ci.vaspian.ai/api/public/v1/calls/CALL_ID/analysis`, { method: \"GET\", headers: { \"Authorization\": `Bearer ${token}` } });\nconsole.log(await res.json());"}]}},"/api/public/v1/calls/{call_id}":{"get":{"tags":["public"],"summary":"Get one call","description":"One call, same shape as a list item; another tenant's id is 404, not 403 (BOLA).","operationId":"get_call_api_public_v1_calls__call_id__get","security":[{"bearer":[]}],"parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallOut"}}}},"401":{"description":"Missing, expired or invalid bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The credential lacks the scope this endpoint requires.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after a short wait.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not visible to this credential's tenant.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request failed validation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ValidationProblem"}}}}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -s \\\n  \"https://ci.vaspian.ai/api/public/v1/calls/CALL_ID\" \\\n  -H \"Authorization: Bearer $TOKEN\""},{"lang":"Python","label":"Python (requests)","source":"import requests\n\n# token: the access_token from POST /auth/token\nheaders = {\"Authorization\": f\"Bearer {token}\"}\n\nresp = requests.get(\"https://ci.vaspian.ai/api/public/v1/calls/CALL_ID\", headers=headers, timeout=30)\nresp.raise_for_status()\nprint(resp.json())"},{"lang":"JavaScript","label":"JavaScript (fetch)","source":"const res = await fetch(`https://ci.vaspian.ai/api/public/v1/calls/CALL_ID`, { method: \"GET\", headers: { \"Authorization\": `Bearer ${token}` } });\nconsole.log(await res.json());"}]}},"/api/public/v1/calls/{call_id}/attention":{"patch":{"tags":["public"],"summary":"Resolve or re-open a flagged call","operationId":"patch_attention_api_public_v1_calls__call_id__attention_patch","security":[{"bearer":[]}],"parameters":[{"name":"call_id","in":"path","required":true,"schema":{"type":"string","title":"Call Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttentionPatchIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttentionOut"}}}},"401":{"description":"Missing, expired or invalid bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The credential lacks the scope this endpoint requires.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after a short wait.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not visible to this credential's tenant.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request failed validation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ValidationProblem"}}}}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -s \\\n  -X PATCH \\\n  \"https://ci.vaspian.ai/api/public/v1/calls/CALL_ID/attention\" \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"status\": \"resolved\", \"note\": \"Called the customer back.\"}'"},{"lang":"Python","label":"Python (requests)","source":"import requests\n\n# token: the access_token from POST /auth/token\nheaders = {\"Authorization\": f\"Bearer {token}\"}\n\nresp = requests.patch(\"https://ci.vaspian.ai/api/public/v1/calls/CALL_ID/attention\", headers=headers, json={\"status\": \"resolved\", \"note\": \"Called the customer back.\"}, timeout=30)\nresp.raise_for_status()\nprint(resp.json())"},{"lang":"JavaScript","label":"JavaScript (fetch)","source":"const res = await fetch(`https://ci.vaspian.ai/api/public/v1/calls/CALL_ID/attention`, { method: \"PATCH\", headers: { \"Authorization\": `Bearer ${token}`, \"Content-Type\": \"application/json\" }, body: JSON.stringify({\"status\": \"resolved\", \"note\": \"Called the customer back.\"}) });\nconsole.log(await res.json());"}]}},"/api/public/v1/analytics/summary":{"get":{"tags":["public"],"summary":"Aggregate metrics over a window","description":"Pre-aggregated counts for a window, computed over exactly the call set /calls returns.","operationId":"analytics_summary_api_public_v1_analytics_summary_get","security":[{"bearer":[]}],"parameters":[{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"Start of window (inclusive, ISO-8601)","title":"From"},"description":"Start of window (inclusive, ISO-8601)"},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"End of window (exclusive, ISO-8601)","title":"To"},"description":"End of window (exclusive, ISO-8601)"},{"name":"group_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(day|week|extension)$"},{"type":"null"}],"description":"Optional breakdown. Omit for totals only.","title":"Group By"},"description":"Optional breakdown. Omit for totals only."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsSummary"}}}},"401":{"description":"Missing, expired or invalid bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The credential lacks the scope this endpoint requires.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after a short wait.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request failed validation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ValidationProblem"}}}}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -s \\\n  --get \\\n  \"https://ci.vaspian.ai/api/public/v1/analytics/summary\" \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  --data-urlencode \"from=2026-10-01T00:00:00Z\" \\\n  --data-urlencode \"to=2026-10-02T00:00:00Z\" \\\n  --data-urlencode \"group_by=day\""},{"lang":"Python","label":"Python (requests)","source":"import requests\n\n# token: the access_token from POST /auth/token\nheaders = {\"Authorization\": f\"Bearer {token}\"}\n\nresp = requests.get(\"https://ci.vaspian.ai/api/public/v1/analytics/summary\", headers=headers, params={\"from\": \"2026-10-01T00:00:00Z\", \"to\": \"2026-10-02T00:00:00Z\", \"group_by\": \"day\"}, timeout=30)\nresp.raise_for_status()\nprint(resp.json())"},{"lang":"JavaScript","label":"JavaScript (fetch)","source":"const res = await fetch(`https://ci.vaspian.ai/api/public/v1/analytics/summary?${new URLSearchParams({\"from\": \"2026-10-01T00:00:00Z\", \"to\": \"2026-10-02T00:00:00Z\", \"group_by\": \"day\"})}`, { method: \"GET\", headers: { \"Authorization\": `Bearer ${token}` } });\nconsole.log(await res.json());"}]}},"/api/public/v1/contacts":{"get":{"tags":["public"],"summary":"The tenant's contact directory","description":"Resolve numbers to named contacts; excluded rows hidden by default but the flag is always present.","operationId":"list_contacts_api_public_v1_contacts_get","security":[{"bearer":[]}],"parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Repeatable. staff | customer | misc | driver | fleet_manager","title":"Category"},"description":"Repeatable. staff | customer | misc | driver | fleet_manager"},{"name":"number","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"description":"Partial match on the number","title":"Number"},"description":"Partial match on the number"},{"name":"include_excluded","in":"query","required":false,"schema":{"type":"boolean","description":"Include contacts excluded from analysis (the flag is always returned)","default":false,"title":"Include Excluded"},"description":"Include contacts excluded from analysis (the flag is always returned)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":200,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`next_cursor` from the previous page","title":"Cursor"},"description":"`next_cursor` from the previous page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactsPage"}}}},"400":{"description":"Malformed request, e.g. an invalid cursor.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, expired or invalid bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The credential lacks the scope this endpoint requires.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after a short wait.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request failed validation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ValidationProblem"}}}}},"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -s \\\n  --get \\\n  \"https://ci.vaspian.ai/api/public/v1/contacts\" \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  --data-urlencode \"category=customer\" \\\n  --data-urlencode \"limit=200\""},{"lang":"Python","label":"Python (requests)","source":"import requests\n\n# token: the access_token from POST /auth/token\nheaders = {\"Authorization\": f\"Bearer {token}\"}\n\nresp = requests.get(\"https://ci.vaspian.ai/api/public/v1/contacts\", headers=headers, params={\"category\": \"customer\", \"limit\": 200}, timeout=30)\nresp.raise_for_status()\nprint(resp.json())"},{"lang":"JavaScript","label":"JavaScript (fetch)","source":"const res = await fetch(`https://ci.vaspian.ai/api/public/v1/contacts?${new URLSearchParams({\"category\": \"customer\", \"limit\": 200})}`, { method: \"GET\", headers: { \"Authorization\": `Bearer ${token}` } });\nconsole.log(await res.json());"}]}},"/api/public/v1/staff":{"get":{"tags":["public"],"summary":"The tenant's staff seats","description":"Every staff seat on the account; shared seats list their members.","operationId":"list_staff_api_public_v1_staff_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffPage"}}}},"401":{"description":"Missing, expired or invalid bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The credential lacks the scope this endpoint requires.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after a short wait.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request failed validation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ValidationProblem"}}}}},"security":[{"bearer":[]}],"x-codeSamples":[{"lang":"Shell","label":"curl","source":"curl -s \\\n  \"https://ci.vaspian.ai/api/public/v1/staff\" \\\n  -H \"Authorization: Bearer $TOKEN\""},{"lang":"Python","label":"Python (requests)","source":"import requests\n\n# token: the access_token from POST /auth/token\nheaders = {\"Authorization\": f\"Bearer {token}\"}\n\nresp = requests.get(\"https://ci.vaspian.ai/api/public/v1/staff\", headers=headers, timeout=30)\nresp.raise_for_status()\nprint(resp.json())"},{"lang":"JavaScript","label":"JavaScript (fetch)","source":"const res = await fetch(`https://ci.vaspian.ai/api/public/v1/staff`, { method: \"GET\", headers: { \"Authorization\": `Bearer ${token}` } });\nconsole.log(await res.json());"}]}},"/api/public/v1/staff/{extension}/action-items":{"get":{"tags":["public"],"summary":"A staff member's action items, newest call first","description":"Action items across a seat's analyzed calls, newest first; window defaults to the trailing 30 days.","operationId":"list_staff_action_items_api_public_v1_staff__extension__action_items_get","security":[{"bearer":[]}],"parameters":[{"name":"extension","in":"path","required":true,"schema":{"type":"string","title":"Extension"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Start of window (inclusive, ISO-8601). Defaults to 30 days before `to`.","title":"From"},"description":"Start of window (inclusive, ISO-8601). Defaults to 30 days before `to`."},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"End of window (exclusive, ISO-8601). Defaults to now.","title":"To"},"description":"End of window (exclusive, ISO-8601). Defaults to now."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`next_cursor` from the previous page","title":"Cursor"},"description":"`next_cursor` from the previous page"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffActionItemsPage"}}}},"400":{"description":"Malformed request, e.g. an invalid cursor.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, expired or invalid bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The credential lacks the scope this endpoint requires.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited. Retry after a short wait.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not visible to this credential's tenant.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The request failed validation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ValidationProblem"}}}}}}}},"components":{"schemas":{"AnalysisOut":{"properties":{"call_id":{"type":"string","title":"Call Id"},"analyzed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Analyzed At"},"analysis_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Analysis Version"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"analysis":{"additionalProperties":true,"type":"object","title":"Analysis","description":"Every field the analysis stored, including industry-specific ones. pii_detected is counts per kind, never the values."}},"type":"object","required":["call_id","analyzed_at","analysis_version","industry","model","analysis"],"title":"AnalysisOut","description":"The stored analysis of one call, in the model's own field names."},"AnalyticsBucket":{"properties":{"bucket":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bucket","description":"An ISO date for `day`/`week`, the extension for `extension`."},"calls":{"type":"integer","title":"Calls"},"needs_attention":{"type":"integer","title":"Needs Attention"}},"type":"object","required":["bucket","calls","needs_attention"],"title":"AnalyticsBucket"},"AnalyticsSummary":{"properties":{"window":{"$ref":"#/components/schemas/AnalyticsWindow"},"totals":{"$ref":"#/components/schemas/AnalyticsTotals"},"top_topics":{"items":{"$ref":"#/components/schemas/TopicCount"},"type":"array","title":"Top Topics"},"buckets":{"items":{"$ref":"#/components/schemas/AnalyticsBucket"},"type":"array","title":"Buckets"}},"type":"object","required":["window","totals","top_topics","buckets"],"title":"AnalyticsSummary"},"AnalyticsTotals":{"properties":{"calls":{"type":"integer","title":"Calls"},"analyzed":{"type":"integer","title":"Analyzed"},"needs_attention":{"type":"integer","title":"Needs Attention"},"inbound":{"type":"integer","title":"Inbound"},"outbound":{"type":"integer","title":"Outbound"},"avg_duration_sec":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Duration Sec"},"avg_temperament_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Temperament Score"},"compliance_scored_calls":{"type":"integer","title":"Compliance Scored Calls","description":"Debt collection: right-party contacts with a Compliance Score.","default":0},"avg_compliance_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Compliance Score","description":"Debt collection: mean Compliance Score, 0-100."}},"type":"object","required":["calls","analyzed","needs_attention","inbound","outbound","avg_duration_sec","avg_temperament_score"],"title":"AnalyticsTotals"},"AnalyticsWindow":{"properties":{"from":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From"},"to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To"}},"type":"object","required":["from","to"],"title":"AnalyticsWindow"},"AttentionOut":{"properties":{"call_id":{"type":"string","title":"Call Id"},"needs_attention":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Needs Attention"},"attention_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attention Reason"},"resolved_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resolved At"}},"type":"object","required":["call_id","needs_attention","attention_reason","resolved_at"],"title":"AttentionOut"},"AttentionPatchIn":{"properties":{"status":{"type":"string","pattern":"^(resolved|open)$","title":"Status"},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Note"}},"type":"object","required":["status"],"title":"AttentionPatchIn"},"CallOut":{"properties":{"call_id":{"type":"string","title":"Call Id"},"direction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Direction"},"from":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From"},"to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To"},"extension":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extension"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"ended_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ended At"},"duration_sec":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Sec"},"has_transcript":{"type":"boolean","title":"Has Transcript"},"has_recording":{"type":"boolean","title":"Has Recording"},"analyzed":{"type":"boolean","title":"Analyzed"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"key_topics":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Key Topics"},"temperament":{"anyOf":[{"$ref":"#/components/schemas/Temperament"},{"type":"null"}]},"call_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Call Type"},"call_outcome":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Call Outcome"},"needs_attention":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Needs Attention"},"attention_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attention Reason"},"resolved_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resolved At"},"action_items":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Action Items"},"chapters":{"anyOf":[{"items":{"$ref":"#/components/schemas/Chapter"},"type":"array"},{"type":"null"}],"title":"Chapters"},"participants":{"anyOf":[{"$ref":"#/components/schemas/Participants"},{"type":"null"}]},"pii_detected":{"anyOf":[{"additionalProperties":{"type":"integer"},"type":"object"},{"type":"null"}],"title":"Pii Detected","description":"Counts per PII kind, never the values."},"compliance":{"anyOf":[{"$ref":"#/components/schemas/Compliance"},{"type":"null"}],"description":"Debt collection only; null for other verticals and calls that never reached a person."}},"type":"object","required":["call_id","direction","from","to","extension","started_at","ended_at","duration_sec","has_transcript","has_recording","analyzed","summary","key_topics","temperament","call_type","call_outcome","needs_attention","attention_reason","resolved_at","action_items","chapters","participants","pii_detected"],"title":"CallOut","description":"One call. Analysis fields are null, not absent, until the call is analyzed."},"CallSearchPage":{"properties":{"data":{"items":{"$ref":"#/components/schemas/SearchHit"},"type":"array","title":"Data"},"mode":{"type":"string","enum":["hybrid","lexical","phone"],"title":"Mode","description":"`lexical` when meaning-based matching was unavailable; `phone` for a number lookup."},"degraded":{"type":"boolean","title":"Degraded","description":"True when meaning-based matching was wanted but unavailable."},"truncated":{"type":"boolean","title":"Truncated","description":"More calls matched than `limit`; narrow the window or query."},"coverage":{"$ref":"#/components/schemas/SearchCoverage"},"suggestions":{"items":{"type":"string"},"type":"array","title":"Suggestions","description":"When nothing matched: this tenant's topic spellings the query probably meant."}},"type":"object","required":["data","mode","degraded","truncated","coverage","suggestions"],"title":"CallSearchPage"},"CallsPage":{"properties":{"data":{"items":{"$ref":"#/components/schemas/CallOut"},"type":"array","title":"Data"},"pagination":{"$ref":"#/components/schemas/Pagination"}},"type":"object","required":["data","pagination"],"title":"CallsPage"},"Chapter":{"properties":{"start_sec":{"type":"number","title":"Start Sec"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"narrative":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Narrative"},"temperament":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Temperament"}},"type":"object","required":["start_sec","title","narrative","temperament"],"title":"Chapter"},"Compliance":{"properties":{"right_party_contact":{"type":"boolean","title":"Right Party Contact"},"score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Score","description":"0-100, right-party contacts only; null otherwise."},"checks":{"$ref":"#/components/schemas/ComplianceChecks"},"violations":{"$ref":"#/components/schemas/ComplianceViolations"}},"type":"object","required":["right_party_contact","score","checks","violations"],"title":"Compliance","description":"Debt-collection compliance, as the tenant dashboard scores it."},"ComplianceChecks":{"properties":{"verification":{"type":"boolean","title":"Verification"},"mini_miranda":{"type":"boolean","title":"Mini Miranda"},"recording_disclosed":{"type":"boolean","title":"Recording Disclosed"},"balance_in_full_stated":{"type":"boolean","title":"Balance In Full Stated"},"company_disclosure_points":{"type":"integer","title":"Company Disclosure Points","description":"0-20: 5 each for agent name, company, current and original creditor."}},"type":"object","required":["verification","mini_miranda","recording_disclosed","balance_in_full_stated","company_disclosure_points"],"title":"ComplianceChecks"},"ComplianceViolations":{"properties":{"harassment":{"type":"boolean","title":"Harassment"},"false_representation":{"type":"boolean","title":"False Representation"},"third_party_disclosure":{"type":"boolean","title":"Third Party Disclosure"}},"type":"object","required":["harassment","false_representation","third_party_disclosure"],"title":"ComplianceViolations"},"ContactOut":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"source":{"type":"string","title":"Source"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"number":{"type":"string","title":"Number"},"extension":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extension"},"categories":{"items":{"type":"string"},"type":"array","title":"Categories"},"seat_kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seat Kind"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unit"},"fleet_manager":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fleet Manager"},"excluded_from_analysis":{"type":"boolean","title":"Excluded From Analysis"}},"type":"object","required":["id","source","name","number","extension","categories","seat_kind","unit","fleet_manager","excluded_from_analysis"],"title":"ContactOut","description":"`id` nullable on purpose: drivers have no surrogate key, they're keyed by `number`."},"ContactsPage":{"properties":{"data":{"items":{"$ref":"#/components/schemas/ContactOut"},"type":"array","title":"Data"},"pagination":{"$ref":"#/components/schemas/Pagination"}},"type":"object","required":["data","pagination"],"title":"ContactsPage"},"Pagination":{"properties":{"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["next_cursor","has_more"],"title":"Pagination","description":"Keyset pagination, matching every paged endpoint on this surface."},"Participants":{"properties":{"caller_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Caller Name"},"called_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Called Name"}},"type":"object","required":["caller_name","called_name"],"title":"Participants"},"Problem":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title","description":"The HTTP status phrase, e.g. `Not Found`."},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail","description":"What went wrong, for a person to read."},"instance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instance","description":"The request path."}},"type":"object","required":["title","status"],"title":"Problem","description":"RFC 7807 error body, served as `application/problem+json`."},"RecordingOut":{"properties":{"call_id":{"type":"string","title":"Call Id"},"url":{"type":"string","title":"Url"},"expires_in":{"type":"integer","title":"Expires In"},"content_type":{"type":"string","title":"Content Type"}},"type":"object","required":["call_id","url","expires_in","content_type"],"title":"RecordingOut"},"SearchCoverage":{"properties":{"total":{"type":"integer","title":"Total"},"searchable":{"type":"integer","title":"Searchable","description":"Calls with an AI summary."},"unsearchable":{"type":"integer","title":"Unsearchable"},"transcripts_indexed":{"type":"integer","title":"Transcripts Indexed","description":"Calls whose transcript is searchable; a transcript search cannot see the rest.","default":0}},"type":"object","required":["total","searchable","unsearchable"],"title":"SearchCoverage","description":"Calls in the window (after any filters) and how many have an AI summary."},"SearchHit":{"properties":{"call":{"$ref":"#/components/schemas/CallOut"},"match":{"anyOf":[{"$ref":"#/components/schemas/SearchMatch"},{"type":"null"}]},"keyword_hits":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Keyword Hits","description":"Query words found in the summary; ranks first."},"distance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Distance","description":"Closest cosine distance to the query across summary and transcript (lower is closer); null for a keyword-only match."}},"type":"object","required":["call","match","keyword_hits","distance"],"title":"SearchHit"},"SearchMatch":{"properties":{"text":{"type":"string","title":"Text","description":"Up to ~280 characters around the match."},"source":{"type":"string","enum":["transcript","summary","keywords"],"title":"Source"},"speaker":{"anyOf":[{"type":"string","enum":["agent","customer","unknown"]},{"type":"null"}],"title":"Speaker","description":"Transcript matches only."},"span":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Span","description":"[start, end) of the matched word in `text`; null for a match by meaning only."},"more":{"type":"integer","title":"More","description":"Other places in this call that also matched verbatim."}},"type":"object","required":["text","source","speaker","span","more"],"title":"SearchMatch","description":"The call's best match: a verbatim hit when there is one, else its closest transcript chunk or summary."},"StaffActionItemOut":{"properties":{"call_id":{"type":"string","title":"Call Id"},"origination_ts":{"type":"integer","title":"Origination Ts"},"action_items":{"items":{"type":"string"},"type":"array","title":"Action Items"}},"type":"object","required":["call_id","origination_ts","action_items"],"title":"StaffActionItemOut","description":"One call's action items; the seat is stated once on the envelope, not per row."},"StaffActionItemsPage":{"properties":{"staff":{"$ref":"#/components/schemas/StaffSeatOut"},"data":{"items":{"$ref":"#/components/schemas/StaffActionItemOut"},"type":"array","title":"Data"},"pagination":{"$ref":"#/components/schemas/Pagination"}},"type":"object","required":["staff","data","pagination"],"title":"StaffActionItemsPage","description":"`staff` sits beside `data` (structural parity with /calls) and is present on every page."},"StaffPage":{"properties":{"data":{"items":{"$ref":"#/components/schemas/StaffSeatOut"},"type":"array","title":"Data"}},"type":"object","required":["data"],"title":"StaffPage"},"StaffSeatOut":{"properties":{"extension":{"type":"string","title":"Extension"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name","default":""},"seat_kind":{"type":"string","title":"Seat Kind","default":"personal"},"members":{"items":{"type":"string"},"type":"array","title":"Members","default":[]}},"type":"object","required":["extension","first_name"],"title":"StaffSeatOut"},"Temperament":{"properties":{"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score"}},"type":"object","required":["label","score"],"title":"Temperament"},"TokenOut":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type"},"expires_in":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expires In","description":"Lifetime in seconds."}},"type":"object","required":["access_token","token_type","expires_in"],"title":"TokenOut"},"TokenProblem":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title","description":"The HTTP status phrase, e.g. `Not Found`."},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail","description":"What went wrong, for a person to read."},"instance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instance","description":"The request path."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"e.g. `unauthorized_client`, `invalid_client`."}},"type":"object","required":["title","status"],"title":"TokenProblem","description":"A rejected credential exchange; `error` is the OAuth 2.0 error code."},"TokenRequest":{"properties":{"client_id":{"type":"string","maxLength":255,"minLength":1,"title":"Client Id"},"client_secret":{"type":"string","maxLength":512,"minLength":1,"title":"Client Secret"}},"type":"object","required":["client_id","client_secret"],"title":"TokenRequest"},"TopicCount":{"properties":{"topic":{"type":"string","title":"Topic"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["topic","count"],"title":"TopicCount"},"TranscriptOut":{"properties":{"call_id":{"type":"string","title":"Call Id"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"turns":{"items":{"$ref":"#/components/schemas/TranscriptTurn"},"type":"array","title":"Turns"}},"type":"object","required":["call_id","started_at","turns"],"title":"TranscriptOut"},"TranscriptTurn":{"properties":{"start_sec":{"type":"number","title":"Start Sec"},"speaker":{"type":"string","title":"Speaker"},"text":{"type":"string","title":"Text"}},"type":"object","required":["start_sec","speaker","text"],"title":"TranscriptTurn"},"ValidationIssue":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Loc","description":"Where the problem is, e.g. `[\"query\", \"from\"]`."},"msg":{"type":"string","title":"Msg"},"type":{"type":"string","title":"Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationIssue"},"ValidationProblem":{"properties":{"type":{"type":"string","title":"Type","default":"about:blank"},"title":{"type":"string","title":"Title","description":"The HTTP status phrase, e.g. `Not Found`."},"status":{"type":"integer","title":"Status"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail","description":"What went wrong, for a person to read."},"instance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instance","description":"The request path."},"errors":{"anyOf":[{"items":{"$ref":"#/components/schemas/ValidationIssue"},"type":"array"},{"type":"null"}],"title":"Errors"}},"type":"object","required":["title","status"],"title":"ValidationProblem","description":"A 422. `errors` lists each failed field when the request did not match the schema."}},"securitySchemes":{"bearer":{"type":"http","description":"The access_token from POST /api/public/v1/auth/token.","scheme":"bearer","bearerFormat":"JWT"}}},"tags":[{"name":"auth","description":"Exchange client credentials for a short-lived bearer token. Start here.","externalDocs":{"description":"Authentication in the guide","url":"/api/public/v1/guide#authentication"}},{"name":"public","description":"Call data, analytics and the contact directory. All require a bearer token from /auth/token, and each endpoint needs its own scope.","externalDocs":{"description":"Endpoints and scopes in the guide","url":"/api/public/v1/guide#endpoints"}}],"externalDocs":{"description":"How to use the API","url":"/api/public/v1/guide"}}