{"openapi":"3.1.0","info":{"title":"LiveHub AI Agents - REST API","description":"The REST API of the LiveHub **AI Agents** framework covers the complete lifecycle:\nconfiguration, monitoring and troubleshooting.\n\n### Authentication\n\nEvery operation requires a LiveHub access token, presented as `Authorization: Bearer <access_token>`.\nSelect **Authorize** below and use either method:\n\n- **HTTPBearer** - supply a token already obtained.\n- **OAuth2ClientCredentials** - supply an API client's **Client Id** and **Client Secret**; this\n  page then obtains a token and applies it to every request issued from here.\n\nBoth methods require a LiveHub **API client**, created under Access control (IAM). The API client\nmust be assigned to the user group covering the operations it is intended to perform. An\nintegration obtains a token from the same credentials:\n\n```\nPOST https://livehub.audiocodes.io/oauth/token\nContent-Type: application/x-www-form-urlencoded\n\ngrant_type=client_credentials&client_id=<client_id>&client_secret=<client_secret>\n```\n\nA token remains valid for one hour and must be renewed before it expires.\n\n### Common to every endpoint\n\n- **A token is scoped to a single account**, and every request applies to that account; the\naccount is therefore not named in the URL. To work with several accounts, create an API client\nin each and use the token corresponding to the intended account.\n\n- The **role** an operation requires follows its HTTP method: `READ` for GET, `CREATE` for POST,\n`UPDATE` for PUT and `DELETE` for DELETE, each within the `LIVEHUB/AIFRAMEWORK/` namespace (a GET\ntherefore requires `LIVEHUB/AIFRAMEWORK/READ`), except where the operation's own description\nstates otherwise.\n\n- The **entity listings** - agents, flows, documents, tools, models, post-call analyses, test\nsuites and conversations - accept `filter`, `sort`, `limit` and `page`, and return\n`{\"<entities>\": [...], \"total_count\": N}`. `total_count` reflects the entire filtered set\nrather than the page returned, `page` is 1-based, and the ordering applies across all pages.\nA sub-resource listing - the nodes of a flow, the prompt history of an agent - accepts none of\nthe four, as each such operation states.\n\n- **Errors** carry a `detail` string: `401` for a missing, malformed or expired token; `403` where\nthe token lacks the role the operation requires; `404` where the entity named in the URL does not\nexist in this account; `400` for every other rejection, including an invalid payload, a duplicate\nname and a reference to a non-existent entity. Each operation documents the codes it may return,\ntogether with `422` - whose `detail` is a list of per-field objects rather than a string - for a\nparameter that fails schema validation before the operation is invoked. A write may also return\n`502`, indicating that a store on which this deployment depends was unreachable and that\n**nothing was saved**.\n","version":"1.0.0"},"paths":{"/api/v1/agents":{"post":{"tags":["Agents"],"summary":"Create an agent","description":"Create an LLM-driven agent: a prompt, a model, and the tools, documents, sub-agents and\npost-call analyses it may reach for.\n\n`name`, `llm` and `prompt` are the required fields. `llm` is a model name - one this\ndeployment provides, or one of the account's own from `GET /models`.\n\n**References are names.** `tools_config`, `documents`, `agents`, `flows` and\n`post_call_analysis` name what they point at, and a name that matches nothing is dropped\nsilently rather than rejected - so create what an agent depends on before the agent.\n\n**`advanced_config` is where every setting with no field of its own lives.**\n\nRejected with a **400**: a duplicate name, and the account's agent cap.","operationId":"create_agent","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentModel"},"examples":{"minimal":{"summary":"The smallest agent that runs","description":"A name, a model and a prompt. Everything else takes its default, which is enough for a single agent answering from the prompt alone.","value":{"name":"order-status","description":"Answers questions about order status","llm":"gpt-4o","prompt":"You are a support agent for an online shop. Answer questions about orders briefly, and say you do not know rather than guessing.\n\nThe caller is phoning from {caller}."}},"with_tools_and_documents":{"summary":"An agent with a tool, a document and a greeting","description":"References are **names**: `tools_config` names a custom tool through `tool_id` and the platform builtins directly, and `documents` names documents. All of them have to exist already - a name that matches nothing is dropped silently.","value":{"name":"order-status","description":"Answers questions about order status","llm":"gpt-4o","prompt":"You are a support agent for an online shop.\n\nUse `lookup-order` to find an order, and the documents for anything about delivery times or returns. Transfer to a human if the caller asks.\n\nKeep answers short - they are read aloud.","welcome":{"type":"static","message":"Thanks for calling. How can I help?"},"tools_config":[{"tool":"custom","tool_id":"lookup-order"},{"tool":"transfer_call"},{"tool":"end_call"}],"documents":["delivery-and-returns"],"variables_str":"shop_name = Example Shop","max_turns":30}},"multi_agent":{"summary":"A main agent handing off to two specialists","description":"The multi-agent shape: `agents` names the sub-agents (which must exist), and `pass_question` is what lets this one hand a question over. `orchestration_mode` decides whether the sub-agent answers the caller directly (`delegate`) or reports back to this agent (`consult`).","value":{"name":"support-front-desk","description":"Routes callers to the right specialist","llm":"gpt-4o","prompt":"You are the front desk of a support line. Route each question:\n\n- orders, delivery, returns -> pass to `order-status`\n- billing and invoices -> pass to `billing`\n- anything else -> answer briefly yourself, or say you do not know.\n\nKeep answers short - they are read aloud.","welcome":{"type":"static","message":"Support desk, how can I help?"},"agents":["order-status","billing"],"orchestration_mode":"consult","tools_config":[{"tool":"pass_question"},{"tool":"end_call"}]}}}}}},"responses":{"201":{"description":"The created agent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Agents"],"summary":"List agents","description":"List all agents.\n\nReturns a flat list that carries the multi-agent hierarchy in entry's\nfields rather than by nesting.\n\n**The order is meaningful.** Each top-level agent is followed by its sub-agents,\nthen theirs, breadth-first; `depth` says how far down a row sits, `parent_id` / `parent_name`\nname its direct parent (absent on a top-level agent) and `top_level_id` / `top_level_name` name\nthe group it belongs to. Sorting by `name` keeps that grouping; sorting by anything else\ndeliberately flattens it, because a global order and a hierarchy cannot both hold.\n\nRows are a projection for a list view: counts rather than the tools and documents themselves.\nRead one back with `GET /agents/{agent_id}` for the prompt and the configuration.","operationId":"get_agents","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"filter","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `name~support` or `(name~support,llm~gpt)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `name=support;billing`.\n\nThis collection can be filtered by `name`, `description`, `llm`.","examples":["name~support","name~support,llm~gpt","name=support;billing"],"title":"Filter"},"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `name~support` or `(name~support,llm~gpt)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `name=support;billing`.\n\nThis collection can be filtered by `name`, `description`, `llm`."},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `description`, `llm`, `tools_count`, `documents_count`, `agents_count`, `depth`.","examples":["-name"],"title":"Sort"},"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `description`, `llm`, `tools_count`, `documents_count`, `agents_count`, `depth`."},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum number of items to return. If not specified, all of them are returned.","examples":[50],"title":"Limit"},"description":"Maximum number of items to return. If not specified, all of them are returned."},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned.","examples":[1],"title":"Page"},"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned."}],"responses":{"200":{"description":"A page of agents, grouped by hierarchy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}":{"get":{"tags":["Agents"],"summary":"Get an agent","description":"Read one agent's full configuration.\n\n`tools_config`, `documents`, `agents`, `flows` and `post_call_analysis` all come back as names.\n\nSecrets in webhooks and tool configuration come back masked - the first three characters plus\n`*****`, with a `$<index>` suffix where a list holds several. Send a mask back unchanged and the\nstored secret is kept, so the agent round-trips without the caller ever holding a credential.","operationId":"get_agent","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}}],"responses":{"200":{"description":"The agent, with its conversation URLs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentDetail"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Agents"],"summary":"Update an agent","description":"Update an agent. Every field is optional - omit one and its stored value is kept.\n\n**`advanced_config` is the exception, and the one thing worth reading twice: sending it\nreplaces every advanced key at once.** Omit it and the stored advanced configuration is left\nalone; send it with two keys and the agent is left with those two. So a client that reads an\nagent, edits one advanced key and sends the whole object back is safe - one that sends a\nhand-built `advanced_config` is not.\n\nChanging `prompt` snapshots the new one into the agent's prompt history. The history holds\nthe last 100 versions.\n\n**Secrets.** Sending a masked value back is understood as \"unchanged\", which is what lets the\nwhole object round-trip; send a real value to replace one, or an empty string to clear it.\n\nLists replace rather than merge: `tools_config`, `documents`, `agents`, `flows` and\n`post_call_analysis` are each taken as the new whole, and all five name what they point at, as\non create.","operationId":"update_agent","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentUpdateModel"}}}},"responses":{"200":{"description":"The updated agent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Agents"],"summary":"Delete an agent","description":"Delete an agent and its prompt history.\n\nA top-level agent created from quickstart also deletes every sub-agent, document,\ntool and post call analysis created alongside it.\n\nTools, documents, post-call analyses and sub-agents the agent merely referenced are shared\nentities and stay.","operationId":"delete_agent","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}}],"responses":{"204":{"description":"No content"},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/clone":{"post":{"tags":["Agents"],"summary":"Clone an agent","description":"Copy an agent, prompt and configuration and all, under a new name and a new id.\n\nThe copy is named `clone <original>`, or `clone-1 <original>` and upwards where that is taken.\nIt takes no request body: everything comes from the source.\n\n**The copy is a sibling, not a child.** It references the same tools, documents and sub-agents\nas the original, and nothing references it - so a cloned agent is unreachable in a multi-agent\ntopology until some agent names it, or a conversation starts on it directly.","operationId":"clone_agent","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}}],"responses":{"201":{"description":"The new copy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/prompt-history":{"get":{"tags":["Agents"],"summary":"List an agent's prompt history","description":"List every prompt this agent has had, newest first.\n\nA version is snapshotted when the agent is created and again whenever an update changes\n`prompt`, so what is recorded is each prompt as it took effect: **normally the newest entry is\nthe agent's current prompt**, and the one to roll back to is the second. Two operations leave\nthat out of step, both deliberately - restoring an earlier version adds no entry of its own,\nand this history's own delete can remove the newest one - so compare against the agent's\n`prompt` rather than assuming. The last 100 are kept; older ones are dropped as new versions\narrive, and the whole history goes when the agent does.\n\nThe body is a bare array rather than the `{items, total_count}` envelope the other listings\nuse, and takes no `filter` / `sort` / `limit` / `page`.","operationId":"get_agent_prompt_history","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}}],"responses":{"200":{"description":"The agent's prompt versions, newest first","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PromptHistoryItem"},"title":"Response 200 Get Agent Prompt History"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/agents/{agent_id}/prompt-history/{prompt_id}":{"get":{"tags":["Agents"],"summary":"Get one prompt from the history","description":"Read one version of the agent's prompt from the history.\n\nThe listing carries every entry's whole text already, so this is for fetching a single version\nby id - to diff it against the current prompt before restoring it, say. The entry has to belong\nto this agent: one from another agent's history is a **404**, as is an id the agent no longer\nholds.","operationId":"get_prompt_from_history","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}},{"name":"prompt_id","in":"path","required":true,"schema":{"type":"string","title":"Prompt Id"}}],"responses":{"200":{"description":"The prompt version","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromptHistoryItem"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Agents"],"summary":"Restore a prompt from the history","description":"Make one of the agent's earlier prompts the current one again.\n\nThe prompt has to be in this agent's own history - one belonging to another agent is a **404**,\nand so is an entry the history no longer holds. Nothing but `prompt` changes.\n\n**The restore is not itself snapshotted**, because the text being replaced is already in the\nhistory: restoring version 3 over version 7 leaves 7 in the history, so the move is reversible\nthe same way. Restoring the prompt the agent already has is accepted and changes nothing.","operationId":"change_active_prompt","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}},{"name":"prompt_id","in":"path","required":true,"schema":{"type":"string","title":"Prompt Id"}}],"responses":{"200":{"description":"The agent, with the restored prompt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Agents"],"summary":"Delete a prompt from the history","description":"Drop one entry from an agent's prompt history.\n\nOnly the history entry goes - the agent's current prompt is untouched, whether or not this was\nthe version it replaced. There is no undo: the text is not recoverable afterwards.","operationId":"delete_prompt_from_history","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","title":"Agent Id"}},{"name":"prompt_id","in":"path","required":true,"schema":{"type":"string","title":"Prompt Id"}}],"responses":{"204":{"description":"No content"},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backups/create":{"post":{"tags":["Backup"],"summary":"Create a backup","description":"Download a ZIP holding the agents or flows you name and, by default, everything they depend on.\n\n**Dependencies are resolved for you.** Name an agent and the archive also carries the tools,\ndocuments, models and post-call analyses it references, so restoring it elsewhere gives a working\nagent rather than one full of dangling names. `agents` and `flows` may be given by id or by name.\n\nSet `resolve_dependencies` to `false` to take control instead: the `tools`, `documents`, `models`\nand `post_call_analysis` lists are then honoured exactly as sent and nothing is added. That is the\nsecond half of the review flow - call `/create/preview` first, adjust the set, then export it.\nThose four lists are **ignored** while `resolve_dependencies` is true.\n\n**Unknown names are dropped rather than reported.** A **400** comes back only when *nothing* you named\nresolves - a list mixing one real agent with one typo exports the real one and says nothing about\nthe typo, and with `resolve_dependencies` off there is no check at all. Call `/create/preview`\nfirst if that matters to you. Asking for a backup with no agent or flow to anchor it is also a\n**400**: the archive is built from the selection, not from the whole account.","operationId":"backup_create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupCreate"}}},"required":true},"responses":{"200":{"description":"A ZIP archive of the selected entities","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}]}},"/api/v1/backups/create/preview":{"post":{"tags":["Backup"],"summary":"Preview a backup","description":"Find out what a backup of these agents and flows would carry, before downloading it. **Writes nothing.**\n\nThe answer is every entity in the account grouped by type, each flagged with whether the resolved\nbackup would include it and whether it was asked for directly - so a client can show the full\npicture and let the user drop a dependency or add something the resolver missed.\n\nThat adjusted set then goes to `/create` with `resolve_dependencies` set to `false`. Calling\n`/create` on its own skips this and exports with dependencies resolved, which is what a client that\ndoes not need the review step should do.","operationId":"backup_create_preview","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupExportPreview"}}},"required":true},"responses":{"200":{"description":"Every account entity, flagged for what the backup would include","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupPreview"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}]}},"/api/v1/backups/restore":{"post":{"tags":["Backup"],"summary":"Restore a backup","description":"Upload a backup archive and write its contents into this account.\n\n`multipart/form-data` with a single `file` part, which has to be the `.zip` a backup produced.\n\n**An entity whose name already exists is overwritten**, not duplicated - so a restore is also how an\narchive is re-applied after an edit. Call `/restore/preview` first to see which ones those are;\nthere is no dry-run flag here and no undo.\n\n**Documents come back empty and fill in afterwards.** Each restored document is marked `updating`\nand re-parsed in the background, because the archive carries the definition rather than the parsed\nchunks - so a restored agent can answer nothing from its documents until those parses finish. Watch\nthe listing's `processing` flag.\n\nA file that is not a zip, or one this API cannot read, is a **400**.","operationId":"backup_restore","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_backup_restore"}}},"required":true},"responses":{"200":{"description":"Ids of everything that was written, by type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupRestored"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}]}},"/api/v1/backups/restore/preview":{"post":{"tags":["Backup"],"summary":"Preview a restore","description":"Find out what restoring this archive would do, before doing it. **Writes nothing.**\n\nTakes the same `.zip` as `/restore`, in the same `multipart/form-data` shape, and reports the\nentities it holds grouped by type, each flagged with whether it would be created or would\n**overwrite something that already exists**. That flag is the point: a restore is silent about\noverwriting, so this is the only warning a user gets.\n\nA broken archive fails here exactly as it would there, so this doubles as a check that the file is\nreadable at all.","operationId":"backup_restore_preview","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_backup_restore_preview"}}},"required":true},"responses":{"200":{"description":"What the archive would create, and what it would overwrite","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupPreview"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}]}},"/api/v1/conversations":{"get":{"tags":["Conversations"],"summary":"List conversations","description":"List conversations - calls, chats and agent-assist sessions alike, once they\nhave ended. A conversation still running is in `/live_conversations` instead.\n\nA row carries no transcript, only how long it was; read one back with `GET /conversations/{conversation_id}` for the\nmessages.\n\n**`agent` names the agent or flow that answered; `sub_agents` names the ones it handed the\ncall to.** `filter=sub_agents=<name>` is how you find the calls that reached a particular\nsub-agent in a multi-agent setup, and several at once as `filter=sub_agents=billing;refunds`.\nAn agent that both answers calls of its own and is a sub-agent elsewhere plays a different role\nfrom call to call; `any_agent=<name>` covers both at once, which no combination of `filter=`\nterms can, since those are combined with AND.\n\n**`type` says what kind of session it was** - `call`, `chat`, `agent-assist`, or `test`\nfor one a test suite drove. **A listing is real traffic by default**: the test runs are left out\nunless `test_logs=true` asks for them.\nFor the test runs on their own, `filter=type=test` - naming the field replaces the default's own\ncondition on it.\n\nThe returned results are paged and default to 100 rows, capped at 200; a `limit` outside\n1-200 falls back to the default rather than being rejected.","operationId":"get_conversations","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"filter","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `agent=support` or `(sub_agents=billing,start_time>=2026-01-01T00:00:00Z)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `sub_agents=billing;refunds`.\n\nThis collection can be filtered by `start_time`, `agent`, `sub_agents`, `type`.","examples":["agent=support","sub_agents=billing,start_time>=2026-01-01T00:00:00Z","sub_agents=billing;refunds"],"title":"Filter"},"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `agent=support` or `(sub_agents=billing,start_time>=2026-01-01T00:00:00Z)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `sub_agents=billing;refunds`.\n\nThis collection can be filtered by `start_time`, `agent`, `sub_agents`, `type`."},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"Field to sort by, prefixed with `-` for descending. If not specified, the newest come first. A field this collection cannot be sorted by falls back to that default rather than being rejected.\n\nThis collection can be sorted by `start_time`, `agent`, `type`.","examples":["-start_time"],"default":"-start_time","title":"Sort"},"description":"Field to sort by, prefixed with `-` for descending. If not specified, the newest come first. A field this collection cannot be sorted by falls back to that default rather than being rejected.\n\nThis collection can be sorted by `start_time`, `agent`, `type`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Maximum number of items to return, 1..200. Anything outside that range falls back to 100 rather than being rejected.","examples":[100],"default":100,"title":"Limit"},"description":"Maximum number of items to return, 1..200. Anything outside that range falls back to 100 rather than being rejected."},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned.","examples":[1],"title":"Page"},"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned."},{"name":"any_agent","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Keep only the conversations this agent or flow took part in, whether it answered the call or was handed it. Exact names, `;`-separated for a set. Use this rather than a `filter=` term when the same name can appear in either role - filter terms are combined with AND, so they cannot ask for either","examples":["billing"],"title":"Any Agent"},"description":"Keep only the conversations this agent or flow took part in, whether it answered the call or was handed it. Exact names, `;`-separated for a set. Use this rather than a `filter=` term when the same name can appear in either role - filter terms are combined with AND, so they cannot ask for either"},{"name":"test_logs","in":"query","required":false,"schema":{"type":"boolean","description":"Include the conversations driven by test runs as well. Off by default, so a listing is real traffic unless it asks for them","default":false,"title":"Test Logs"},"description":"Include the conversations driven by test runs as well. Off by default, so a listing is real traffic unless it asks for them"}],"responses":{"200":{"description":"A page of conversations, newest first","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/conversations/{conversation_id}":{"get":{"tags":["Conversations"],"summary":"Get a conversation","description":"Read one conversation in full: the messages, the tool calls, and the log the runtime kept while it\nran. `duration` is derived from the two timestamps as the response is built, so it is here and\nin the listing but never in a stored or exported record.\n\n**The literal `latest` is accepted** in place of an id and returns the account's most recent\nconversation, which is what makes this usable for a quick look after a test call.","operationId":"get_conversation","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"responses":{"200":{"description":"The conversation, with its full transcript","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationResponse"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Conversations"],"summary":"Delete a conversation","description":"Delete one conversation and its transcript.\n\nIts post-call analysis results are a separate record and survive - `GET /post_call_analysis_data` keeps\nreturning them, keyed by a conversation id that no longer resolves. Delete those too if the\nconversation is meant to leave no trace.\n\nUnlike the single read, this takes an id only; `latest` is not accepted here.","operationId":"delete_conversation","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"responses":{"204":{"description":"No content"},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/live_conversations":{"get":{"tags":["Live Conversations"],"summary":"List running conversations","description":"List every conversation happening right now.\n\n**Chats are left out by default.** A supervisor is usually looking for calls, and on a busy account\nchats would bury them - so ask for `chat` in `types` when you want them. An unknown type is a **400**\nrather than being ignored.\n\nThere is no paging, filtering or sorting: the set is small by nature and turns over in seconds.\nA conversation appears here within a second or two of starting, drops off the moment it ends,\nand then appears under `/conversations`.\n\nEach row carries the `conversation_id` every other operation here takes, the `type`, `caller` /\n`callee` (empty for chats), `app_call_id` when the platform assigned one, `setup_time`, the\n`agent` that answered and its `kind` (`agent` or `flow`), `current_agent` / `current_node` for\nwhere a multi-agent topology or a flow stands right now, `status`, and `realtime` - `true` for\na speech-to-speech agent, which changes what the commands below may do.\n\n**Logs stream over a WebSocket** at `/api/v1/live_conversations/{conversation_id}/logs`,\nauthenticated by a `token` query parameter rather than a header, which a browser cannot set on\na handshake: get one from `POST /api/v1/websocket_token`. The connection is read-only and\ncloses when the conversation ends; a schema cannot describe a WebSocket, so the frame format\nis in the documentation's REST API section.","operationId":"get_live_conversations","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"types","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated selection of `call`, `chat` and `agent-assist`. Defaults to calls and agent-assist sessions; ask for `chat` explicitly to include those too","title":"Types"},"description":"Comma-separated selection of `call`, `chat` and `agent-assist`. Defaults to calls and agent-assist sessions; ask for `chat` explicitly to include those too"}],"responses":{"200":{"description":"The conversations running right now","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiveConversationList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/live_conversations/{conversation_id}/end":{"post":{"tags":["Live Conversations"],"summary":"End a live conversation","description":"Hang up a conversation that is happening now, optionally after playing a parting message.\n\n**202, not 200, and deliberately so.** The action is queued for whatever is running the\nconversation, which pushes it to the platform carrying the call; `accepted` means it got that far\nand no further. The call is torn down moments later - watch the log stream or the listing to see it\ngo.\n\n`message` is spoken before the hang-up when the conversation can still speak; omit it to end\nwithout a word. A speech-to-speech conversation (`realtime` in the listing) always ends without\nit: the model generates its own audio, so there is no way to have it speak supplied text.\n\nThe failures are worth telling apart: **409** the conversation cannot take this action, **500** it\nwas tried and failed, **504** nothing answered - the conversation's owner went away, or the layer\nthey coordinate through is down. A **404** means the conversation is not running, which includes having\njust ended.\n\nTakes the **UPDATE** role, POST notwithstanding: the command changes an existing conversation\nrather than creating anything.","operationId":"end_live_conversation","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndCallRequestModel","default":{"message":""}}}}},"responses":{"202":{"description":"The action was accepted for delivery","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiveCommandAccepted"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"409":{"description":"The entity is busy with work that has to finish first, or cannot take this action","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"500":{"description":"The action was delivered but could not be carried out","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"504":{"description":"Whatever was asked to carry the action out never answered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/live_conversations/{conversation_id}/transfer":{"post":{"tags":["Live Conversations"],"summary":"Transfer a live conversation","description":"Hand a running call to a human, or to another number.\n\n`phone` is where it goes - a number or a SIP URI - and is required; `message` is spoken before\nthe transfer, which is the difference between a caller being told what is happening and one\nhearing silence. A speech-to-speech conversation (`realtime` in the listing) transfers without\nthe message: the model generates its own audio, so supplied text cannot be spoken.\n\n**202 means queued, not transferred** - as with ending a call, the platform carrying it does the\nwork and may fail afterwards. A transfer on a conversation that cannot be transferred (a chat, for\ninstance) is a **409** rather than a **400**: the request was fine, the conversation was not.\n\nTakes the **UPDATE** role, POST notwithstanding: the command changes an existing conversation\nrather than creating anything.","operationId":"transfer_live_conversation","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferCallRequestModel"}}}},"responses":{"202":{"description":"The action was accepted for delivery","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiveCommandAccepted"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"409":{"description":"The entity is busy with work that has to finish first, or cannot take this action","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"500":{"description":"The action was delivered but could not be carried out","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"504":{"description":"Whatever was asked to carry the action out never answered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/live_conversations/{conversation_id}/message":{"post":{"tags":["Live Conversations"],"summary":"Play a message into a live conversation","description":"Say something into a conversation that is happening now, without ending or transferring it.\n\nThe message is spoken to the caller as the agent's own words - this is a supervisor stepping in, so\nit lands mid-conversation and the agent carries on afterwards. The agent is not told the message\ncame from outside, and may repeat or contradict it.\n\nA speech-to-speech conversation (`realtime` in the listing) cannot take this action at all - it\nis a **409**: the model generates its own audio, and supplied text cannot be spoken.\n\n**202 means queued**, as with the other two actions. Delivery is at the next moment the\nconversation can speak, not necessarily immediately.\n\nTakes the **UPDATE** role, POST notwithstanding: the command changes an existing conversation\nrather than creating anything.","operationId":"message_live_conversation","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageRequestModel"}}}},"responses":{"202":{"description":"The action was accepted for delivery","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiveCommandAccepted"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"409":{"description":"The entity is busy with work that has to finish first, or cannot take this action","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"500":{"description":"The action was delivered but could not be carried out","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"504":{"description":"Whatever was asked to carry the action out never answered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/websocket_token":{"post":{"tags":["WebSocket Tokens"],"summary":"Obtain a token for a WebSocket connection","description":"Obtain a token for opening a WebSocket connection.\n\nA WebSocket takes its credential as a `token` query parameter, because a browser cannot set\nheaders on a handshake - and a URL is kept, so what goes there should not be your access token.\nThis is what to put there instead. It lasts as long as `expires_in` says, about a minute, and\nis accepted **once**, so ask for one each time you need to connect or reconnect.\n\nTakes the **READ** role: nothing is created that outlives the next\nconnection, and a read-only client has to be able to watch a live conversation.\n\nThe WebSocket that takes one is `/live_conversations/{conversation_id}/logs`; its frame\nformat is in the documentation's REST API section, which a schema cannot describe.","operationId":"create_websocket_token","responses":{"200":{"description":"The token, and how long it lasts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebSocketToken"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}}},"security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}]}},"/api/v1/documents":{"post":{"tags":["Documents"],"summary":"Create a document from URLs","description":"Create a document by crawling URLs.\n\n**This endpoint cannot upload files** - a JSON body has nowhere to put them. Use\n`POST /documents/form` for that, or if you are unsure which of the two you want: it takes\nURLs just as well, and is what the UI uses.\n\n`urls` is a newline-separated list. What the crawler does from there is up to the crawl\nsettings: `max_depth` link levels deep (0 = the given URLs and nothing else), at most\n`max_urls` pages, following only the links `follow_links`, `include_paths`, `exclude_paths`\nand `sitemap` allow.\n\nCrawling and chunking run after the response, so the document comes back with `status: creating`\nand no chunks yet - poll `GET /documents` and watch the row's `processing` flag.\n`overlap` has to be smaller than `chunk_size`, and an account has a cap on how many\ndocuments it may hold; either one is a **400**.","operationId":"create_document","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentModel"},"examples":{"urls":{"summary":"Crawl a documentation site","description":"`urls` is newline-separated. `max_depth` 0 fetches exactly those pages; 1 follows their links one level. A page prefixed with `##` on the line before it gets that as its title.","value":{"name":"delivery-and-returns","description":"Delivery times, returns policy and shipping costs","urls":"https://help.example.com/delivery\nhttps://help.example.com/returns","max_depth":1,"max_urls":50,"follow_links":"direct","auto_refresh":"weekly"}},"single_page":{"summary":"A single page, refreshed daily","description":"The narrowest useful crawl: one page, no link following, re-parsed every day so an agent answers from what the page says today.","value":{"name":"opening-hours","description":"Branch opening hours","urls":"https://www.example.com/opening-hours","max_depth":0,"auto_refresh":"daily","content_extraction":"main"}}}}}},"responses":{"201":{"description":"The created document, still parsing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Documents"],"summary":"List documents","description":"List all documents.\n\nRows are a projection for a list view, not whole documents: the name, the parse counters,\nand one of `urls` (the first three of them, for a crawl) or `file_names` (for uploads). Read\none back with `GET /documents/{document_id}` for the crawl settings, the advanced configuration and the\nper-URL parse results.\n\nTwo fields are for polling rather than display. `processing` says whether a row is still\nbeing parsed, and `refresh_needed` says whether any row on the page is - which is what a\nUI refreshes on. Don't parse `status` for that: it is phrased for a human\n(`ready (3 files, 412 chunks)`) and carries the parser's own message when something failed.","operationId":"get_documents","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"filter","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `name~faq` or `(name~faq,description~pricing)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `name=faq;pricing`.\n\nThis collection can be filtered by `name`, `description`.","examples":["name~faq","name~faq,description~pricing","name=faq;pricing"],"title":"Filter"},"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `name~faq` or `(name~faq,description~pricing)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `name=faq;pricing`.\n\nThis collection can be filtered by `name`, `description`."},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `description`, `status`, `type`, `urls`, `max_depth`, `auto_refresh`, `n_files`, `n_chunks`, `updated`.","examples":["-updated"],"title":"Sort"},"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `description`, `status`, `type`, `urls`, `max_depth`, `auto_refresh`, `n_files`, `n_chunks`, `updated`."},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum number of items to return. If not specified, all of them are returned.","examples":[50],"title":"Limit"},"description":"Maximum number of items to return. If not specified, all of them are returned."},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned.","examples":[1],"title":"Page"},"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned."}],"responses":{"200":{"description":"A page of documents","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/documents/form":{"post":{"tags":["Documents"],"summary":"Create a document from files or URLs","description":"Create a document from uploaded files, or from URLs to crawl. **This is the endpoint\nthat can upload files**; the JSON `POST /documents` cannot.\n\nThe body is `multipart/form-data`, and three things about it are not guessable:\n\n* **Files arrive as a repeated `file` part** - the field name is literally `file`, once per\n  file: `curl -F name=manuals -F file=@a.pdf -F file=@b.pdf ...`\n* **`urls` and `file` are mutually exclusive.** Sending both is a **400** (`Cannot specify both\n  URLs and files`), and so is sending neither (`No URLs or files specified`). A document is\n  one kind or the other for its whole life - files cannot later be added to a crawl, or URLs\n  to an upload.\n* **`advanced_config` is a JSON object encoded as a string**, since a form field can carry\n  nothing else.\n\nEverything else is a plain scalar. The values are validated as a whole document, so anything\nrejected comes back as a **400** with a readable message rather than a **422**.\n\nParsing runs after the response: the document comes back with `status: creating` and no\nchunks yet, and `GET /documents` is where to watch the row's `processing` flag for the\nfinish.\n\nAudio documents (`.wav` / `.pcm` files) may carry one matching `.txt` or `.json` transcript\nper recording, named after it. A transcript is stored and read whole rather than chunked, so\nit is the one upload with a size cap - an oversized one is a **413**, and the whole request\nis discarded rather than half-created.","operationId":"create_document_form","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_document_form"}}},"required":true},"responses":{"201":{"description":"The created document, still parsing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"413":{"description":"The uploaded file is larger than this endpoint accepts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}]}},"/api/v1/documents/{document_id}":{"get":{"tags":["Documents"],"summary":"Get a document","description":"Read one document's full configuration and what the parse made of it.\n\n`doc_data` has an entry per crawled URL or uploaded file, with the chunk count and, where\nsomething went wrong, the reason - so it is the place to look when a document is `ready` but\nan agent cannot find what it should. A URL fetched by a browser-based download client is\nprefixed there with a marker: `●` for `enhanced`, `✦` for `advanced`. The URL itself is the\nrest of the string.\n\nCrawl settings that a document created before they existed does not store come back at their\ndefaults, so what you read here is the document's *effective* configuration rather than its\nstored one - which is also what makes the whole object safe to edit and send back.","operationId":"get_document","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","title":"Document Id"}}],"responses":{"200":{"description":"The document, with its per-file parse results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentResponse"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Documents"],"summary":"Update a document from URLs","description":"Update a document's settings or its URL list. Every field is optional - omit one and its\nstored value is kept.\n\n**This endpoint cannot upload files**, and it is not the way to change which uploaded files a\ndocument keeps either: `PUT /documents/form/{document_id}` does both. URLs cannot be given to\na document built from files at all.\n\n**A change to anything the parse reads re-parses the document from scratch**, so `status`\ncomes back `updating` and the chunk counts stay stale until that finishes - for a URL document\nthat is a full re-crawl. `description` is one of those fields: it is part of what a search\nmatches a document against. Renaming a document, or changing only how often it refreshes, is\nnot, and leaves the parsed content alone. Sending a body that changes nothing re-parses, which\nis how a URL document is re-crawled on demand.\nSending `chunk_size` requires sending `overlap` with it, since the two are only meaningful\nagainst each other. `advanced_config` replaces the whole advanced configuration when sent;\nomit it to keep the stored one.","operationId":"update_document","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","title":"Document Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentUpdateModel"}}}},"responses":{"200":{"description":"The updated document","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Documents"],"summary":"Delete a document","description":"Delete a document, its chunks and its uploaded files.\n\nA parse still running for this document is stopped first, so the call can take a few seconds\non a document that is mid-crawl.","operationId":"delete_document","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","title":"Document Id"}}],"responses":{"204":{"description":"No content"},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/documents/{document_id}/chunks/{doc_id}":{"get":{"tags":["Documents"],"summary":"Get one file's chunks","description":"Read the chunks one of a document's files or URLs was split into.\n\n`doc_id` is that entry's **position in the document's own `doc_data` list**, as\n`get_document` returns it - not an id of its own. The chunks are the exact texts a retrieval\nhit hands to an agent, which is what makes this the place to look when an agent answers from\nthe wrong passage.\n\nAn empty object comes back rather than a **404** whenever there is nothing to show: a document\nthat has not finished parsing, a `doc_id` past the end of the list, or a document id that\ndoes not exist.","operationId":"get_document_chunks","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","title":"Document Id"}},{"name":"doc_id","in":"path","required":true,"schema":{"type":"integer","title":"Doc Id"}}],"responses":{"200":{"description":"The chunks, in document order","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentChunks"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/documents/{document_id}/content":{"get":{"tags":["Documents"],"summary":"Get a document's parsed text","description":"Read what the parse made of a document: every file or URL concatenated into one markdown\nstream, before chunking.\n\nThis is the source an agent's retrieval actually searches, so it is where to check whether a\ncrawl or a PDF conversion picked the text up at all - a document can be `ready` and still\nhave got nothing but a cookie banner.\n\nServed as `text/plain`, and truncated at 100,000 characters because it is read into the\nserving process to answer the request. An empty body comes back rather than a **404** for a\ndocument that has not parsed yet, or an id that does not exist.","operationId":"get_document_content","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","title":"Document Id"}}],"responses":{"200":{"description":"The whole document as markdown text","content":{"text/plain":{"schema":{"type":"string"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/documents/form/{document_id}":{"put":{"tags":["Documents"],"summary":"Update a document from files or URLs","description":"Update a document, replace its files, or both. Every field is optional - omit one and its\nstored value is kept. **This is the endpoint that can upload files**; the JSON\n`PUT /documents/{document_id}` cannot.\n\nThe body is `multipart/form-data` and works as it does on create - a repeated `file` part per\nfile, `advanced_config` as a JSON string - with one addition that is easy to get backwards:\n\n* **`file_names` is a comma-separated keep-list**, not a list of files to remove. The document\n  ends up with exactly the files this request uploads plus the ones `file_names` names; a file\n  left out of both is deleted. Sending the whole list back unchanged is therefore how a\n  metadata-only edit leaves the files alone, and dropping one name from it is how a file is\n  removed.\n* Removing an audio recording takes its matching transcript with it, named or not - a\n  transcript with no recording is not a thing a document can hold.\n\nA document keeps its kind: `urls` on a document built from files is a **400**, and files on one\nbuilt from URLs likewise. `advanced_config` replaces the whole advanced configuration when\nsent; omit it to keep the stored one. An oversized transcript is a **413** and nothing is\nsaved.\n\n**A change to anything the parse reads re-parses the document**, so `status` comes back\n`updating` and the chunk counts stay stale until that finishes; poll the listing's `processing`\nflag. `description` is one of those fields - it is part of what a search matches a document\nagainst - while a rename, or a change to how often the document refreshes, leaves the parsed\ncontent alone. Sending the document back unchanged re-parses it, which is how a URL document\nis re-crawled on demand.","operationId":"update_document_form","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","title":"Document Id"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_update_document_form"}}}},"responses":{"200":{"description":"The updated document","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"413":{"description":"The uploaded file is larger than this endpoint accepts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/models":{"post":{"tags":["LLMs"],"summary":"Create a model","description":"Create custom model - bring your own API key, an Azure deployment, or any\nOpenAI-compatible endpoint.\n\nWhich fields are required depends on `provider`. The field list below spans every provider,\nso most of it will not apply to yours: `openai` and the other direct providers need\n`model_name` and `api_key`; `azure-openai` needs `deployment_name` and `api_base` as well;\n`google-vertex` needs the project, region and service-account key; `amazon` needs the three\nAWS fields; and `custom` needs `api_base` plus the `context_len` / `tools_api` /\n`streaming` / `structured_output` settings that describe what the endpoint supports.\n\nThe name has to be unique and cannot repeat the name of a pre-deployed model.\n\n**Secrets are never returned in the clear.** The response masks them to their first three\ncharacters plus `*****`. Sending a mask back on update is understood as \"leave this one\nalone\", so a client can round-trip the whole object without knowing the secret.","operationId":"create_llm","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LLMModel"},"examples":{"azure_openai":{"summary":"An Azure OpenAI deployment","description":"The provider with the most required fields, and the one worth seeing spelled out: `deployment_name` is what you called the deployment in Azure, `model_name` is the OpenAI model behind it, and `api_base` is the resource endpoint **without** any `/openai/deployments` path.","value":{"name":"my-gpt-4o","description":"The account's own GPT-4o deployment","provider":"azure-openai","model_name":"gpt-4o","deployment_name":"gpt4o-prod","api_base":"https://my-resource.openai.azure.com","api_key":"REPLACE-WITH-YOUR-KEY"}},"openai":{"summary":"OpenAI with the account's own key","description":"A direct provider needs only the model name and a key. The same shape covers `anthropic`, `google`, `groq`, `mistral`, `xai` and `cerebras`.","value":{"name":"my-openai","provider":"openai","model_name":"gpt-4o","api_key":"REPLACE-WITH-YOUR-KEY"}},"custom":{"summary":"Any OpenAI-compatible endpoint","description":"`custom` takes a free-text model name and needs to be told what the endpoint supports: its context length, whether it can call tools, whether it streams, and whether it does structured output.","value":{"name":"self-hosted-llama","provider":"custom","model_name":"llama-3.3-70b-instruct","api_base":"https://llm.internal.example.com/v1","api_key":"REPLACE-WITH-YOUR-KEY","context_len":128000,"tools_api":"tools","streaming":true,"structured_output":false}}}}}},"responses":{"201":{"description":"The created model, with its secrets masked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LLMResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["LLMs"],"summary":"List models","description":"List all custom models.\n\nRows are a compact projection for a list view, not whole models - no credentials, and no\nprovider-specific settings. Read one back with `GET /models/{id}` for those.\n`is_realtime` field indicates whether the model can drive a speech-to-speech\nagent.\n\nThe pre-deployed models are not listed here.","operationId":"get_llms","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"filter","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `provider=openai` or `(provider=openai,model_name~mini)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `provider=openai;google`.\n\nThis collection can be filtered by `name`, `provider`, `model_name`.","examples":["provider=openai","provider=openai,model_name~mini","provider=openai;google"],"title":"Filter"},"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `provider=openai` or `(provider=openai,model_name~mini)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `provider=openai;google`.\n\nThis collection can be filtered by `name`, `provider`, `model_name`."},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `provider`, `model_name`.","examples":["-name"],"title":"Sort"},"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `provider`, `model_name`."},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum number of items to return. If not specified, all of them are returned.","examples":[50],"title":"Limit"},"description":"Maximum number of items to return. If not specified, all of them are returned."},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned.","examples":[1],"title":"Page"},"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned."}],"responses":{"200":{"description":"A page of the account's own models","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LLMList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/models/{llm_id}":{"get":{"tags":["LLMs"],"summary":"Get a model","description":"Read a custom model.\n\nSecrets come back masked - the first three characters plus `*****`. Send a mask back\nunchanged on update and the stored secret is kept, so the object round-trips without the\ncaller ever holding the credential.\n\nEvery provider's fields are present in the schema; the ones that do not apply to this\nmodel's `provider` are empty.","operationId":"get_llm","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"llm_id","in":"path","required":true,"schema":{"type":"string","title":"Llm Id"}}],"responses":{"200":{"description":"The model, with its secrets masked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LLMResponse"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["LLMs"],"summary":"Update a model","description":"Update a custom model. Every field is optional - omit one and its stored value is kept.\n\n**Secrets.** Send a masked value back and it is treated as unchanged, which is what lets a\nclient read the model, edit one field and send the whole object back. Send a real value to\nreplace one, or an empty string to clear it - clearing revokes the stored secret, so the model\nstops working until you set a new one. `vertex_key` is the exception: an empty one is taken as\n\"unchanged\", since a key that arrives blank is far more often an omission than a revocation.\n\n**The per-provider requirements are checked against the `provider` you send.** Name it and the\nwhole set applies, as on create - so a request that sets `provider` cannot also blank the\n`api_key`, deployment name or region that provider requires. Leave `provider` out and only what\nyou sent is validated, which is how a credential gets cleared. The name still cannot collide\nwith a model this deployment provides.","operationId":"update_llm","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"llm_id","in":"path","required":true,"schema":{"type":"string","title":"Llm Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LLMUpdateModel"}}}},"responses":{"200":{"description":"The updated model, with its secrets masked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LLMResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["LLMs"],"summary":"Delete a model","description":"Delete a custom model.\n\n**Whatever used it is moved to the account's default model**, there and then: every agent, flow,\nflow node, test suite and post-call analysis pointing at it is rewritten in place, so a read\nafterwards shows the default rather than a dangling reference.","operationId":"delete_llm","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"llm_id","in":"path","required":true,"schema":{"type":"string","title":"Llm Id"}}],"responses":{"204":{"description":"No content"},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/post_call_analysis":{"post":{"tags":["Post Call Analysis"],"summary":"Create a post-call analysis","description":"Create an analysis to run over a conversation's transcript once the conversation has ended.\n\n**`type` decides what it produces**, and what else it needs:\n\n* `summarize` - a prose summary, from `summarize_prompt` or the platform's default.\n* `extract` - named values pulled out of the transcript, one per entry in `params`.\n* `insights` - the same extraction, but the values are also aggregated across conversations and\n  reported as metrics. Only `int`, `float`, `bool` and `str` variables are allowed, and **a `str`\n  variable has to be narrowed to a fixed set in its description** (`ENUM: yes, no`) - an open\n  string cannot be aggregated.\n* `transcript` - the transcript itself, with no model involved. This is the one type that needs\n  no `llm`; every other type is rejected without one.\n\nAn agent or flow names the analyses it wants in its own `post_call_analysis` field - creating one\nhere does not attach it to anything. Set `webHookUrl` to have the result posted somewhere as well\nas stored.\n\nRejected with a **400**: a duplicate name or parameter name, a missing model, an `insights` variable\nof an unsupported type or an un-narrowed `insights` string, and the account's cap.","operationId":"create_post_call_analysis_tool","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCallAnalysisModel"},"examples":{"extract":{"summary":"Pull named values out of the transcript","description":"One entry in `params` per value wanted. A parameter's `description` is the instruction the model follows, so it is where the work goes.","value":{"name":"call-outcome","description":"What the caller wanted and whether they got it","type":"extract","llm":"gpt-4o","params":[{"name":"reason","type":"str","required":true,"description":"Why the caller got in touch, in a few words"},{"name":"resolved","type":"bool","required":true,"description":"Whether the caller got what they wanted before the call ended"}]}},"summarize":{"summary":"Summarise the call, and post it somewhere","description":"A summary needs no `params`. Setting `webHookUrl` posts the result as well as storing it, which is how a call summary reaches a CRM.","value":{"name":"call-summary","description":"A short summary of every call","type":"summarize","llm":"gpt-4o","summarize_prompt":"Summarise this call in two sentences: what the caller wanted, and what was agreed.","webHookUrl":"https://crm.example.com/hooks/call-summary","auth":{"type":"bearer","token":"REPLACE-WITH-YOUR-TOKEN"}}},"insights":{"summary":"Values aggregated across calls","description":"Same extraction, but the values are also reported as metrics through `/insights`. Only int, float, bool and str are allowed, and **a str has to be narrowed to a fixed set** with `ENUM:` in its description - an open string cannot be aggregated.","value":{"name":"call-insights","description":"Sentiment and resolution, per call","type":"insights","llm":"gpt-4o","params":[{"name":"sentiment","type":"str","required":true,"display_name":"Caller sentiment","description":"How the caller sounded overall. ENUM: positive, neutral, negative"},{"name":"resolved","type":"bool","required":true,"display_name":"Resolved on first call","description":"Whether the issue was settled without another call being needed"}]}}}}}},"responses":{"201":{"description":"The created definition","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCallAnalysisResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Post Call Analysis"],"summary":"List post-call analyses","description":"List post-call analysis definitions - what will run after a conversation, not what\nany conversation produced. `GET /post_call_analysis_data` is for the results.\n\nA row is a projection: the variables are counted rather than listed, and the prompts are not in it.","operationId":"get_all_post_call_analysis","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"filter","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `name~sentiment` or `(name~sentiment,webHookUrl~crm)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `name=summary;sentiment`.\n\nThis collection can be filtered by `name`, `description`, `webHookUrl`.","examples":["name~sentiment","name~sentiment,webHookUrl~crm","name=summary;sentiment"],"title":"Filter"},"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `name~sentiment` or `(name~sentiment,webHookUrl~crm)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `name=summary;sentiment`.\n\nThis collection can be filtered by `name`, `description`, `webHookUrl`."},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `description`, `llm`, `webHookUrl`, `auth_type`, `params_count`.","examples":["-name"],"title":"Sort"},"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `description`, `llm`, `webHookUrl`, `auth_type`, `params_count`."},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum number of items to return. If not specified, all of them are returned.","examples":[50],"title":"Limit"},"description":"Maximum number of items to return. If not specified, all of them are returned."},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned.","examples":[1],"title":"Page"},"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned."}],"responses":{"200":{"description":"A page of definitions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCallAnalysisList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/post_call_analysis/{pca_id}":{"get":{"tags":["Post Call Analysis"],"summary":"Get a post-call analysis","description":"Read post-call analysis definition in full. `GET /post_call_analysis_data` is for the results.\n\nThe webhook token comes back masked; echoing it back keeps the stored one.","operationId":"get_post_call_analysis","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"pca_id","in":"path","required":true,"schema":{"type":"string","title":"Pca Id"}}],"responses":{"200":{"description":"The definition","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCallAnalysisResponse"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Post Call Analysis"],"summary":"Update a post-call analysis","description":"Update a post-call analysis definition. Every field is optional - omit one and its stored value is kept.\n\nThe webhook token follows the usual rule - a masked value echoed back means unchanged.\n\nEditing a definition changes what runs after the *next* conversation. Results already stored are\nnot re-computed, so a listing can hold results from two versions of the same definition.","operationId":"update_post_call_analysis","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"pca_id","in":"path","required":true,"schema":{"type":"string","title":"Pca Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCallAnalysisUpdateModel"}}}},"responses":{"200":{"description":"The updated definition","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCallAnalysisResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Post Call Analysis"],"summary":"Delete a post-call analysis","description":"Delete a post-call analysis definition, so it stops running after conversations.\n\nEvery agent and flow that named it has the reference removed. **Results it already produced\nstay** - they belong to the conversations, not to the definition, so `/post_call_analysis_data`\nkeeps returning them.","operationId":"delete_post_call_analysis","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"pca_id","in":"path","required":true,"schema":{"type":"string","title":"Pca Id"}}],"responses":{"204":{"description":"No content"},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/post_call_analysis/{pca_id}/clone":{"post":{"tags":["Post Call Analysis"],"summary":"Clone a post-call analysis","description":"Copy a post-call analysis definition under a new name and a new id. Takes no request body.\n\nThe copy is named `clone <original>`, or `clone-1 <original>` and upwards where that is taken. No\nagent or flow references it, so it runs after nothing until one names it - which is what makes\ncloning the way to try a different prompt without touching a definition already in use.","operationId":"clone_post_call_analysis","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"pca_id","in":"path","required":true,"schema":{"type":"string","title":"Pca Id"}}],"responses":{"201":{"description":"The new copy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCallAnalysisResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/post_call_analysis_data":{"get":{"tags":["Post Call Analysis"],"summary":"List post-call analysis results","description":"List post-call analysis results, one row per conversation that has been analysed.\n\n**A row is keyed by the conversation**: its `id` is the conversation's id, which is what\n`get_post_call_analysis_data` takes. `names` lists which definitions produced results for it, as a\nhint of what the full record holds - the outputs themselves are in the single read.\n\nUnlike the entity listings, this one is paged and **defaults to 100 rows, capped at\n200**; a `limit` outside 1-200 falls back to the default rather than being rejected.\n\nA conversation appears here once its analyses have run, which is after it ended - so the newest\nconversation may not be listed yet.","operationId":"list_post_call_analysis_data","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"filter","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `agent=support` or `(agent=support,time>=2026-01-01T00:00:00Z)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `agent=support;billing`.\n\nThis collection can be filtered by `time`, `agent`.","examples":["agent=support","agent=support,time>=2026-01-01T00:00:00Z","agent=support;billing"],"title":"Filter"},"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `agent=support` or `(agent=support,time>=2026-01-01T00:00:00Z)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `agent=support;billing`.\n\nThis collection can be filtered by `time`, `agent`."},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"Field to sort by, prefixed with `-` for descending. If not specified, the newest come first. A field this collection cannot be sorted by falls back to that default rather than being rejected.\n\nThis collection can be sorted by `time`, `agent`.","examples":["-time"],"default":"-time","title":"Sort"},"description":"Field to sort by, prefixed with `-` for descending. If not specified, the newest come first. A field this collection cannot be sorted by falls back to that default rather than being rejected.\n\nThis collection can be sorted by `time`, `agent`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Maximum number of items to return, 1..200. Anything outside that range falls back to 100 rather than being rejected.","examples":[100],"default":100,"title":"Limit"},"description":"Maximum number of items to return, 1..200. Anything outside that range falls back to 100 rather than being rejected."},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned.","examples":[1],"title":"Page"},"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned."}],"responses":{"200":{"description":"A page of results, newest first","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCallAnalysisDataList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/post_call_analysis_data/{conversation_id}":{"get":{"tags":["Post Call Analysis"],"summary":"Get one conversation's results","description":"Get post-call analyses results for a specific conversation.\n\n`conversation_id` is the conversation's own id. **The literal `latest` is accepted** in its place\nand returns the most recently analysed conversation in the account, which is what makes this\nusable for a quick check after a test call without looking an id up first.\n\n`results` has one entry per definition that ran, its output under `data`, and `type` says how to\nread it: `transcript` carries the conversation itself, `summarize` its summary under `output`, and\n`extract` the variables pulled out. On results stored before `type` existed it is inferred here\nfrom which keys `data` holds.","operationId":"get_post_call_analysis_data","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"responses":{"200":{"description":"Every analysis result for that conversation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCallAnalysisData"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Post Call Analysis"],"summary":"Delete one conversation's results","description":"Delete the post-call analysis results for specific conversation.\n\nOnly the results go: the conversation itself, its transcript and its recording are separate and\nstay. Nothing re-runs the analysis afterwards, so this is not a way to have a conversation\nre-analysed - the results are gone for good.\n\nUnlike the single read, this takes an id only; `latest` is not accepted here.","operationId":"delete_post_call_analysis_data","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"responses":{"204":{"description":"No content"},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools":{"post":{"tags":["Tools"],"summary":"Create a tool","description":"Create a tool an agent or a flow node can call.\n\n**`type` decides what the rest of the fields mean.** A `rest` tool calls an HTTP endpoint and\nuses `url`, `method`, `headers`, `content` and `auth`. An `mcp` tool points `url` at an MCP\nserver and may narrow what it exposes with `mcp_tools`. A `flow` tool runs one of the account's\nflows - named in `flow`, and required - and ignores the HTTP fields entirely.\n\n**`description` is a prompt, not documentation.** It is the text the model reads when deciding\nwhether to call this tool, and so is the field that most decides whether the tool ever gets used.\nThe same goes for each parameter's own description.\n\n`{name}` in the URL, headers or body is substituted at call time - from a declared parameter, a\ntool variable, or a conversation variable, in that order. A parameter description beginning with\n`=` declares a default rather than describing the parameter.\n\nThe name has to be free of the platform's builtin tools (`end_call`, `transfer_call` and the\nrest), which would win at resolution time. Rejected with a **400**: a duplicate name, a duplicate\nparameter name, a malformed header line, an invalid variable name, a `flow` tool with no flow, and\nthe account's tool cap.","operationId":"create_tool","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolModel"},"examples":{"rest_get":{"summary":"A REST tool with a parameter in the URL","description":"`{order_id}` is substituted from the parameter of that name when the model calls the tool. `description` is what the model reads when deciding whether to call it, so it is the field that decides whether the tool is used at all.","value":{"name":"lookup-order","description":"Look up an order's status and delivery date by its order number.","type":"rest","method":"GET","url":"https://api.example.com/orders/{order_id}","params":[{"name":"order_id","type":"str","required":true,"description":"The order number, as the caller gives it"}],"timeout":10}},"rest_post_with_auth":{"summary":"A REST tool that posts, with a bearer token","description":"The body is a template: `{...}` references a parameter or a tool variable. A variable typed `secret` is stored and returned masked, which is how a key that belongs in a header stays out of the URL.","value":{"name":"create-ticket","description":"Open a support ticket for the caller and return its reference.","type":"rest","method":"POST","url":"https://api.example.com/tickets","auth":{"type":"bearer","token":"REPLACE-WITH-YOUR-TOKEN"},"headers":"Content-Type: application/json\nX-Api-Version: {api_version}","content":"{\"subject\": \"{subject}\", \"priority\": \"{priority}\", \"phone\": \"{caller}\"}","params":[{"name":"subject","type":"str","required":true,"description":"One line describing the problem"},{"name":"priority","type":"str","required":false,"description":"ENUM: low, normal, high"}],"variables":[{"name":"api_version","type":"str","value":"2024-01-01"}],"response_reshape":".ticket.reference"}},"mcp":{"summary":"A tool backed by an MCP server","description":"One tool entry exposes every tool the server advertises. Narrow that with `mcp_tools`, and use `POST /tools/{tool_id}/mcp-tools` to see what the server offers.","value":{"name":"crm","description":"Customer records: look up a customer, list their recent orders.","type":"mcp","url":"https://mcp.example.com/crm","auth":{"type":"bearer","token":"REPLACE-WITH-YOUR-TOKEN"},"mcp_tools":"get_customer,list_orders"}}}}}},"responses":{"201":{"description":"The created tool, with its secrets masked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Tools"],"summary":"List tools","description":"List all custom tools.\n\n**The platform's builtin tools are not here** - `end_call`, `transfer_call` and the rest are\nreferenced by name without being defined here. This lists only the\ncustom REST, MCP and flow tools.\n\nA row is a projection: parameters are counted rather than listed, authentication is reduced to\nits type, and which of `method`, `url` and `flow` a row carries follows from `type`. Read one\nback with `GET /tools/{tool_id}` for the whole definition.","operationId":"get_tools","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"filter","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `url~crm` or `(url~crm,method=GET)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `method=GET;POST`.\n\nThis collection can be filtered by `name`, `description`, `url`, `method`.","examples":["url~crm","url~crm,method=GET","method=GET;POST"],"title":"Filter"},"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `url~crm` or `(url~crm,method=GET)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `method=GET;POST`.\n\nThis collection can be filtered by `name`, `description`, `url`, `method`."},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `description`, `type`, `url`, `method`, `auth_type`, `params_count`.","examples":["-name"],"title":"Sort"},"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `description`, `type`, `url`, `method`, `auth_type`, `params_count`."},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum number of items to return. If not specified, all of them are returned.","examples":[50],"title":"Limit"},"description":"Maximum number of items to return. If not specified, all of them are returned."},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned.","examples":[1],"title":"Page"},"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned."}],"responses":{"200":{"description":"A page of the account's own tools","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools/{tool_id}":{"get":{"tags":["Tools"],"summary":"Get a tool","description":"Read custom tool in full.\n\nEvery field that applies is present whatever the tool's `type`, at its default where the tool\ndoes not set it; a field left unset that has no default - `flow` on a REST tool, `mcp_tools`,\n`response_reshape` - is absent rather than null. Settings the tool predates come back at the\nvalue the runtime uses for it rather than the model's default - `realtime_async_mode` reads\n`false` on a tool created before it existed, because that is how such a tool behaves.\n\nSecrets - the bearer token, the password, the OAuth client secret, and any `secret`-typed\nvariable - come back masked to their first three characters plus `*****`. Echo a mask back on\nupdate and the stored secret is kept, so the whole object round-trips without the caller ever\nholding a credential.","operationId":"get_tool","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"tool_id","in":"path","required":true,"schema":{"type":"string","title":"Tool Id"}}],"responses":{"200":{"description":"The tool, with its secrets masked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResponse"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Tools"],"summary":"Update a tool","description":"Update a custom tool. Every field is optional - omit one and its stored value\nis kept.\n\n**`params` and `variables` replace rather than merge**: each is taken as the new whole, so\nediting one parameter means sending them all. `auth` likewise replaces the authentication block.\n\n**Secrets.** A masked value sent back is understood as unchanged - which is what lets a client\nread a tool, edit one field and send the whole object back. A real value replaces the secret, and\nan empty string clears it. For a `secret`-typed variable, a mask matching nothing stored is a\n**400** rather than being taken literally: storing it would make the mask itself the secret. Send\na real value for a renamed secret, not the mask you read off the old one.\n\nChanging `type` is allowed, and drags the type-specific fields with it: switching away from\n`flow` clears the flow reference, and switching *to* it requires one.","operationId":"update_tool","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"tool_id","in":"path","required":true,"schema":{"type":"string","title":"Tool Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolUpdateModel"}}}},"responses":{"200":{"description":"The updated tool, with its secrets masked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Tools"],"summary":"Delete a tool","description":"Delete a tool.\n\nA flow this tool ran is a separate entity and is untouched.","operationId":"delete_tool","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"tool_id","in":"path","required":true,"schema":{"type":"string","title":"Tool Id"}}],"responses":{"204":{"description":"No content"},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools/{tool_id}/clone":{"post":{"tags":["Tools"],"summary":"Clone a tool","description":"Copy a tool under a new name and a new id. Takes no request body.\n\nThe copy is named `clone <original>`, or `clone-1 <original>` and upwards where that is taken. It\nis fully independent of the original, which is what makes cloning the safe way to try a variant of\na tool that agents already use.\n\nNothing references the copy: an agent has to be given it, or a flow node pointed at it.","operationId":"clone_tool","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"tool_id","in":"path","required":true,"schema":{"type":"string","title":"Tool Id"}}],"responses":{"201":{"description":"The new copy, with its secrets masked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools/{tool_id}/test-params":{"post":{"tags":["Tools"],"summary":"List a tool's test parameters","description":"What `test-run` needs supplied, for a `rest` or `flow` tool.\n\nMore than the tool's declared `params`: a REST tool's URL, headers, body, reshape and\nauthentication may reference `{name}` values that are neither declared parameters nor tool\nvariables, and those have to be supplied too or the call goes out with the placeholder in it.\nThey come back typed `str`. A flow tool has no such references - only its own parameters, plus\nwhatever variables the flow reads, which a test run may pass as extra values.\n\n**The body is optional, and its point is testing an unsaved edit.** Send nothing and the saved\ntool is used. Send `tool` and that definition is used instead of the stored one, so a client can\nresolve parameters for a tool the user is still editing. Masked secrets in an override are filled\nin from the saved copy, matched by id or, failing that, by name.\n\nAn `mcp` tool is a **400** here: its parameters belong to the individual MCP tools, so use\n`/mcp-tools` and then `/mcp-tools/{mcp_tool_name}`.","operationId":"get_tool_test_params","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"tool_id","in":"path","required":true,"schema":{"type":"string","title":"Tool Id"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolOverrideRequestModel"}}}},"responses":{"200":{"description":"Every value a test run has to be given","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolTestParams"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools/{tool_id}/mcp-tools":{"post":{"tags":["Tools"],"summary":"List an MCP server's tools","description":"Ask the MCP server this tool points at what it can do.\n\n**This reaches out to the server**, using the tool's URL and authentication, so it is also how to\ncheck that a newly configured MCP tool connects at all. Names and descriptions only - a server\nmay advertise dozens of tools, and each one's parameters are a separate read\n(`/mcp-tools/{mcp_tool_name}`).\n\n**The tool's own `mcp_tools` allow-list is applied first**, so this answers what the tool exposes\nrather than everything the server has: an agent given the tool sees exactly these. Clear\n`mcp_tools` to see the server's full set.\n\nAs with the other testing endpoints, the body is optional: send nothing to use the saved tool, or\n`tool` to use a definition the user is still editing, with masked secrets filled in from the saved\ncopy. A **400** covers both a tool that is not `mcp` and a server that could not be reached - the\nreason is in `detail`.","operationId":"get_tool_mcp_tools","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"tool_id","in":"path","required":true,"schema":{"type":"string","title":"Tool Id"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolOverrideRequestModel"}}}},"responses":{"200":{"description":"The tools the server offers, name and description only","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpToolList"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools/{tool_id}/mcp-tools/{mcp_tool_name}":{"post":{"tags":["Tools"],"summary":"Get one MCP tool's parameters","description":"What one of the MCP server's tools takes, ready to hand to `test-run`.\n\n`mcp_tool_name` is the name as `/mcp-tools` listed it. The server's JSON-schema input is\ntranslated into the same parameter shape `test-params` returns for a REST tool - name, type,\nrequired, default - so a client can render one form for either kind of tool.\n\nThis reaches out to the server again rather than caching the earlier listing, so a tool added on\nthe server since is visible. An unknown name and an unreachable server are both a **400**, as is a\ntool that is not `mcp`.","operationId":"get_tool_mcp_tool","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"tool_id","in":"path","required":true,"schema":{"type":"string","title":"Tool Id"}},{"name":"mcp_tool_name","in":"path","required":true,"schema":{"type":"string","title":"Mcp Tool Name"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolOverrideRequestModel"}}}},"responses":{"200":{"description":"The named tool, with its parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpTool"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools/{tool_id}/test-run":{"post":{"tags":["Tools"],"summary":"Run a tool once","description":"Call the tool for real, with values you supply, and see exactly what comes back.\n\n**This is a live call**, not a simulation: a REST tool sends the request, an MCP tool invokes the\nnamed tool on the server, and a flow tool runs the flow to completion. Nothing is recorded as a\nconversation.\n\n`params` is a flat list of name/value pairs, and **a name that is not one of the tool's declared\nparameters is treated as a variable override** - which is how the `{name}` references that\n`test-params` reports get filled in. For an MCP tool, `mcp_tool_name` is required and `params` are\nthat tool's arguments; values may be sent as strings and are coerced to the types the server's\nschema declares.\n\nThe response separates two things worth comparing: `response_body` is what the endpoint actually\nsaid, and `reshaped_response_body` is what `response_reshape` made of it - which is what the model\nwould have received.\n\n**For a REST tool, an error status from the endpoint is not an error here**: a **500** comes back as\n`status_code` **500** with its body, and `error` stays null. `error` is for a call that never\ncompleted - a connection failure, a bad template - and `status_code` is null alongside it. An MCP\ntool differs: it has no HTTP status of its own, so `status_code` is a synthesized 200 or **500**, and a\ntool that reports failure sets both that **500** **and** `error`.\n\nAs with the other testing endpoints, `tool` in the body replaces the saved definition, so an\nunsaved edit can be tried before it is stored; masked secrets in it are filled in from the saved\ncopy.","operationId":"run_tool_test","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"tool_id","in":"path","required":true,"schema":{"type":"string","title":"Tool Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunRequestModel"}}}},"responses":{"200":{"description":"What the call returned, raw and reshaped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolTestRun"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/test_suites":{"post":{"tags":["Test Suites"],"summary":"Create a test suite","description":"Create a set of tests to run against an agent or a flow. A test is a scenario the platform\nplays out with a simulated caller, judged by a model.\n\n`agent` names the target and `target_type` says which kind it is - an agent by default, a flow\notherwise. `llm` is the model that **plays the caller and judges the outcome**, so it has to be a\ntext model: a speech-to-speech one is rejected.\n\nRejected with a **400**: a duplicate suite or test name, a target that does not exist, an unknown or\nrealtime model, and the account's suite cap.","operationId":"create_tests_suite","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSuiteModel"}}}},"responses":{"201":{"description":"The created suite","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSuiteResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Test Suites"],"summary":"List test suites","description":"List all test suites - the definitions, not the runs. `GET /tests` lists the runs.\n\nA row carries the target both ways: `agent` is the id and `agent_name` the name. The tests\nthemselves are reduced to a count plus their names, which is enough to offer one to run on its own.","operationId":"get_all_test_suites","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"filter","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `name~smoke` or `(name~smoke,description~nightly)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `name=smoke;regression`.\n\nThis collection can be filtered by `name`, `description`.","examples":["name~smoke","name~smoke,description~nightly","name=smoke;regression"],"title":"Filter"},"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `name~smoke` or `(name~smoke,description~nightly)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `name=smoke;regression`.\n\nThis collection can be filtered by `name`, `description`."},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `description`.","examples":["-name"],"title":"Sort"},"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `description`."},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum number of items to return. If not specified, all of them are returned.","examples":[50],"title":"Limit"},"description":"Maximum number of items to return. If not specified, all of them are returned."},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned.","examples":[1],"title":"Page"},"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned."}],"responses":{"200":{"description":"A page of test suites","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSuiteList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/test_suites/{test_id}":{"get":{"tags":["Test Suites"],"summary":"Get a test suite","description":"Read one test suite and every test in it.\n\nThe target and the model come back as **names** (`agent_name`, `llm`), though both are stored as\nids - so the object can be edited and sent back as it is.","operationId":"get_test_suite","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string","title":"Test Id"}}],"responses":{"200":{"description":"The suite, with its tests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSuiteResponse"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Test Suites"],"summary":"Update a test suite","description":"Update a test suite. Every field is optional - omit one and its stored value is kept.\n\n**`tests` replaces the whole set**, so editing one test means sending them all; read the suite\nfirst if you do not hold them. Test names have to be unique within the suite.\n\nChanging the target or the model is validated the same way create is: the target has to exist, and\nthe model has to be a text one.","operationId":"update_test_suite","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string","title":"Test Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSuiteUpdateModel"}}}},"responses":{"200":{"description":"The updated suite","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSuiteResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Test Suites"],"summary":"Delete a test suite","description":"Delete a test suite and its tests.\n\n**Past runs stay.** They belong to the runs collection, so `GET /tests` keeps returning them and\neach still names the suite it came from - a suite id in an old run may no longer resolve.","operationId":"delete_test_suite","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string","title":"Test Id"}}],"responses":{"204":{"description":"No content"},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/test_suites/export":{"post":{"tags":["Test Suites"],"summary":"Export test suites","description":"Download one or more test suites as a ZIP, for moving them between accounts or keeping them in\nversion control.\n\n`test_suites` is a list naming what to export, **by id or by name** - the two are interchangeable\nhere. The archive holds a single `data.json` with the suites sorted by name, and each suite keeps\nits target and model as names rather than ids, which is what makes the file portable.\n\nThe internal fields go: no ids, no account. Import matches on name instead. Naming nothing that\nexists is a **400** rather than an empty archive.","operationId":"export_test_suites","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSuiteExportRequest"}}},"required":true},"responses":{"200":{"description":"A ZIP archive containing data.json","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}]}},"/api/v1/test_suites/import":{"post":{"tags":["Test Suites"],"summary":"Import test suites","description":"Upload an archive produced by `export` and create the test suites in it.\n\n`multipart/form-data` with a single `file` part, which has to be a `.zip` containing `data.json`.\n\n**A suite whose name already exists is overwritten**, keeping its id - so importing the same\narchive twice leaves one copy, not two, and re-importing is how an edited file is applied. The\ntargets and models are matched by name in *this* account. A model name that matches nothing is\ncleared, and a target that matches nothing is kept as the archive had it; either way the suite\nimports and cannot run until it is pointed at something that exists here.\n\n**Import is partial rather than all-or-nothing**: a suite that fails validation is skipped and\nnamed in `skipped`, and the rest are still created. Only a broken archive - not a zip, no\n`data.json`, no suites in it - is a **400**.","operationId":"import_test_suites","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_import_test_suites"}}},"required":true},"responses":{"200":{"description":"What was imported, and what was skipped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSuiteImport"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}]}},"/api/v1/test_suites/{test_id}/start":{"post":{"tags":["Test Suites"],"summary":"Start a test run","description":"Run a test suite against its target and return at once, before any test has finished.\n\n**The run is asynchronous.** The response carries the run's id (as `_id`, which is the runtime's\nown shape passed through) and nothing about outcomes; `GET /tests/{test_id}` with that id is where\nprogress and results appear.\n\nSend `test_name` to run a single test rather than the whole suite, and `iterations` to run it\nrepeatedly - the same scenario played more than once, which is how a flaky agent is caught.\n\n**One run at a time per account**, and the conversations happen elsewhere in the deployment rather\nthan here: an already-running run, an empty suite, or that part of the deployment being unreachable\nare all reported as a **400** with the reason in `detail`. A **504** means the request was\naccepted for delivery and nothing answered - retry it.\n\nThis operation deliberately asks only for a **READ** role - running tests changes no configuration.","operationId":"run_test","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string","title":"Test Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartTestModel"}}}},"responses":{"200":{"description":"The run that has just started","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunStarted"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"504":{"description":"Whatever was asked to carry the action out never answered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tests/{test_id}":{"get":{"tags":["Test Suites"],"summary":"Get a test run","description":"Get results for one run: where it has got to, and what each test did.\n\n`test_id` here is a **run** id - the one `start` returned - not a suite id. This is the endpoint to\npoll while a run is in progress: `test_status` moves from `running` to `completed` or `cancelled`,\n`completion_status` carries the same state with a percentage for display, and the three totals\nbuild up as tests finish.\n\n`tests` holds the per-test outcomes, each with the judging model's reasoning - which is where a\nfailure is explained. The listing omits it and reports only the totals.\n\nA run this deployment has no record of answers **404**; one that finished carries its stored record, so\nresults outlive the run.","operationId":"get_test_status","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string","title":"Test Id"}}],"responses":{"200":{"description":"The run, with each test's outcome","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunStatus"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Test Suites"],"summary":"Cancel a test run","description":"Stop a run that is still going. **Nothing is deleted** - despite the method, the run's record\nand the results of whatever finished before the stop are kept, and the run ends up `cancelled`\nrather than gone.\n\nCancellation is **requested, not immediate**: the response confirms the request, and the run\nsettles a moment later. Poll `GET /tests/{test_id}` to see it land.\n\nOnly a run in progress can be cancelled - one that already finished, or that this deployment holds\nno record of, is a **404**. As with `start`, the work happens elsewhere in the deployment: that part\nbeing unreachable is a **400**, and a **504** means nothing answered in time. The run may still be\ngoing after a **504**, so read its status rather than assuming either way.\n\nLike `start`, this asks only for a **READ** role.","operationId":"delete_test","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string","title":"Test Id"}}],"responses":{"200":{"description":"Confirmation that cancellation was requested","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunCancelled"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"504":{"description":"Whatever was asked to carry the action out never answered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tests":{"get":{"tags":["Test Suites"],"summary":"List test runs","description":"List every test run - the history, not the suite definitions.\n\nA row carries the totals but not the per-test outcomes; read one back with `GET /tests/{test_id}` for\nthose. `name` is the suite's name **as it was when the run happened**, so a renamed or deleted\nsuite still reads sensibly here.\n\nLike the other time-series listings this one is paged and defaults to 100 rows, capped\nat 200; a `limit` outside 1-200 falls back to the default rather than being rejected.","operationId":"get_tests","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"filter","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `agent=support` or `(agent=support,start_time>=2026-01-01T00:00:00Z)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `agent=support;billing`.\n\nThis collection can be filtered by `start_time`, `agent`.","examples":["agent=support","agent=support,start_time>=2026-01-01T00:00:00Z","agent=support;billing"],"title":"Filter"},"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `agent=support` or `(agent=support,start_time>=2026-01-01T00:00:00Z)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `agent=support;billing`.\n\nThis collection can be filtered by `start_time`, `agent`."},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"Field to sort by, prefixed with `-` for descending. If not specified, the newest come first. A field this collection cannot be sorted by falls back to that default rather than being rejected.\n\nThis collection can be sorted by `start_time`, `agent`.","examples":["-start_time"],"default":"-start_time","title":"Sort"},"description":"Field to sort by, prefixed with `-` for descending. If not specified, the newest come first. A field this collection cannot be sorted by falls back to that default rather than being rejected.\n\nThis collection can be sorted by `start_time`, `agent`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Maximum number of items to return, 1..200. Anything outside that range falls back to 100 rather than being rejected.","examples":[100],"default":100,"title":"Limit"},"description":"Maximum number of items to return, 1..200. Anything outside that range falls back to 100 rather than being rejected."},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned.","examples":[1],"title":"Page"},"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned."}],"responses":{"200":{"description":"A page of runs, newest first","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/flows":{"post":{"tags":["Flows"],"summary":"Create a flow","description":"Create a flow: the deterministic alternative to an agent, a state machine of nodes rather\nthan a prompt.\n\n**This creates the flow, not its nodes.** A new flow is empty and cannot run a conversation\nuntil it has at least one node and a `start_widget` pointing at it - both through\n`POST /flows/{flow_id}/widgets` and the `start` node.\n\n`name` is the only required field. `llm` may be left out, in which case the account's default\nmodel is used; set it to the literal `none` for a flow with no model at all, which restricts\nconversation nodes to reading fixed text (`say`) rather than generating replies. `prompt`,\n`temperature` and `max_tokens` apply to whichever nodes do call the model.\n\nRejected with a **400**: a duplicate name, and the account's flow cap.","operationId":"create_flow","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowModel"}}}},"responses":{"201":{"description":"The created flow, with no nodes yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Flows"],"summary":"List flows","description":"List all flows.\n\nRows are a projection for a list view: the name, the model, and how many nodes the flow holds.\nRead one back with `GET /flows/{flow_id}` for its configuration, and `GET /flows/{flow_id}/widgets` for the nodes themselves.","operationId":"get_flows","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"filter","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `name~billing` or `(name~billing,llm~gpt)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `name=billing;support`.\n\nThis collection can be filtered by `name`, `description`, `llm`.","examples":["name~billing","name~billing,llm~gpt","name=billing;support"],"title":"Filter"},"description":"Narrow the result set. Each value is a comma-separated list of `field<op>value` terms, optionally wrapped in parentheses, e.g. `name~billing` or `(name~billing,llm~gpt)`. Operators: `~` contains (case-insensitive, text fields), `=` equals, `!=` differs, and `<` `>` `<=` `>=` compare numbers and ISO-8601 timestamps. `=` and `!=` also take a `;`-separated set, e.g. `name=billing;support`.\n\nThis collection can be filtered by `name`, `description`, `llm`."},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `llm`, `widgets_count`.","examples":["-name"],"title":"Sort"},"description":"Field to sort by, prefixed with `-` for descending. If not specified, `name` is used. The sort spans the whole filtered set rather than the page, and a field this endpoint cannot sort by leaves the order untouched.\n\nThis collection can be sorted by `name`, `llm`, `widgets_count`."},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum number of items to return. If not specified, all of them are returned.","examples":[50],"title":"Limit"},"description":"Maximum number of items to return. If not specified, all of them are returned."},{"name":"page","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned.","examples":[1],"title":"Page"},"description":"1-based page number, applied together with `limit`. If not specified, the first page is returned."}],"responses":{"200":{"description":"A page of flows","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/flows/{flow_id}":{"get":{"tags":["Flows"],"summary":"Get a flow","description":"Read flow configuration.\n\n**The nodes are not in it.** They are a sub-resource: `GET /flows/{flow_id}/widgets` lists them,\nand `start_widget` here is the id of the one the conversation begins at.\n\nWebhook secrets come back masked; echoing a mask back on update keeps the stored secret.","operationId":"get_flow","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"flow_id","in":"path","required":true,"schema":{"type":"string","title":"Flow Id"}}],"responses":{"200":{"description":"The flow, with its conversation URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowDetail"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Flows"],"summary":"Update a flow","description":"Update a flow's configuration. Every field is optional - omit one and its stored value is\nkept. This does not touch the nodes; each is edited through its own endpoint.\n\n**`advanced_config` is the exception: sending it replaces every advanced key at once.** Omit it\nand the stored advanced configuration is left alone. So reading a flow, editing one advanced key\nand sending the whole object back is safe; sending a hand-built `advanced_config` is not.\n\n`start_widget` is a node **id**, not a name.\n\nWebhook secrets follow the usual rule: a masked value echoed back means unchanged, a real value\nreplaces, an empty string clears.","operationId":"update_flow","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"flow_id","in":"path","required":true,"schema":{"type":"string","title":"Flow Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowUpdateModel"}}}},"responses":{"200":{"description":"The updated flow","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Flows"],"summary":"Delete a flow","description":"Delete a flow, every node in it and its version history.\n\nA flow created from a quickstart also deletes every document,\ntool and post call analysis created alongside it.\n\nTools, documents, post-call analyses and agents the flow's nodes merely referenced are shared\nentities and stay.","operationId":"delete_flow","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"flow_id","in":"path","required":true,"schema":{"type":"string","title":"Flow Id"}}],"responses":{"204":{"description":"No content"},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/flows/{flow_id}/clone":{"post":{"tags":["Flows"],"summary":"Clone a flow","description":"Copy a flow whole: its configuration, every node, and the canvas layout.\n\nThe copy is named `clone <original>`, or `clone-1 <original>` and upwards where that is taken,\nand takes no request body. **Every node gets a new id, and the references between them are\nrewritten to match** - transitions, `next_widget`, `skip_widget`, `else_widget`,\n`failed_widget` and the flow's own `start_widget` - so the copy is a working flow rather than one\npointing back at the original's nodes.\n\nReferences out of the flow are copied as they are: the copy calls the same tools and hands off to\nthe same agents. Nothing references the copy, so a conversation has to be started on it\ndirectly, or an agent pointed at it.","operationId":"clone_flow","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"flow_id","in":"path","required":true,"schema":{"type":"string","title":"Flow Id"}}],"responses":{"201":{"description":"The new copy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/flows/{flow_id}/widgets":{"post":{"tags":["Flows"],"summary":"Create a flow node","description":"Add a node to a flow.\n\n**`data.flavor` decides everything else.** It picks which variant `data` has to satisfy - a\n`conversation` node's text and transitions, an `api` node's URL and method, a `condition` node's\nexpressions - and it cannot be changed afterwards; a node of the wrong type has to be deleted and\nremade. The variant schemas below say what each accepts.\n\n**Nodes point at each other by id, never by name**, so a node cannot be wired up in the same\nrequest that creates it: create the targets first, then set `next_widget` / `transitions[].widget`\non the nodes that lead to them. Names are used for the entities *outside* the flow that a node\nreaches - `tool`, `agent`, `flow`, `documents` - and a name matching nothing is stored empty.\n\nThe new node is also placed on the flow's canvas, so a client that never touches the canvas\nendpoints still gets a usable layout. Adding a node does not make it reachable: the flow's\n`start_widget`, or some other node's transition, has to point at it.\n\nAn unknown `flow_id` is a **400**, not a **404** - the flow is payload here rather than the entity\nbeing addressed.","operationId":"create_widget","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"flow_id","in":"path","required":true,"schema":{"type":"string","title":"Flow Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowWidgetModel"}}}},"responses":{"201":{"description":"The created node","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WidgetResponse"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Flows"],"summary":"List a flow's nodes","description":"List every node of a flow.\n\nTwo things to know before reading a row:\n\n* **The first entry is not a real node.** `start` is synthesized from the flow's own\n  `start_widget`, carries the **flow's** id, and exists so the canvas has an entry point to draw\n  an edge from. Nothing stores it, and it is the one node that cannot be deleted.\n* **A row is flatter than the node itself.** A subset of the node's `data` keys is lifted to the\n  top level here, where `get_widget` returns them nested under `data`. Only a subset, so a row is\n  enough to draw the graph but not to edit a node - read it back with `get_widget` for that.\n\n`agent`, `tool` and `flow` on a row are names; everything pointing at another node - `next_widget`,\n`skip_widget`, `else_widget`, `failed_widget`, `transitions[].widget` - is an id.","operationId":"get_widgets","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"flow_id","in":"path","required":true,"schema":{"type":"string","title":"Flow Id"}}],"responses":{"200":{"description":"Every node of the flow, start node first","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WidgetList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/flows/{flow_id}/widgets/{widget_id}":{"get":{"tags":["Flows"],"summary":"Get a flow node","description":"Read one node in full - everything the listing leaves out, nested under `data` as the write\nendpoints take it.\n\n**Passing the flow's own id as `widget_id` returns the synthesized `start` node**, which is how\nthat node is addressed. It answers a smaller object: an id, the name `start`, and where the\nconversation begins.\n\nSettings a node does not store come back at the value the runtime would use, so this is the\nnode's effective configuration - which is what makes the object safe to edit and send back.\nSecrets in an `api` node's authentication come back masked, and a mask echoed back is understood\nas unchanged.","operationId":"get_widget","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"flow_id","in":"path","required":true,"schema":{"type":"string","title":"Flow Id"}},{"name":"widget_id","in":"path","required":true,"schema":{"type":"string","title":"Widget Id"}}],"responses":{"200":{"description":"The node, with its behaviour under `data`","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/WidgetResponse"},{"$ref":"#/components/schemas/StartWidgetResponse"}],"title":"Response 200 Get Widget"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Flows"],"summary":"Update a flow node","description":"Update a node. **`data` merges by key rather than replacing**: send only the keys you are\nchanging and the rest of the node stands.\n\n**Every update carries `data`, and `data.flavor` has to match what the node already is** - a\ndifferent flavor is a **400**, and so is a request with no `data` at all, even one that only\nrenames the node. A node cannot change type.\n\n**Setting the flow's entry point goes through here too**, with the flow's own id as `widget_id`\nand `data.flavor` of `start`: `data.next_widget` then becomes the flow's `start_widget`. That\nrequest writes to the flow, not to any node, and answers with the synthesized start node.\n\nIds inside `transitions`, `expressions` and `variables` are generated where a new entry arrives\nwithout one, so a client can append an entry without inventing an id. Referenced tools, agents and\nflows are named; other nodes are referenced by id.","operationId":"update_widget","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"flow_id","in":"path","required":true,"schema":{"type":"string","title":"Flow Id"}},{"name":"widget_id","in":"path","required":true,"schema":{"type":"string","title":"Widget Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowWidgetUpdateModel"}}}},"responses":{"200":{"description":"The updated node","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/WidgetResponse"},{"$ref":"#/components/schemas/StartWidgetResponse"}],"title":"Response 200 Update Widget"}}}},"400":{"description":"The request was understood but rejected - an invalid payload, a duplicate name, or a reference to an entity that does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Flows"],"summary":"Delete a flow node","description":"Remove a node from a flow.\n\n**Every reference to the node goes with it.** A transition that pointed here is emptied rather\nthan dropped, so the branch stays and its condition survives for you to point somewhere else;\na `next_widget`, `failed_widget`, `skip_widget` or `else_widget` naming this node is cleared,\nas is the flow's `start_widget` if this was the entry point. The node also leaves the flow's\ncanvas layout.\n\nThe synthesized `start` node cannot be deleted - it is not stored, so its id (the flow's) matches\nno node and answers **404**.","operationId":"delete_widget","security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}],"parameters":[{"name":"flow_id","in":"path","required":true,"schema":{"type":"string","title":"Flow Id"}},{"name":"widget_id","in":"path","required":true,"schema":{"type":"string","title":"Widget Id"}}],"responses":{"204":{"description":"No content"},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"404":{"description":"No entity with the id named in the URL exists in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/info/models":{"get":{"tags":["Info"],"summary":"List pre-deployed models","description":"List the pre-deployed models.\nReference one by its `name` from an agent, a flow or a post-call analysis.\n\nThese are not the models under `/models`, which are the ones this account defines itself\nagainst its own provider credentials, and they cannot be created, edited or deleted. Which\nmodels are deployed is a property of the deployment, so the list differs between them and\nchanges as models are added and retired.\n\nEach entry contains information that helps to choose between them: whether it is speech-to-speech\nor text model, its measured response latency, its published token prices and its Artificial Analysis\nscore.\n\nLiveHub offers a handful of pre-deployed models, so the whole set comes back at once: no `filter`,\n`sort`, `limit` or `page`.","operationId":"get_predeployed_models","responses":{"200":{"description":"Every model this deployment provides","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredeployedModelList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}}},"security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}]}},"/api/v1/info/tools":{"get":{"tags":["Info"],"summary":"List pre-defined tools","description":"List the pre-defined tools - ending a call, transferring it, handing over to\nanother agent, reading the clock. Reference one from an agent's or a node's tools by name\nalone: `{\"tool\": \"end_call\"}`, where a tool this account defines takes `{\"tool\": \"custom\",\n\"tool_id\": \"<name>\"}`.\n\nThey are not stored entities and do not appear under `/tools`; a name here is therefore\nalso a name no custom tool may take. The document tools an agent gets from the documents\nattached to it - `doc_search` and its companions - are not listed here either, as an agent\ndoes not reference those itself.\n\nA tool that carries a `deprecation_notice` still works; the notice says what to use in\nits place.\n\nWhat a tool takes and how it behaves is described per tool in the LiveHub documentation.\nThe whole set comes back at once: no `filter`, `sort`, `limit` or `page`.","operationId":"get_predefined_tools","responses":{"200":{"description":"Every tool the platform provides","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredefinedToolList"}}}},"401":{"description":"Missing, malformed or expired bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}},"403":{"description":"The token does not carry the role this operation requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}}}},"security":[{"HTTPBearer":[]},{"OAuth2ClientCredentials":[]}]}}},"components":{"schemas":{"ActiveListeningModel":{"properties":{"hypothesis_interval_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hypothesis Interval Ms","description":"Minimum time between hypotheses in milliseconds"},"logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Logs","description":"Write an active_listening log entry when a pre-generated response is consumed (default: enabled)"},"max_parallel":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Parallel","description":"Maximum number of parallel response generations"},"mode":{"type":"string","enum":["disabled","every_hypothesis","end_of_sentence","eager_end_of_turn"],"title":"Mode","description":"Active listening mode"},"similarity_threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Similarity Threshold","description":"Similarity threshold between final recognition and last hypothesis (0.0 to 1.0)"}},"type":"object","required":["mode"],"title":"ActiveListeningModel"},"AgentAssistModel":{"properties":{"change_volume_tool":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Change Volume Tool","description":"Interactive mode: expose a \"change_volume\" tool that adjusts the audio volume between customer and agent"},"default_player":{"anyOf":[{"type":"string","enum":["customer","agent","all","none"]},{"type":"null"}],"title":"Default Player","description":"Interactive mode: player used for a plain free-text LLM response; \"none\" (default) discards it"},"mode":{"anyOf":[{"type":"string","enum":["active","passive","transcript","interactive"]},{"type":"null"}],"title":"Mode","description":"Agent assist mode: \"active\" relays LLM responses, \"passive\" analysis only, \"transcript\" relays STT, \"interactive\" plays audio via players"},"no_response_phrases":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"No Response Phrases","description":"List of phrases that indicate that assistant has nothing to say"},"play_activity_params":{"anyOf":[{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object"},{"type":"null"}],"title":"Play Activity Params","description":"Interactive mode: static activityParams merged into a played message, keyed by player name (\"customer\", \"agent\" or \"all\")"},"play_tool_params":{"anyOf":[{"items":{"$ref":"#/components/schemas/AgentAssistPlayToolParamModel"},"type":"array"},{"type":"null"}],"title":"Play Tool Params","description":"Interactive mode: extra parameters exposed on the play tools; each supplied value is written to the message activityParams (e.g. tts_language)"},"players":{"anyOf":[{"items":{"$ref":"#/components/schemas/AgentAssistPlayerModel"},"type":"array"},{"type":"null"}],"title":"Players","description":"Interactive mode: audio players the agent can play to; if not set, default \"customer\" and \"agent\" players are created"},"transcript":{"anyOf":[{"type":"string","enum":["none","user","both"]},{"type":"null"}],"title":"Transcript","description":"Relay this session's STT transcript to the matching regular call: \"user\" = user side, \"both\" = user and agent, \"none\" = off. Implied \"user\" in \"transcript\" mode"},"transport":{"anyOf":[{"type":"string","enum":["webhook","metadata"]},{"type":"null"}],"title":"Transport","description":"How to send assistant response in active mode"},"trigger_words":{"anyOf":[{"items":{"$ref":"#/components/schemas/AgentAssistTriggerWordModel"},"type":"array"},{"type":"null"}],"title":"Trigger Words","description":"Specific words in user utterance that trigger assistant response"}},"type":"object","title":"AgentAssistModel"},"AgentAssistPlayToolParamModel":{"properties":{"activity_param_name":{"type":"string","title":"Activity Param Name","description":"Key the parameter value is written to in the message activityParams"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Parameter description shown to the LLM"},"name":{"type":"string","title":"Name","description":"Parameter name exposed to the LLM on the play tools"},"required":{"type":"boolean","title":"Required","description":"Whether the LLM must provide the parameter","default":true},"type":{"type":"string","enum":["str","int","bool","float"],"title":"Type","description":"Parameter type","default":"str"},"values":{"anyOf":[{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array"},{"type":"null"}],"title":"Values","description":"Allowed values (enum); supported for \"str\" and \"int\" types"}},"type":"object","required":["name","activity_param_name"],"title":"AgentAssistPlayToolParamModel"},"AgentAssistPlayerModel":{"properties":{"targets":{"items":{"$ref":"#/components/schemas/AgentAssistPlayerTargetModel"},"type":"array","maxItems":2,"title":"Targets","description":"Participants this player plays to (up to 2); the player name is deduced from the targets as \"customer\", \"agent\" or \"all\""}},"type":"object","required":["targets"],"title":"AgentAssistPlayerModel"},"AgentAssistPlayerTargetModel":{"properties":{"barge_in":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Barge In","description":"Allow this participant to barge in (interrupt playback)"},"gain_db":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gain Db","description":"Playback gain (in dB) applied for this participant"},"participant":{"type":"string","enum":["customer","agent"],"title":"Participant","description":"Participant this player plays audio to"}},"type":"object","required":["participant"],"title":"AgentAssistPlayerTargetModel"},"AgentAssistTriggerWordModel":{"properties":{"participant":{"anyOf":[{"type":"string","enum":["customer","agent"]},{"type":"null"}],"title":"Participant","description":"Participant whose utterance will be checked"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text","description":"Words that trigger the assistant response"}},"type":"object","title":"AgentAssistTriggerWordModel"},"AgentConfigAdvancedModel":{"properties":{"active_listening":{"anyOf":[{"$ref":"#/components/schemas/ActiveListeningModel"},{"type":"null"}],"description":"Generate LLM responses based on STT hypotheses"},"activity_params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Activity Params","description":"Bot Connection configuration parameters for each activity"},"agent_assist":{"anyOf":[{"$ref":"#/components/schemas/AgentAssistModel"},{"type":"null"}],"description":"Configuration for agent assist mode"},"agent_flavor":{"anyOf":[{"$ref":"#/components/schemas/AgentFlavor"},{"type":"null"}],"description":"Agent flavor"},"call_recording":{"anyOf":[{"$ref":"#/components/schemas/CallRecording"},{"type":"null"}],"description":"Call recording configuration"},"call_transfer_conditions":{"anyOf":[{"items":{"$ref":"#/components/schemas/CallTransferConditionModel"},"type":"array"},{"type":"null"}],"title":"Call Transfer Conditions","description":"Conditions for call transfer"},"customize_tools":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/ToolCustomizeModel"},"type":"object"},{"type":"null"}],"title":"Customize Tools","description":"Custom tools configuration"},"doc_content_len":{"anyOf":[{"type":"integer","maximum":200000.0,"minimum":1.0},{"type":"null"}],"title":"Doc Content Len","description":"Maximum length of document content to be used in \"Full content\" document modes"},"doc_tools":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/DocToolsConfigModel"},"propertyNames":{"enum":["doc_search","doc_get","doc_toc"]},"type":"object"},{"type":"null"}],"title":"Doc Tools","description":"Configuration for document tools"},"document_conditions":{"anyOf":[{"items":{"$ref":"#/components/schemas/DocumentConditionModel"},"type":"array"},{"type":"null"}],"title":"Document Conditions","description":"Filter documents available to the agent (RAG and document tools); available only if its condition is true; unlisted documents are always available"},"documents_mode":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/DocumentMode"},"type":"object"},{"type":"null"}],"title":"Documents Mode","description":"Per-document override of \"document_mode\"; key = document name, value = mode (rag / doc_search / prompt / doc_get). Documents not listed here inherit the agent-level \"document_mode\"."},"dynamic_prompt":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Dynamic Prompt","description":"Re-generate prompt after every user utterance"},"empty_llm_response":{"anyOf":[{"$ref":"#/components/schemas/EmptyLLMResponse"},{"type":"null"}],"description":"How to treat empty LLM response"},"end_call_detection":{"anyOf":[{"$ref":"#/components/schemas/EndCallDetectionModel"},{"type":"null"}],"description":"Detect end call by keywords"},"establish_llm_connection":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Establish Llm Connection","description":"Establish LLM connection during agent initilization"},"explicit_tool_errors":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Explicit Tool Errors","description":"Enable explicit errors in tool response to LLM"},"gemini_api":{"anyOf":[{"type":"string","enum":["openai","google"]},{"type":"null"}],"title":"Gemini Api","description":"API to be used for Gemini models: \"openai\" (OpenAI-compat, default) or \"google\" (native google-genai SDK)"},"gemini_audio":{"anyOf":[{"$ref":"#/components/schemas/GeminiAudioModel"},{"type":"null"}],"description":"Configuration for Gemini native audio model"},"grok_voice":{"anyOf":[{"$ref":"#/components/schemas/GrokVoiceModel"},{"type":"null"}],"description":"Configuration for Grok voice model"},"ignore_first_call_transfer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ignore First Call Transfer","description":"Message to be played if LLM tries to perform call transfer after first user utterance"},"inactivity_reminder":{"anyOf":[{"$ref":"#/components/schemas/InactivityReminderModel"},{"type":"null"}],"description":"Reminder sent to model when user is silent after model finished playing (speech-to-speech models; Gemini requires \"gemini_audio.vad_mode\" = \"silero\")"},"incomplete_turn":{"anyOf":[{"$ref":"#/components/schemas/IncompleteTurnModel"},{"type":"null"}],"description":"Let the model suppress its response when the user has not finished speaking (non-realtime models)"},"increment_counter_call_transfer":{"anyOf":[{"items":{"$ref":"#/components/schemas/IncrementCounterCallTransferModel"},"type":"array"},{"type":"null"}],"title":"Increment Counter Call Transfer","description":"Call transfer upon counter increment"},"increment_counter_conditions":{"anyOf":[{"items":{"$ref":"#/components/schemas/IncrementCounterConditionsModel"},"type":"array"},{"type":"null"}],"title":"Increment Counter Conditions","description":"Increment dynamic counters for specific user utterances or LLM responses"},"init_conditions":{"anyOf":[{"items":{"$ref":"#/components/schemas/InitConditionsModel"},"type":"array"},{"type":"null"}],"title":"Init Conditions","description":"Conditional agent initialization"},"init_tools":{"anyOf":[{"items":{"$ref":"#/components/schemas/InitToolModel"},"type":"array"},{"type":"null"}],"title":"Init Tools","description":"Tools to be run during agent initialization"},"init_tools_cancel":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Init Tools Cancel","description":"Cancel init tools after specified number of user utterances"},"language_detected":{"anyOf":[{"$ref":"#/components/schemas/LanguageDetectedModel"},{"type":"null"}],"description":"Pass question to another language upon language detection"},"llm_add_period":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Llm Add Period","description":"Add period at the end of LLM response if missing"},"llm_logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Llm Logs","description":"Enable LLM logs for troubleshooting (visible on the backend only)"},"llm_message_with_tool_call":{"anyOf":[{"type":"string","enum":["play","drop"]},{"type":"null"}],"title":"Llm Message With Tool Call","description":"How to handle the LLM text message that accompanies a (non-terminal) tool call: \"play\" (default) delivers it to the user, \"drop\" discards it. Non-streaming path only (streaming always plays it); ignored for call-control tools"},"llm_not_found":{"anyOf":[{"$ref":"#/components/schemas/LLMNotFound"},{"type":"null"}],"description":"What to do when the configured LLM name is not provisioned in the account: \"strict\" (default) fails; \"fallback\" uses any available model"},"llm_replace_words":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Llm Replace Words","description":"Words to be replaced in LLM response"},"llm_stream_first_sentence":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Llm Stream First Sentence","description":"Immediately play first sentence of LLM response"},"max_turns_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Max Turns Message","description":"Message to be played when max turns limit is reached"},"mcp_logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Mcp Logs","description":"Enable additional logs when calling MCP tools"},"multiple_progress_messages":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Multiple Progress Messages","description":"Multiple progress messages per user utterance"},"no_tool_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"No Tool Error","description":"Error message to be returned to LLM if it didn't call any tool; use only if you ALWAYS expect LLM to call tools - e.g. if you use \"play_url\" tool"},"nova_sonic":{"anyOf":[{"$ref":"#/components/schemas/NovaSonicModel"},{"type":"null"}],"description":"Configuration for Amazon Nova Sonic model"},"numbers_sequence":{"anyOf":[{"$ref":"#/components/schemas/NumbersSequenceModel"},{"type":"null"}],"description":"Process numbers sequence in user utterance - e.g. change \"line 500 29\" to \"line 529\""},"openai_api":{"anyOf":[{"type":"string","enum":["chat_completions","responses","responses_stateful"]},{"type":"null"}],"title":"Openai Api","description":"API to be used for OpenAI models"},"openai_realtime":{"anyOf":[{"$ref":"#/components/schemas/OpenAIRealtimeModel"},{"type":"null"}],"description":"Configuration for OpenAI realtime models"},"orchestration_mode":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/OrchestrationMode"},"type":"object"},{"type":"null"}],"title":"Orchestration Mode","description":"Orchestration mode for multi-agent deployment topologies"},"post_call_analysis":{"anyOf":[{"$ref":"#/components/schemas/PostCallAnalysisConfigModel"},{"type":"null"}],"description":"Configuration of post-call analysis behavior"},"prerecorded_audio":{"anyOf":[{"$ref":"#/components/schemas/PrerecordedAudioConfigModel"},{"type":"null"}],"description":"Play pre-recorded audio files instead of specific LLM responses"},"progress_message_conditions":{"anyOf":[{"items":{"$ref":"#/components/schemas/ProgressMessageConditionModel"},"type":"array"},{"type":"null"}],"title":"Progress Message Conditions","description":"Conditional progress messages"},"prompt_log":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Prompt Log","description":"Log the system prompt as a separate \"prompt\" entry in the conversation log - at the beginning of the conversation, and when a sub-agent is entered for the first time"},"rag_chunks":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rag Chunks","description":"Number of chunks to be used in \"RAG\" document modes"},"reasoning_effort":{"anyOf":[{"type":"string","enum":["none","minimal","low","medium","high"]},{"type":"null"}],"title":"Reasoning Effort","description":"Reasoning level for thinking models"},"reasoning_logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Reasoning Logs","description":"Enable reasoning logs for thinking models"},"remove_symbols":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Remove Symbols","description":"Symbols to be removed from user utterance"},"replace_words":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Replace Words","description":"Words to be replaced in user utterance"},"scripted":{"anyOf":[{"$ref":"#/components/schemas/ScriptedLLMModel"},{"type":"null"}],"description":"Scripted responses, used when agent_flavor=\"scripted\""},"send_metadata_init":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Send Metadata Init","description":"Relay the conversation identifiers to the connector as a \"sendMetaData\" event at the beginning of the conversation"},"send_metadata_tools":{"anyOf":[{"items":{"$ref":"#/components/schemas/SendMetadataToolModel"},"type":"array"},{"type":"null"}],"title":"Send Metadata Tools","description":"Tools that can be called by LLM to send a \"sendMetaData\" event with a predefined metadata payload"},"send_metadata_transcript":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Send Metadata Transcript","description":"Relay the conversation transcript (user and assistant utterances) to the connector as \"sendMetaData\" events"},"session_params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Session Params","description":"Bot Connection configuration parameters for the session"},"session_params_tools":{"anyOf":[{"items":{"$ref":"#/components/schemas/SessionParamsToolModel"},"type":"array"},{"type":"null"}],"title":"Session Params Tools","description":"Tools that can be called by LLM to change the session parameters"},"session_reminders":{"anyOf":[{"items":{"$ref":"#/components/schemas/SessionReminderModel"},"type":"array"},{"type":"null"}],"title":"Session Reminders","description":"Reminders to be sent to the LLM after specified session duration"},"silero_vad":{"anyOf":[{"$ref":"#/components/schemas/SileroVadModel"},{"type":"null"}],"description":"Configuration for Silero VAD"},"tool_certs":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Tool Certs","description":"Custom certificates for tools calls; key = tool name, value = name of document containing the certificates"},"tool_logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Tool Logs","description":"Enable tool call logs for troubleshooting"},"transfer_call_sip_headers":{"anyOf":[{"items":{"$ref":"#/components/schemas/SipHeadersModel"},"type":"array"},{"type":"null"}],"title":"Transfer Call Sip Headers","description":"List of SIP headers to be added to the call transfer request"},"tts_stream":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Tts Stream","description":"If enabled, the LLM response will be streamed to the TTS engine"},"webchat_config":{"anyOf":[{"$ref":"#/components/schemas/WebChatConfigModel"},{"type":"null"}],"description":"Webchat configuration"},"welcome_message_activity_params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Welcome Message Activity Params","description":"Bot Connection configuration parameters for the welcome message activity"},"welcome_message_barge_in":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Welcome Message Barge In","description":"Configure barge-in during welcome message playback"},"welcome_message_delay":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Welcome Message Delay","description":"Delay in milliseconds before playing the welcome message"},"welcome_message_parts":{"anyOf":[{"items":{"$ref":"#/components/schemas/WelcomeMessagePartModel"},"type":"array"},{"type":"null"}],"title":"Welcome Message Parts","description":"Configure multi-part welcome message with barge-in control per part"}},"type":"object","title":"AgentConfigAdvancedModel"},"AgentDetail":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the agent"},"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/AgentConfigAdvancedModel"},{"type":"null"}],"description":"Configuration with no dedicated field of its own. Absent when the agent has none set"},"agents":{"items":{"type":"string"},"type":"array","title":"Sub-agents","description":"Sub-agents that this agent can communicate with"},"api_url":{"type":"string","title":"Api Url","description":"Where a client starts an HTTP conversation with this agent"},"description":{"type":"string","title":"Description","description":"Agent description","default":""},"doc_tool_mode":{"$ref":"#/components/schemas/DocToolMode","description":"Document tool mode","default":"regular"},"document_mode":{"$ref":"#/components/schemas/DocumentMode","title":"Use documents","description":"Mode for working with documents","default":"doc_search"},"documents":{"items":{"type":"string"},"type":"array","title":"Documents","description":"Documents that can be used by the agent"},"error_message":{"type":"string","title":"Error message","description":"Mesage to be played if LLM response couldn't be generated due to some error","default":""},"flows":{"items":{"type":"string"},"type":"array","title":"Sub-flows","description":"Sub-flows that this agent can communicate with"},"id":{"type":"string","title":"Id","description":"Unique agent id"},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used by the agent.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence or speech-to-speech index (from artificialanalysis.ai)"},"logs":{"anyOf":[{"type":"string","enum":["enabled","disabled","masked"]},{"type":"null"}],"title":"Logs","description":"Logging level for the agent","default":"enabled"},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max output tokens","description":"Maximum number of tokens in LLM response","default":1000},"max_turns":{"type":"integer","maximum":500.0,"minimum":1.0,"title":"Max utterances","description":"Maximum number of turns (user utterance / LLM response) in the conversation","default":50},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Agent name"},"orchestration_mode":{"$ref":"#/components/schemas/OrchestrationMode","title":"Orchestration mode","description":"Orchestration mode for multi-agent deployment topologies","default":"delegate"},"post_call_analysis":{"items":{"type":"string"},"type":"array","title":"Post call analysis","description":"Post call analysis tools to be run at the end of the conversation"},"progress_message":{"type":"string","title":"Progress message","description":"Progress message to be played if LLM response takes too long","default":""},"progress_timeout":{"type":"integer","maximum":30000.0,"minimum":1.0,"title":"Progress message timeout (msec)","description":"Progress message timeout in milliseconds","default":2000},"prompt":{"type":"string","title":"Prompt","description":"System prompt that defines agent behavior. Use {...} to reference variables. Send an empty one and the agent runs on the platform's default prompt."},"prompt_history":{"items":{"type":"string"},"type":"array","title":"Prompt history","description":"Prompt history"},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"tools_config":{"items":{"oneOf":[{"$ref":"#/components/schemas/PassQuestionConfigModel"},{"$ref":"#/components/schemas/SendMessageConfigModel"},{"$ref":"#/components/schemas/EndCallConfigModel"},{"$ref":"#/components/schemas/TransferCallConfigModel"},{"$ref":"#/components/schemas/DialDtmfConfigModel"},{"$ref":"#/components/schemas/PlayUrlConfigModel"},{"$ref":"#/components/schemas/GetConversationDataConfigModel"},{"$ref":"#/components/schemas/GetTimeConfigModel"},{"$ref":"#/components/schemas/ConvertTimeConfigModel"},{"$ref":"#/components/schemas/ConvertMultipleTimesConfigModel"},{"$ref":"#/components/schemas/SetCounterConfigModel"},{"$ref":"#/components/schemas/GetCountersConfigModel"},{"$ref":"#/components/schemas/IncrementCounterConfigModel"},{"$ref":"#/components/schemas/CustomToolConfigModel"}],"discriminator":{"propertyName":"tool","mapping":{"convert_multiple_times":"#/components/schemas/ConvertMultipleTimesConfigModel","convert_time":"#/components/schemas/ConvertTimeConfigModel","custom":"#/components/schemas/CustomToolConfigModel","dial_dtmf":"#/components/schemas/DialDtmfConfigModel","end_call":"#/components/schemas/EndCallConfigModel","get_conversation_data":"#/components/schemas/GetConversationDataConfigModel","get_counters":"#/components/schemas/GetCountersConfigModel","get_time":"#/components/schemas/GetTimeConfigModel","increment_counter":"#/components/schemas/IncrementCounterConfigModel","pass_question":"#/components/schemas/PassQuestionConfigModel","play_url":"#/components/schemas/PlayUrlConfigModel","send_message":"#/components/schemas/SendMessageConfigModel","set_counter":"#/components/schemas/SetCounterConfigModel","transfer_call":"#/components/schemas/TransferCallConfigModel"}}},"type":"array","title":"Tools","description":"Configuration of tools that can be used by the agent"},"variables_str":{"type":"string","title":"Variables","description":"Variables that can be used in prompt and tools; use \"NAME = VALUE\" format, for example: \"name = John\"; use multiple lines to specify multiple variables","default":""},"webhooks":{"anyOf":[{"items":{"$ref":"#/components/schemas/WebhookModel"},"type":"array"},{"type":"null"}],"title":"Webhooks","description":"Webhooks to be called during the agent execution"},"websocket_url":{"type":"string","title":"Websocket Url","description":"Where a client opens a streaming conversation with this agent"},"welcome":{"$ref":"#/components/schemas/WelcomeModel","title":"Welcome message","description":"Welcome message configuration"}},"type":"object","required":["id","name","llm","prompt","account_id","api_url","websocket_url"],"title":"AgentDetail","description":"What reading one agent adds, and create, update and clone do not: the two URLs a client\nstarts a conversation on."},"AgentFlavor":{"type":"string","enum":["llm","echo","listen","say","scripted"],"title":"AgentFlavor"},"AgentList":{"properties":{"agents":{"items":{"$ref":"#/components/schemas/AgentListItem"},"type":"array","title":"Agents","description":"The requested page of agents, each group led by its top-level agent"},"total_count":{"type":"integer","title":"Total Count","description":"Rows matching the filter, across every page - not the number returned here","examples":[42]}},"type":"object","required":["total_count","agents"],"title":"AgentList"},"AgentListItem":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the agent"},"agents_count":{"type":"integer","title":"Agents Count","description":"Sub-agents the agent can hand off to"},"depth":{"type":"integer","title":"Depth","description":"How many hand-off levels below its top-level agent this row sits - 0 for a top-level agent itself"},"description":{"type":"string","title":"Description","description":"Agent description"},"documents_count":{"type":"integer","title":"Documents Count","description":"Documents attached to the agent"},"flows_count":{"type":"integer","title":"Flows Count","description":"Sub-flows the agent can hand off to"},"id":{"type":"string","title":"Id","description":"Unique agent id"},"is_realtime":{"type":"boolean","title":"Is Realtime","description":"Whether the agent runs on a speech-to-speech model"},"llm":{"type":"string","title":"Llm","description":"Name of the model the agent uses - resolved to the name, even where the agent stores a custom model by id","examples":["gpt-4o"]},"logo_url":{"type":"string","title":"Logo Url","description":"URL of the model provider's logo, served by this deployment"},"name":{"type":"string","title":"Name","description":"Agent name","examples":["support-triage"]},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Id of the agent this row hands off from - absent on a top-level agent"},"parent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Name","description":"Name of that parent agent"},"tools_count":{"type":"integer","title":"Tools Count","description":"Tools configured on the agent"},"top_level_id":{"type":"string","title":"Top Level Id","description":"Id of the top-level agent whose group this row belongs to"},"top_level_name":{"type":"string","title":"Top Level Name","description":"Name of that top-level agent"}},"type":"object","required":["id","account_id","name","description","llm","logo_url","is_realtime","tools_count","documents_count","agents_count","flows_count","depth","top_level_id","top_level_name"],"title":"AgentListItem","description":"One row of the agent listing - a projection, plus the fields that place the row in\nthe multi-agent hierarchy."},"AgentModel":{"properties":{"_id":{"type":"string","title":"Id","description":"Assigned when the entity is created; a create that sends one of its own is rejected","readOnly":true},"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/AgentConfigAdvancedModel"},{"type":"null"}],"description":"Advanced configuration parameters"},"agents":{"items":{"type":"string"},"type":"array","title":"Sub-agents","description":"Sub-agents that this agent can communicate with"},"description":{"type":"string","title":"Description","description":"Agent description","default":""},"doc_tool_mode":{"$ref":"#/components/schemas/DocToolMode","description":"Document tool mode","default":"regular"},"document_mode":{"$ref":"#/components/schemas/DocumentMode","title":"Use documents","description":"Mode for working with documents","default":"doc_search"},"documents":{"items":{"type":"string"},"type":"array","title":"Documents","description":"Documents that can be used by the agent"},"error_message":{"type":"string","title":"Error message","description":"Mesage to be played if LLM response couldn't be generated due to some error","default":""},"flows":{"items":{"type":"string"},"type":"array","title":"Sub-flows","description":"Sub-flows that this agent can communicate with"},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used by the agent.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence or speech-to-speech index (from artificialanalysis.ai)"},"logs":{"anyOf":[{"type":"string","enum":["enabled","disabled","masked"]},{"type":"null"}],"title":"Logs","description":"Logging level for the agent","default":"enabled"},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max output tokens","description":"Maximum number of tokens in LLM response","default":1000},"max_turns":{"type":"integer","maximum":500.0,"minimum":1.0,"title":"Max utterances","description":"Maximum number of turns (user utterance / LLM response) in the conversation","default":50},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Agent name"},"orchestration_mode":{"$ref":"#/components/schemas/OrchestrationMode","title":"Orchestration mode","description":"Orchestration mode for multi-agent deployment topologies","default":"delegate"},"post_call_analysis":{"items":{"type":"string"},"type":"array","title":"Post call analysis","description":"Post call analysis tools to be run at the end of the conversation"},"progress_message":{"type":"string","title":"Progress message","description":"Progress message to be played if LLM response takes too long","default":""},"progress_timeout":{"type":"integer","maximum":30000.0,"minimum":1.0,"title":"Progress message timeout (msec)","description":"Progress message timeout in milliseconds","default":2000},"prompt":{"type":"string","title":"Prompt","description":"System prompt that defines agent behavior. Use {...} to reference variables. Send an empty one and the agent runs on the platform's default prompt."},"prompt_history":{"items":{"type":"string"},"type":"array","title":"Prompt history","description":"Prompt history"},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"tools_config":{"items":{"oneOf":[{"$ref":"#/components/schemas/PassQuestionConfigModel"},{"$ref":"#/components/schemas/SendMessageConfigModel"},{"$ref":"#/components/schemas/EndCallConfigModel"},{"$ref":"#/components/schemas/TransferCallConfigModel"},{"$ref":"#/components/schemas/DialDtmfConfigModel"},{"$ref":"#/components/schemas/PlayUrlConfigModel"},{"$ref":"#/components/schemas/GetConversationDataConfigModel"},{"$ref":"#/components/schemas/GetTimeConfigModel"},{"$ref":"#/components/schemas/ConvertTimeConfigModel"},{"$ref":"#/components/schemas/ConvertMultipleTimesConfigModel"},{"$ref":"#/components/schemas/SetCounterConfigModel"},{"$ref":"#/components/schemas/GetCountersConfigModel"},{"$ref":"#/components/schemas/IncrementCounterConfigModel"},{"$ref":"#/components/schemas/CustomToolConfigModel"}],"discriminator":{"propertyName":"tool","mapping":{"convert_multiple_times":"#/components/schemas/ConvertMultipleTimesConfigModel","convert_time":"#/components/schemas/ConvertTimeConfigModel","custom":"#/components/schemas/CustomToolConfigModel","dial_dtmf":"#/components/schemas/DialDtmfConfigModel","end_call":"#/components/schemas/EndCallConfigModel","get_conversation_data":"#/components/schemas/GetConversationDataConfigModel","get_counters":"#/components/schemas/GetCountersConfigModel","get_time":"#/components/schemas/GetTimeConfigModel","increment_counter":"#/components/schemas/IncrementCounterConfigModel","pass_question":"#/components/schemas/PassQuestionConfigModel","play_url":"#/components/schemas/PlayUrlConfigModel","send_message":"#/components/schemas/SendMessageConfigModel","set_counter":"#/components/schemas/SetCounterConfigModel","transfer_call":"#/components/schemas/TransferCallConfigModel"}}},"type":"array","title":"Tools","description":"Configuration of tools that can be used by the agent"},"variables_str":{"type":"string","title":"Variables","description":"Variables that can be used in prompt and tools; use \"NAME = VALUE\" format, for example: \"name = John\"; use multiple lines to specify multiple variables","default":""},"webhooks":{"anyOf":[{"items":{"$ref":"#/components/schemas/WebhookModel"},"type":"array"},{"type":"null"}],"title":"Webhooks","description":"Webhooks to be called during the agent execution"},"welcome":{"$ref":"#/components/schemas/WelcomeModel","title":"Welcome message","description":"Welcome message configuration"}},"type":"object","required":["name","llm","prompt"],"title":"AgentModel"},"AgentResponse":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the agent"},"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/AgentConfigAdvancedModel"},{"type":"null"}],"description":"Configuration with no dedicated field of its own. Absent when the agent has none set"},"agents":{"items":{"type":"string"},"type":"array","title":"Sub-agents","description":"Sub-agents that this agent can communicate with"},"description":{"type":"string","title":"Description","description":"Agent description","default":""},"doc_tool_mode":{"$ref":"#/components/schemas/DocToolMode","description":"Document tool mode","default":"regular"},"document_mode":{"$ref":"#/components/schemas/DocumentMode","title":"Use documents","description":"Mode for working with documents","default":"doc_search"},"documents":{"items":{"type":"string"},"type":"array","title":"Documents","description":"Documents that can be used by the agent"},"error_message":{"type":"string","title":"Error message","description":"Mesage to be played if LLM response couldn't be generated due to some error","default":""},"flows":{"items":{"type":"string"},"type":"array","title":"Sub-flows","description":"Sub-flows that this agent can communicate with"},"id":{"type":"string","title":"Id","description":"Unique agent id"},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used by the agent.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence or speech-to-speech index (from artificialanalysis.ai)"},"logs":{"anyOf":[{"type":"string","enum":["enabled","disabled","masked"]},{"type":"null"}],"title":"Logs","description":"Logging level for the agent","default":"enabled"},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max output tokens","description":"Maximum number of tokens in LLM response","default":1000},"max_turns":{"type":"integer","maximum":500.0,"minimum":1.0,"title":"Max utterances","description":"Maximum number of turns (user utterance / LLM response) in the conversation","default":50},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Agent name"},"orchestration_mode":{"$ref":"#/components/schemas/OrchestrationMode","title":"Orchestration mode","description":"Orchestration mode for multi-agent deployment topologies","default":"delegate"},"post_call_analysis":{"items":{"type":"string"},"type":"array","title":"Post call analysis","description":"Post call analysis tools to be run at the end of the conversation"},"progress_message":{"type":"string","title":"Progress message","description":"Progress message to be played if LLM response takes too long","default":""},"progress_timeout":{"type":"integer","maximum":30000.0,"minimum":1.0,"title":"Progress message timeout (msec)","description":"Progress message timeout in milliseconds","default":2000},"prompt":{"type":"string","title":"Prompt","description":"System prompt that defines agent behavior. Use {...} to reference variables. Send an empty one and the agent runs on the platform's default prompt."},"prompt_history":{"items":{"type":"string"},"type":"array","title":"Prompt history","description":"Prompt history"},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"tools_config":{"items":{"oneOf":[{"$ref":"#/components/schemas/PassQuestionConfigModel"},{"$ref":"#/components/schemas/SendMessageConfigModel"},{"$ref":"#/components/schemas/EndCallConfigModel"},{"$ref":"#/components/schemas/TransferCallConfigModel"},{"$ref":"#/components/schemas/DialDtmfConfigModel"},{"$ref":"#/components/schemas/PlayUrlConfigModel"},{"$ref":"#/components/schemas/GetConversationDataConfigModel"},{"$ref":"#/components/schemas/GetTimeConfigModel"},{"$ref":"#/components/schemas/ConvertTimeConfigModel"},{"$ref":"#/components/schemas/ConvertMultipleTimesConfigModel"},{"$ref":"#/components/schemas/SetCounterConfigModel"},{"$ref":"#/components/schemas/GetCountersConfigModel"},{"$ref":"#/components/schemas/IncrementCounterConfigModel"},{"$ref":"#/components/schemas/CustomToolConfigModel"}],"discriminator":{"propertyName":"tool","mapping":{"convert_multiple_times":"#/components/schemas/ConvertMultipleTimesConfigModel","convert_time":"#/components/schemas/ConvertTimeConfigModel","custom":"#/components/schemas/CustomToolConfigModel","dial_dtmf":"#/components/schemas/DialDtmfConfigModel","end_call":"#/components/schemas/EndCallConfigModel","get_conversation_data":"#/components/schemas/GetConversationDataConfigModel","get_counters":"#/components/schemas/GetCountersConfigModel","get_time":"#/components/schemas/GetTimeConfigModel","increment_counter":"#/components/schemas/IncrementCounterConfigModel","pass_question":"#/components/schemas/PassQuestionConfigModel","play_url":"#/components/schemas/PlayUrlConfigModel","send_message":"#/components/schemas/SendMessageConfigModel","set_counter":"#/components/schemas/SetCounterConfigModel","transfer_call":"#/components/schemas/TransferCallConfigModel"}}},"type":"array","title":"Tools","description":"Configuration of tools that can be used by the agent"},"variables_str":{"type":"string","title":"Variables","description":"Variables that can be used in prompt and tools; use \"NAME = VALUE\" format, for example: \"name = John\"; use multiple lines to specify multiple variables","default":""},"webhooks":{"anyOf":[{"items":{"$ref":"#/components/schemas/WebhookModel"},"type":"array"},{"type":"null"}],"title":"Webhooks","description":"Webhooks to be called during the agent execution"},"welcome":{"$ref":"#/components/schemas/WelcomeModel","title":"Welcome message","description":"Welcome message configuration"}},"type":"object","required":["id","name","llm","prompt","account_id"],"title":"AgentResponse","description":"An agent as create, update and clone return it."},"AgentUpdateModel":{"properties":{"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/AgentConfigAdvancedModel"},{"type":"null"}],"description":"Advanced configuration parameters"},"agents":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Sub-agents","description":"Sub-agents that this agent can communicate with"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Agent description"},"doc_tool_mode":{"anyOf":[{"$ref":"#/components/schemas/DocToolMode"},{"type":"null"}],"description":"Document tool mode"},"document_mode":{"anyOf":[{"$ref":"#/components/schemas/DocumentMode"},{"type":"null"}],"title":"Use documents","description":"Mode for working with documents"},"documents":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Documents","description":"Documents that can be used by the agent"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error message","description":"Mesage to be played if LLM response couldn't be generated due to some error"},"flows":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Sub-flows","description":"Sub-flows that this agent can communicate with"},"llm":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Large language model","description":"Large language model (LLM) used by the agent.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence or speech-to-speech index (from artificialanalysis.ai)"},"logs":{"anyOf":[{"type":"string","enum":["enabled","disabled","masked"]},{"type":"null"}],"title":"Logs","description":"Logging level for the agent"},"max_tokens":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Max output tokens","description":"Maximum number of tokens in LLM response"},"max_turns":{"anyOf":[{"type":"integer","maximum":500.0,"minimum":1.0},{"type":"null"}],"title":"Max utterances","description":"Maximum number of turns (user utterance / LLM response) in the conversation"},"name":{"anyOf":[{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$"},{"type":"null"}],"title":"Name","description":"Agent name"},"orchestration_mode":{"anyOf":[{"$ref":"#/components/schemas/OrchestrationMode"},{"type":"null"}],"title":"Orchestration mode","description":"Orchestration mode for multi-agent deployment topologies"},"post_call_analysis":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Post call analysis","description":"Post call analysis tools to be run at the end of the conversation"},"progress_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Progress message","description":"Progress message to be played if LLM response takes too long"},"progress_timeout":{"anyOf":[{"type":"integer","maximum":30000.0,"minimum":1.0},{"type":"null"}],"title":"Progress message timeout (msec)","description":"Progress message timeout in milliseconds"},"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt","description":"System prompt that defines agent behavior. Use {...} to reference variables. Send an empty one and the agent runs on the platform's default prompt."},"temperature":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses"},"tools_config":{"anyOf":[{"items":{"oneOf":[{"$ref":"#/components/schemas/PassQuestionConfigModel"},{"$ref":"#/components/schemas/SendMessageConfigModel"},{"$ref":"#/components/schemas/EndCallConfigModel"},{"$ref":"#/components/schemas/TransferCallConfigModel"},{"$ref":"#/components/schemas/DialDtmfConfigModel"},{"$ref":"#/components/schemas/PlayUrlConfigModel"},{"$ref":"#/components/schemas/GetConversationDataConfigModel"},{"$ref":"#/components/schemas/GetTimeConfigModel"},{"$ref":"#/components/schemas/ConvertTimeConfigModel"},{"$ref":"#/components/schemas/ConvertMultipleTimesConfigModel"},{"$ref":"#/components/schemas/SetCounterConfigModel"},{"$ref":"#/components/schemas/GetCountersConfigModel"},{"$ref":"#/components/schemas/IncrementCounterConfigModel"},{"$ref":"#/components/schemas/CustomToolConfigModel"}],"discriminator":{"propertyName":"tool","mapping":{"convert_multiple_times":"#/components/schemas/ConvertMultipleTimesConfigModel","convert_time":"#/components/schemas/ConvertTimeConfigModel","custom":"#/components/schemas/CustomToolConfigModel","dial_dtmf":"#/components/schemas/DialDtmfConfigModel","end_call":"#/components/schemas/EndCallConfigModel","get_conversation_data":"#/components/schemas/GetConversationDataConfigModel","get_counters":"#/components/schemas/GetCountersConfigModel","get_time":"#/components/schemas/GetTimeConfigModel","increment_counter":"#/components/schemas/IncrementCounterConfigModel","pass_question":"#/components/schemas/PassQuestionConfigModel","play_url":"#/components/schemas/PlayUrlConfigModel","send_message":"#/components/schemas/SendMessageConfigModel","set_counter":"#/components/schemas/SetCounterConfigModel","transfer_call":"#/components/schemas/TransferCallConfigModel"}}},"type":"array"},{"type":"null"}],"title":"Tools","description":"Configuration of tools that can be used by the agent"},"variables_str":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variables","description":"Variables that can be used in prompt and tools; use \"NAME = VALUE\" format, for example: \"name = John\"; use multiple lines to specify multiple variables"},"webhooks":{"anyOf":[{"items":{"$ref":"#/components/schemas/WebhookModel"},"type":"array"},{"type":"null"}],"title":"Webhooks","description":"Webhooks to be called during the agent execution"},"welcome":{"anyOf":[{"$ref":"#/components/schemas/WelcomeModel"},{"type":"null"}],"title":"Welcome message","description":"Welcome message configuration"}},"type":"object","title":"AgentUpdateModel"},"ApiWidgetModel":{"properties":{"auth":{"$ref":"#/components/schemas/ToolAuthModel","title":"Authentication","description":"Authentication type"},"content":{"type":"string","title":"Content","description":"Request body. Use {...} to reference variables or parameters. If empty, all parameters not referenced in URL or Headers will be included.","default":""},"custom_llm":{"type":"boolean","title":"Custom LLM","description":"Choose a different LLM for this node","default":false},"discard_response":{"type":"boolean","title":"Discard response","description":"Discard the response from the conversation history","default":false},"extract_variables":{"type":"boolean","title":"Extract variables","description":"Extract variables from the response","default":false},"failed_widget":{"type":"string","title":"Failed","description":"Node to transition to if the request fails","default":""},"flavor":{"type":"string","const":"api","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"flow":{"type":"string","title":"Flow","description":"For \"flow\" type: the flow to run (referenced by name in the API, stored by id)","default":""},"global_condition":{"type":"string","title":"Global condition","description":"Describe conditions to transition to this node","default":""},"global_widget":{"type":"boolean","title":"Global node","description":"Allow other nodes to transition to this node without edges","default":false},"headers":{"type":"string","title":"Headers","description":"Request headers. Use {...} to reference variables or parameters. For example: \"api-version: {api_version}\"","default":""},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used by this node.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)","default":""},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max output tokens","description":"Maximum number of tokens in LLM response","default":1000},"method":{"type":"string","title":"Method","description":"HTTP method to use","default":"POST"},"next_widget":{"type":"string","title":"Success","description":"Node to transition to","default":""},"params":{"items":{"$ref":"#/components/schemas/ToolParamModel"},"type":"array","title":"Parameters","description":"Request parameters"},"response_len":{"type":"integer","title":"Max response length","description":"Maximum response length in bytes","default":100000},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"text":{"type":"string","title":"Text","description":"Message to be played before performing the request","default":""},"timeout":{"type":"integer","title":"Timeout (sec)","description":"Request timeout in seconds","default":10},"type":{"type":"string","enum":["rest","flow"],"title":"Type","description":"\"rest\" makes an HTTP request; \"flow\" runs a flow to completion","default":"rest"},"url":{"type":"string","title":"URL","description":"Request URL. Use {...} to reference variables or parameters.","default":""},"variables":{"items":{"$ref":"#/components/schemas/ExtractVariableModel"},"type":"array","title":"Variables","description":"List of variables to be extracted"},"wait_response":{"type":"boolean","title":"Wait for response","description":"Wait for the response before proceeding to next node","default":true}},"type":"object","required":["flavor"],"title":"ApiWidgetModel"},"ApiWidgetUpdateModel":{"properties":{"auth":{"anyOf":[{"$ref":"#/components/schemas/ToolAuthModel"},{"type":"null"}],"title":"Authentication","description":"Authentication type"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content","description":"Request body. Use {...} to reference variables or parameters. If empty, all parameters not referenced in URL or Headers will be included."},"custom_llm":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Custom LLM","description":"Choose a different LLM for this node"},"discard_response":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Discard response","description":"Discard the response from the conversation history"},"extract_variables":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Extract variables","description":"Extract variables from the response"},"failed_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failed","description":"Node to transition to if the request fails"},"flavor":{"type":"string","const":"api","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"flow":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flow","description":"For \"flow\" type: the flow to run (referenced by name in the API, stored by id)"},"global_condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Global condition","description":"Describe conditions to transition to this node"},"global_widget":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Global node","description":"Allow other nodes to transition to this node without edges"},"headers":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headers","description":"Request headers. Use {...} to reference variables or parameters. For example: \"api-version: {api_version}\""},"llm":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Large language model","description":"Large language model (LLM) used by this node.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)"},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"max_tokens":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Max output tokens","description":"Maximum number of tokens in LLM response"},"method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Method","description":"HTTP method to use"},"next_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Success","description":"Node to transition to"},"params":{"anyOf":[{"items":{"$ref":"#/components/schemas/ToolParamModel"},"type":"array"},{"type":"null"}],"title":"Parameters","description":"Request parameters"},"response_len":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max response length","description":"Maximum response length in bytes"},"temperature":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text","description":"Message to be played before performing the request"},"timeout":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Timeout (sec)","description":"Request timeout in seconds"},"type":{"anyOf":[{"type":"string","enum":["rest","flow"]},{"type":"null"}],"title":"Type","description":"\"rest\" makes an HTTP request; \"flow\" runs a flow to completion"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"URL","description":"Request URL. Use {...} to reference variables or parameters."},"variables":{"anyOf":[{"items":{"$ref":"#/components/schemas/ExtractVariableModel"},"type":"array"},{"type":"null"}],"title":"Variables","description":"List of variables to be extracted"},"wait_response":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Wait for response","description":"Wait for the response before proceeding to next node"}},"type":"object","required":["flavor"],"title":"ApiWidgetUpdateModel"},"BackupCreate":{"properties":{"agents":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Agents"},"documents":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Documents"},"flows":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Flows"},"models":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Models"},"post_call_analysis":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Post Call Analysis"},"resolve_dependencies":{"type":"boolean","title":"Resolve Dependencies","default":true},"tools":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tools"}},"type":"object","title":"BackupCreate"},"BackupExportPreview":{"properties":{"agents":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Agents"},"flows":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Flows"}},"type":"object","title":"BackupExportPreview"},"BackupPreview":{"properties":{"agents":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Agents","description":"Agents in scope"},"documents":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Documents","description":"Documents in scope"},"flows":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Flows","description":"Flows in scope"},"models":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Models","description":"Models in scope"},"post_call_analysis":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Post Call Analysis","description":"Post-call analyses in scope"},"tools":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Tools","description":"Tools in scope"}},"type":"object","title":"BackupPreview","description":"What an export or a restore would touch, before anything is written."},"BackupRestored":{"properties":{"agents":{"items":{"type":"string"},"type":"array","title":"Agents","description":"Agents created or overwritten"},"canvas":{"items":{"type":"string"},"type":"array","title":"Canvas","description":"Canvas layouts written alongside a restored flow"},"documents":{"items":{"type":"string"},"type":"array","title":"Documents","description":"Documents created or overwritten. Each is re-parsed afterwards, so its content lags the restore"},"flows":{"items":{"type":"string"},"type":"array","title":"Flows","description":"Flows created or overwritten"},"models":{"items":{"type":"string"},"type":"array","title":"Models","description":"Models created or overwritten"},"post_call_analysis":{"items":{"type":"string"},"type":"array","title":"Post Call Analysis","description":"Post-call analyses created or overwritten"},"tools":{"items":{"type":"string"},"type":"array","title":"Tools","description":"Tools created or overwritten"},"widgets":{"items":{"type":"string"},"type":"array","title":"Widgets","description":"Flow nodes written as part of a restored flow - they are the flow's own, not entities a client addresses directly"}},"type":"object","title":"BackupRestored","description":"Ids of everything a restore wrote, by type. A document listed here is re-parsing.\n\nA key is absent when the archive held nothing of that type, so an archive of one agent answers\nwith `agents` alone."},"BargeInModel":{"type":"string","enum":["inherit","enable","disable"],"title":"BargeInModel"},"Body_backup_restore":{"properties":{"file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"File"}},"type":"object","required":["file"],"title":"Body_backup_restore"},"Body_backup_restore_preview":{"properties":{"file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"File"}},"type":"object","required":["file"],"title":"Body_backup_restore_preview"},"Body_create_document_form":{"properties":{"name":{"type":"string","title":"Name","description":"Document name"},"description":{"type":"string","title":"Description","description":"Document description","default":""},"urls":{"type":"string","title":"URL","description":"List of URLs separated by newlines","default":""},"chunk_size":{"type":"integer","title":"Chunk size","description":"Desired chunk size in tokens","default":512},"overlap":{"type":"integer","title":"Overlap","description":"Overlap between chunks in tokens","default":64},"max_chunks":{"type":"integer","title":"Max chunks","description":"Maximum number of chunks","default":5000},"max_depth":{"type":"integer","title":"Max depth","description":"Maximum depth for URL crawling","default":0},"verify_ssl":{"type":"boolean","title":"Verify SSL","description":"Verify SSL certificates","default":true},"auto_refresh":{"type":"string","enum":["never","hourly","daily","weekly","monthly"],"title":"Auto refresh","description":"Auto refresh interval","default":"never"},"web_client":{"type":"string","enum":["standard","enhanced","advanced","auto"],"title":"Download client","description":"Client used for downloading and rendering web pages:\n- \"standard\" mode is the fastest and uses simple HTTP client\n- \"enhanced\" mode uses headless browser to render complete page including dynamic parts generated by Javascript code\n- \"advanced\" mode is the slowest one, but can overcome geo-location blocking and anti-robot protection\n- \"auto\" mode automatically selects the client based on the web page content","default":"auto"},"content_extraction":{"type":"string","enum":["main","clean","article","all"],"title":"Content extraction","description":"Content extraction method:\n- \"main\" extracts main content of the page, removing navigation, ads, and other irrelevant parts\n- \"clean\" is alternative version of main content extraction that often produces cleaner results but may accidentally remove some useful parts\n- \"article\" is optimized for extracting news articles and blog posts\n- \"all\" returns the full HTML content of the page","default":"main"},"max_urls":{"type":"integer","title":"Max URLs","description":"Maximum number of URLs to process","default":100},"follow_links":{"type":"string","enum":["direct","domain","subdomains","all"],"title":"Follow links","description":"What links to follow during crawling:\n- \"direct\" - follow only direct descendants of the crawled URL - e.g. for \"https://site.com/features\" download \"/features/1\", but not \"/pricing\"\n- \"domain\" - follow all links that belong to the same domain - e.g. for \"https://site.com/features\" download both \"/features/1\" and \"/pricing\"\n- \"subdomains\" - follow all links that belong to the same domain and its subdomains - e.g. for \"https://site.com\" download links under \"https://blog.site.com\" too\n- \"all\" - follow all links regardless of the domain","default":"direct"},"include_paths":{"type":"string","title":"Include Paths","description":"Include paths that match the specified regex, e.g. \"/blogs/.*\" downloads links under /blogs only. Multiple regexes may be specified separated by comma.","default":""},"exclude_paths":{"type":"string","title":"Exclude Paths","description":"Exclude paths that match the specified regex, e.g. \"/photos/.*\" excludes links under /photos. Multiple regexes may be specified separated by comma.","default":""},"sitemap":{"type":"string","enum":["include","skip","only"],"title":"Sitemap","description":"Whether to use URLs from sitemap (if available):\n- \"include\" - use both sitemap and inline HTML links\n- \"skip\" - ignore sitemap and use only inline HTML links\n- \"only\" - use sitemap only and ignore inline HTML links","default":"include"},"case_sensitive":{"type":"boolean","title":"Case-sensitive URL matching","description":"Use case-sensitive URL matching when crawling","default":true},"advanced_config":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Advanced configuration","description":"Advanced configuration as a JSON object, encoded as a string - e.g. `{\"pdf_parser\": {\"detect_tables\": false}}`. Sending it replaces the whole advanced configuration; omit the field to keep the stored one."},"file":{"anyOf":[{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array"},{"type":"null"}],"title":"Files","description":"The files to upload, as one `file` part per file - the field name is literally `file`, repeated: `-F file=@a.pdf -F file=@b.pdf`. Mutually exclusive with `urls`."}},"type":"object","required":["name"],"title":"Body_create_document_form"},"Body_import_test_suites":{"properties":{"file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"File"}},"type":"object","required":["file"],"title":"Body_import_test_suites"},"Body_update_document_form":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Document name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Document description"},"urls":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"URL","description":"List of URLs separated by newlines"},"chunk_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Chunk size","description":"Desired chunk size in tokens"},"overlap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Overlap","description":"Overlap between chunks in tokens"},"max_chunks":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max chunks","description":"Maximum number of chunks"},"max_depth":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max depth","description":"Maximum depth for URL crawling"},"verify_ssl":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Verify SSL","description":"Verify SSL certificates"},"auto_refresh":{"anyOf":[{"type":"string"},{"type":"null"}],"enum":["never","hourly","daily","weekly","monthly"],"title":"Auto refresh","description":"Auto refresh interval"},"web_client":{"anyOf":[{"type":"string"},{"type":"null"}],"enum":["standard","enhanced","advanced","auto"],"title":"Download client","description":"Client used for downloading and rendering web pages:\n- \"standard\" mode is the fastest and uses simple HTTP client\n- \"enhanced\" mode uses headless browser to render complete page including dynamic parts generated by Javascript code\n- \"advanced\" mode is the slowest one, but can overcome geo-location blocking and anti-robot protection\n- \"auto\" mode automatically selects the client based on the web page content"},"content_extraction":{"anyOf":[{"type":"string"},{"type":"null"}],"enum":["main","clean","article","all"],"title":"Content extraction","description":"Content extraction method:\n- \"main\" extracts main content of the page, removing navigation, ads, and other irrelevant parts\n- \"clean\" is alternative version of main content extraction that often produces cleaner results but may accidentally remove some useful parts\n- \"article\" is optimized for extracting news articles and blog posts\n- \"all\" returns the full HTML content of the page"},"max_urls":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max URLs","description":"Maximum number of URLs to process"},"follow_links":{"anyOf":[{"type":"string"},{"type":"null"}],"enum":["direct","domain","subdomains","all"],"title":"Follow links","description":"What links to follow during crawling:\n- \"direct\" - follow only direct descendants of the crawled URL - e.g. for \"https://site.com/features\" download \"/features/1\", but not \"/pricing\"\n- \"domain\" - follow all links that belong to the same domain - e.g. for \"https://site.com/features\" download both \"/features/1\" and \"/pricing\"\n- \"subdomains\" - follow all links that belong to the same domain and its subdomains - e.g. for \"https://site.com\" download links under \"https://blog.site.com\" too\n- \"all\" - follow all links regardless of the domain"},"include_paths":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Include Paths","description":"Include paths that match the specified regex, e.g. \"/blogs/.*\" downloads links under /blogs only. Multiple regexes may be specified separated by comma."},"exclude_paths":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exclude Paths","description":"Exclude paths that match the specified regex, e.g. \"/photos/.*\" excludes links under /photos. Multiple regexes may be specified separated by comma."},"sitemap":{"anyOf":[{"type":"string"},{"type":"null"}],"enum":["include","skip","only"],"title":"Sitemap","description":"Whether to use URLs from sitemap (if available):\n- \"include\" - use both sitemap and inline HTML links\n- \"skip\" - ignore sitemap and use only inline HTML links\n- \"only\" - use sitemap only and ignore inline HTML links"},"case_sensitive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Case-sensitive URL matching","description":"Use case-sensitive URL matching when crawling"},"advanced_config":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Advanced configuration","description":"Advanced configuration as a JSON object, encoded as a string - e.g. `{\"pdf_parser\": {\"detect_tables\": false}}`. Sending it replaces the whole advanced configuration; omit the field to keep the stored one."},"file_names":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Files to keep","description":"Comma-separated list of the document's existing file names to KEEP. The document ends up with exactly these plus whatever this request uploads - anything left out is deleted."},"file":{"anyOf":[{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array"},{"type":"null"}],"title":"Files","description":"The files to upload, as one `file` part per file - the field name is literally `file`, repeated: `-F file=@a.pdf -F file=@b.pdf`. Mutually exclusive with `urls`."}},"type":"object","title":"Body_update_document_form"},"CalculateWidgetModel":{"properties":{"expressions":{"items":{"$ref":"#/components/schemas/ExpressionModel"},"type":"array","title":"Expressions","description":"List of variable assignment expressions"},"flavor":{"type":"string","const":"calculate","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"type":"string","title":"Global condition","description":"Describe conditions to transition to this node","default":""},"global_widget":{"type":"boolean","title":"Global node","description":"Allow other nodes to transition to this node without edges","default":false},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"next_widget":{"type":"string","title":"Continue","description":"Node to transition to","default":""}},"type":"object","required":["flavor"],"title":"CalculateWidgetModel"},"CalculateWidgetUpdateModel":{"properties":{"expressions":{"anyOf":[{"items":{"$ref":"#/components/schemas/ExpressionModel"},"type":"array"},{"type":"null"}],"title":"Expressions","description":"List of variable assignment expressions"},"flavor":{"type":"string","const":"calculate","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Global condition","description":"Describe conditions to transition to this node"},"global_widget":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Global node","description":"Allow other nodes to transition to this node without edges"},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"next_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Continue","description":"Node to transition to"}},"type":"object","required":["flavor"],"title":"CalculateWidgetUpdateModel"},"CallRecording":{"type":"string","enum":["enable","stop_on_transfer","start_on_transfer"],"title":"CallRecording"},"CallTransferConditionModel":{"properties":{"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message","description":"Message to be played before the call transfer"},"patterns":{"items":{"type":"string"},"type":"array","title":"Patterns","description":"List of phrases in LLM response that trigger call transfer"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone","description":"Phone number to transfer the call to"},"threshold":{"type":"integer","title":"Threshold","description":"How many LLM responses that match the patterns are required to trigger call transfer; default = 1","default":1}},"type":"object","title":"CallTransferConditionModel"},"ConditionTransitionModel":{"properties":{"condition":{"type":"string","title":"Condition","description":"Enter logical expression, for example: \"age > 18\"","default":""},"id":{"type":"string","title":"Id"},"widget":{"type":"string","title":"Next node","description":"Node to transition to","default":""}},"type":"object","title":"ConditionTransitionModel"},"ConditionWidgetModel":{"properties":{"else_widget":{"type":"string","title":"Else","description":"Node to transition to if no conditions are met","default":""},"flavor":{"type":"string","const":"condition","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"type":"string","title":"Global condition","description":"Describe conditions to transition to this node","default":""},"global_widget":{"type":"boolean","title":"Global node","description":"Allow other nodes to transition to this node without edges","default":false},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"transitions":{"items":{"$ref":"#/components/schemas/ConditionTransitionModel"},"type":"array","title":"Transitions","description":"List of transitions"}},"type":"object","required":["flavor"],"title":"ConditionWidgetModel"},"ConditionWidgetUpdateModel":{"properties":{"else_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Else","description":"Node to transition to if no conditions are met"},"flavor":{"type":"string","const":"condition","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Global condition","description":"Describe conditions to transition to this node"},"global_widget":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Global node","description":"Allow other nodes to transition to this node without edges"},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"transitions":{"anyOf":[{"items":{"$ref":"#/components/schemas/ConditionTransitionModel"},"type":"array"},{"type":"null"}],"title":"Transitions","description":"List of transitions"}},"type":"object","required":["flavor"],"title":"ConditionWidgetUpdateModel"},"ConversationList":{"properties":{"conversations":{"items":{"$ref":"#/components/schemas/ConversationListItem"},"type":"array","title":"Conversations","description":"The requested page of conversations, newest first by default"},"total_count":{"type":"integer","title":"Total Count","description":"Rows matching the filter, across every page - not the number returned here","examples":[42]}},"type":"object","required":["total_count","conversations"],"title":"ConversationList"},"ConversationListItem":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account the conversation belongs to"},"agent":{"type":"string","title":"Agent","description":"Name of the agent or flow that handled it"},"callee":{"type":"string","title":"Callee","description":"Number that was dialled, empty for a session that has none"},"caller":{"type":"string","title":"Caller","description":"Number the call came from, empty for a session that has none","examples":["+12024561111"]},"duration":{"type":"integer","title":"Duration","description":"Seconds between start and end, computed as the response is built. 0 for a conversation with no recorded end","examples":[110]},"end_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string"}],"title":"End Time","description":"When it ended, empty if it did not end cleanly"},"id":{"type":"string","title":"Id","description":"Unique conversation id"},"start_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string"}],"title":"Start Time","description":"When the conversation started"},"sub_agents":{"items":{"type":"string"},"type":"array","title":"Sub Agents","description":"The agents and flows this conversation was handed to, in the order it reached them - everyone that took part except the one `agent` names. Empty when no handoff happened","examples":[["billing","billing-refunds"]]},"test_id":{"type":"string","title":"Test Id","description":"Set when the conversation came from a test run rather than a real caller, empty otherwise"},"type":{"type":"string","title":"Type","description":"What kind of session it was: 'call', 'chat', 'agent-assist', or 'test'.","examples":["call"]}},"type":"object","required":["id","account_id","start_time","end_time","agent","sub_agents","duration","type","caller","callee","test_id"],"title":"ConversationListItem","description":"One row of the conversation listing - enough to build a list view, without the transcript."},"ConversationResponse":{"properties":{"account_id":{"type":"string","title":"Account ID"},"agent":{"type":"string","title":"Agent"},"callee":{"type":"string","title":"Callee","default":""},"caller":{"type":"string","title":"Caller","default":""},"duration":{"type":"integer","title":"Duration","description":"Seconds between start and end. Derived as the response is built, like the log categories, so an exported conversation has no such field. 0 when there is no recorded end","examples":[110]},"embedding_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Embedding tokens"},"end_time":{"type":"string","format":"date-time","title":"End time"},"history":{"items":{"$ref":"#/components/schemas/HistoryDataModel"},"type":"array","title":"History"},"id":{"type":"string","title":"Id","description":"Unique conversation id"},"insights":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Insights"},"metrics":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Pre-defined metrics"},"start_time":{"type":"string","format":"date-time","title":"Start time"},"sub_agents":{"items":{"type":"string"},"type":"array","title":"Sub-agents"},"test_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test ID"},"token_usage":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Token usage"},"type":{"type":"string","title":"Type","default":""}},"type":"object","required":["id","start_time","account_id","agent","history","duration"],"title":"ConversationResponse","description":"One whole conversation, transcript included.\n\n`history` is the conversation in order - what was said, the tools that were called, and the\nruntime's own log lines. Each entry carries `time`, `task_name` (the agent - or, in a flow,\nthe node - that produced it), `from_name` / `to_name` (`User`, `LLM`, a tool name, ...), the\n`message` itself, a readable `label`, and `type` - `message` for something said, `log` for\neverything else. A log entry also carries a display `category` (`tool_call`, `end_call`,\n`warning`, ...) beyond the fields below: it is computed as the response is built, never\nstored, and so is absent from the same conversation in a backup or an export.\n\nSensitive-information handling applies here exactly as in the dashboard: entries marked\nhidden are absent, and masked ones arrive masked."},"ConversationStart":{"type":"string","enum":["llm","user"],"title":"ConversationStart"},"ConversationTransitionModel":{"properties":{"condition":{"type":"string","title":"Condition","description":"Transition condition","default":""},"id":{"type":"string","title":"Id"},"type":{"type":"string","enum":["text","logical"],"title":"Type","description":"Transition type","default":"text"},"widget":{"type":"string","title":"Node","description":"Node to transition to","default":""}},"type":"object","title":"ConversationTransitionModel"},"ConversationWidgetBehavior":{"type":"string","enum":["prompt","say"],"title":"ConversationWidgetBehavior"},"ConversationWidgetModel":{"properties":{"activity_params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Activity parameters","description":"Bot connection configuration parameters for this node"},"barge_in":{"$ref":"#/components/schemas/BargeInModel","title":"Barge-in","description":"Allow user to interrupt while LLM is speaking","default":"inherit"},"behavior":{"$ref":"#/components/schemas/ConversationWidgetBehavior","title":"Behavior","description":"Follow prompt or say static sentence","default":"prompt"},"custom_llm":{"type":"boolean","title":"Custom LLM","description":"Choose a different LLM for this node","default":false},"document_chunks":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Number of chunks","description":"Number of chunks to be extracted from documents"},"documents":{"items":{"type":"string"},"type":"array","title":"Documents","description":"Documents that can be used by this node"},"extract_variables":{"type":"boolean","title":"Extract variables","description":"Extract variables from user response","default":false},"flavor":{"type":"string","const":"conversation","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"type":"string","title":"Global condition","description":"Describe conditions to transition to this node","default":""},"global_widget":{"type":"boolean","title":"Global node","description":"Allow other nodes to transition to this node without edges","default":false},"immediate_transition":{"type":"boolean","title":"Immediate transition","description":"Allow transition to other nodes before saying anything","default":false},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used by this node.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)","default":""},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max output tokens","description":"Maximum number of tokens in LLM response","default":1000},"max_turns":{"type":"integer","maximum":500.0,"minimum":1.0,"title":"Max utterances","description":"Maximum number of user utterances in this node","default":10},"session_params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Session parameters","description":"Bot connection configuration parameters for the whole session"},"skip_response":{"type":"boolean","title":"Skip response","description":"Skip to next node without waiting for user response","default":false},"skip_widget":{"type":"string","title":"Skip to node","description":"Node to skip to if skip_response is true","default":""},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"text":{"type":"string","title":"Prompt","description":"The node prompt or text message","default":""},"transitions":{"items":{"$ref":"#/components/schemas/ConversationTransitionModel"},"type":"array","title":"Transitions","description":"List of transitions"},"variables":{"items":{"$ref":"#/components/schemas/ExtractVariableModel"},"type":"array","title":"Variables","description":"List of variables to be extracted"}},"type":"object","required":["flavor"],"title":"ConversationWidgetModel"},"ConversationWidgetUpdateModel":{"properties":{"activity_params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Activity parameters","description":"Bot connection configuration parameters for this node"},"barge_in":{"anyOf":[{"$ref":"#/components/schemas/BargeInModel"},{"type":"null"}],"title":"Barge-in","description":"Allow user to interrupt while LLM is speaking"},"behavior":{"anyOf":[{"$ref":"#/components/schemas/ConversationWidgetBehavior"},{"type":"null"}],"title":"Behavior","description":"Follow prompt or say static sentence"},"custom_llm":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Custom LLM","description":"Choose a different LLM for this node"},"document_chunks":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Number of chunks","description":"Number of chunks to be extracted from documents"},"documents":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Documents","description":"Documents that can be used by this node"},"extract_variables":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Extract variables","description":"Extract variables from user response"},"flavor":{"type":"string","const":"conversation","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Global condition","description":"Describe conditions to transition to this node"},"global_widget":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Global node","description":"Allow other nodes to transition to this node without edges"},"immediate_transition":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Immediate transition","description":"Allow transition to other nodes before saying anything"},"llm":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Large language model","description":"Large language model (LLM) used by this node.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)"},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"max_tokens":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Max output tokens","description":"Maximum number of tokens in LLM response"},"max_turns":{"anyOf":[{"type":"integer","maximum":500.0,"minimum":1.0},{"type":"null"}],"title":"Max utterances","description":"Maximum number of user utterances in this node"},"session_params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Session parameters","description":"Bot connection configuration parameters for the whole session"},"skip_response":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Skip response","description":"Skip to next node without waiting for user response"},"skip_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Skip to node","description":"Node to skip to if skip_response is true"},"temperature":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt","description":"The node prompt or text message"},"transitions":{"anyOf":[{"items":{"$ref":"#/components/schemas/ConversationTransitionModel"},"type":"array"},{"type":"null"}],"title":"Transitions","description":"List of transitions"},"variables":{"anyOf":[{"items":{"$ref":"#/components/schemas/ExtractVariableModel"},"type":"array"},{"type":"null"}],"title":"Variables","description":"List of variables to be extracted"}},"type":"object","required":["flavor"],"title":"ConversationWidgetUpdateModel"},"ConvertMultipleTimesConfigModel":{"properties":{"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"tool":{"type":"string","const":"convert_multiple_times","title":"Tool"}},"type":"object","required":["tool"],"title":"ConvertMultipleTimesConfigModel"},"ConvertTimeConfigModel":{"properties":{"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"tool":{"type":"string","const":"convert_time","title":"Tool"}},"type":"object","required":["tool"],"title":"ConvertTimeConfigModel"},"CustomToolConfigModel":{"properties":{"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"tool":{"type":"string","const":"custom","title":"Tool"},"tool_id":{"type":"string","title":"Tool Id"}},"type":"object","required":["tool","tool_id"],"title":"CustomToolConfigModel"},"DialDtmfConfigModel":{"properties":{"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"tool":{"type":"string","const":"dial_dtmf","title":"Tool"}},"type":"object","required":["tool"],"title":"DialDtmfConfigModel"},"DocToolMode":{"type":"string","enum":["regular","advanced"],"title":"DocToolMode"},"DocToolsConfigModel":{"properties":{"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Custom tool description"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Custom tool name"},"redact_response":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Redact Response","description":"Redact tool response from message history"}},"type":"object","title":"DocToolsConfigModel"},"DocumentAdvancedModel":{"properties":{"download_markdown":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Download Markdown","description":"For \"advanced\" download client only; defines whether we should download markdown files from \"advanced\" download service"},"link_ignore_classes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Link Ignore Classes","description":"List of CSS classes for inline HTML links to be ignored during crawling, separated by comma"},"link_to_text_classes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Link To Text Classes","description":"List of CSS classes for HTML links to be converted to text, separated by comma"},"lookups":{"anyOf":[{"items":{"$ref":"#/components/schemas/DocumentLookupModel"},"type":"array"},{"type":"null"}],"title":"Lookups","description":"Structured lookup tools over tabular (Excel/CSV) files. Configuring any lookup makes the document lookup-only (its files are not embedded or used for semantic search)."},"pdf_parser":{"anyOf":[{"$ref":"#/components/schemas/PdfParserAdvancedModel"},{"type":"null"}],"description":"PDF parser configuration"},"remove_classes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Remove Classes","description":"List of CSS classes for HTML elements to be removed from the page, separated by comma"},"sitemap_custom":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sitemap Custom","description":"Custom sitemap URL and extraction jq statement - e.g. \"POST https://example.com .[].url\""}},"type":"object","title":"DocumentAdvancedModel"},"DocumentChunks":{"properties":{"chunks":{"items":{"type":"string"},"type":"array","title":"Chunks","description":"The chunk texts, in document order. Absent when the file has not been parsed yet, or when neither the document nor the index exists"}},"type":"object","title":"DocumentChunks","description":"The chunks one of a document's files was split into."},"DocumentConditionModel":{"properties":{"condition":{"type":"string","title":"Condition","description":"Condition that must be true for the document to be available; evaluated against variables and conversation data, e.g. \"caller == 123456\"; if a document is listed multiple times, all its conditions must be true"},"document":{"type":"string","title":"Document","description":"Name of the document to which the condition applies"}},"type":"object","required":["document","condition"],"title":"DocumentConditionModel"},"DocumentDataModel":{"properties":{"chunks":{"type":"integer","title":"Chunks","default":0},"details":{"type":"string","title":"Details","default":""},"status":{"type":"boolean","title":"Status","default":true},"url":{"type":"string","title":"Url","default":""}},"type":"object","title":"DocumentDataModel"},"DocumentList":{"properties":{"documents":{"items":{"oneOf":[{"$ref":"#/components/schemas/UrlDocumentListItem"},{"$ref":"#/components/schemas/FileDocumentListItem"}],"discriminator":{"propertyName":"type","mapping":{"file":"#/components/schemas/FileDocumentListItem","url":"#/components/schemas/UrlDocumentListItem"}}},"type":"array","title":"Documents","description":"The requested page of documents"},"refresh_needed":{"type":"boolean","title":"Refresh Needed","description":"Whether any row on this page is still being parsed - the flag a dashboard polls on"},"total_count":{"type":"integer","title":"Total Count","description":"Rows matching the filter, across every page - not the number returned here","examples":[42]}},"type":"object","required":["total_count","documents","refresh_needed"],"title":"DocumentList"},"DocumentLookupKeyModel":{"properties":{"column":{"type":"string","title":"Column","description":"Column matched against this argument. Either a column letter (\"A\", \"B\", ...) or, when the file has a header row, a header name."},"match_mode":{"anyOf":[{"type":"string","enum":["exact","fuzzy","phonetic","hybrid"]},{"type":"null"}],"title":"Match mode","description":"Matching strategy for this column. Defaults to the lookup's \"match_mode\"; a phone can match exactly while a name stays fuzzy."},"param_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parameter description","description":"Description of the tool argument."},"param_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parameter name","description":"Name of the tool argument carrying this column's value. Defaults to the column as an identifier (\"City\" -> \"city\"), prefixed when too short (\"B\" -> \"query_b\")."}},"type":"object","required":["column"],"title":"DocumentLookupKeyModel","description":"An additional key column a structured lookup matches on, beyond its primary\n`search_column`. Every additional key is an optional tool argument: a record must\nmatch all the values the agent supplies, and the ones it omits are ignored."},"DocumentLookupModel":{"properties":{"additional_search_columns":{"anyOf":[{"items":{"$ref":"#/components/schemas/DocumentLookupKeyModel"},"type":"array","maxItems":2},{"type":"null"}],"title":"Additional search columns","description":"Up to 2 more columns to match, each an optional argument, narrowing the lookup (e.g. phone AND city)."},"confident_score":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Confident score","description":"A single match at or above this score (0-100), clearly ahead of the rest, is returned as a confident match rather than candidates. Defaults to 92."},"debug":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Debug scores","description":"Include a \"scores\" list (top matched values and scores, ignoring thresholds) in the result, to help tune min_score / confident_score. Disable in production."},"file":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File","description":"Which uploaded/downloaded file to search. Defaults to the first Excel/CSV file in the document."},"header_row":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Header row","description":"1-based row number of the header row; rows above it are skipped. Use 0 for a file with no header (columns are then referenced only by letter). Defaults to 1."},"match_mode":{"anyOf":[{"type":"string","enum":["exact","fuzzy","phonetic","hybrid"]},{"type":"null"}],"title":"Match mode","description":"Matching strategy: \"exact\", \"fuzzy\" (typo-tolerant), \"phonetic\" (sounds-alike), or \"hybrid\" (both). Defaults to \"hybrid\"."},"max_candidates":{"anyOf":[{"type":"integer","maximum":50.0,"minimum":1.0},{"type":"null"}],"title":"Max candidates","description":"Maximum number of candidate rows returned when the match is ambiguous. Defaults to 5."},"min_score":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Minimum score","description":"Minimum match score (0-100) for a row to be considered a candidate. Defaults to 75."},"param_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parameter description","description":"Description of the \"search_column\" tool argument."},"param_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parameter name","description":"Name of the tool argument carrying the \"search_column\" value (e.g. \"name\", \"phone\"). Defaults to the column name as an identifier (\"Full Name\" -> \"full_name\")."},"return_columns":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Return columns","description":"Columns (letters or header names) to include in the result. Defaults to all columns."},"search_column":{"type":"string","title":"Search column","description":"Primary column matched against the caller-supplied value; always a required tool argument. Either a column letter (\"A\", \"B\", ...) or, when the file has a header row, a header name."},"sheet":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sheet","description":"Worksheet name (Excel only). Defaults to the first sheet."},"tool_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool description","description":"Description of the lookup tool shown to the agent. A hint to pass the value exactly as heard is always prepended automatically. Auto-generated when omitted."},"tool_name":{"type":"string","title":"Tool name","description":"Name of the lookup tool exposed to the agent"}},"type":"object","required":["tool_name","search_column"],"title":"DocumentLookupModel","description":"Configures a structured keyed-lookup tool over a tabular (Excel/CSV) file, as an\nalternative to semantic search. The tool matches caller-supplied values against one\nor more columns using fuzzy + phonetic matching and returns the matching row(s).\n\nA record must match every value the caller supplies, and scores as its WEAKEST\nmatched column - so min_score / confident_score keep the same meaning however many\ncolumns are configured."},"DocumentMode":{"type":"string","enum":["rag","doc_search","prompt","doc_get"],"title":"DocumentMode"},"DocumentModel":{"properties":{"_id":{"type":"string","title":"Id","description":"Assigned when the entity is created; a create that sends one of its own is rejected","readOnly":true},"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/DocumentAdvancedModel"},{"type":"null"}],"description":"Advanced configuration parameters"},"auto_refresh":{"type":"string","enum":["never","hourly","daily","weekly","monthly"],"title":"Auto refresh","description":"Auto refresh interval","default":"never"},"case_sensitive":{"type":"boolean","title":"Case-sensitive URL matching","description":"Use case-sensitive URL matching when crawling","default":true},"chunk_size":{"type":"integer","maximum":4096.0,"minimum":100.0,"title":"Chunk size","description":"Desired chunk size in tokens","default":512},"content_extraction":{"type":"string","enum":["main","clean","article","all"],"title":"Content extraction","description":"Content extraction method:\n- \"main\" extracts main content of the page, removing navigation, ads, and other irrelevant parts\n- \"clean\" is alternative version of main content extraction that often produces cleaner results but may accidentally remove some useful parts\n- \"article\" is optimized for extracting news articles and blog posts\n- \"all\" returns the full HTML content of the page","default":"main"},"created_on":{"type":"string","format":"date-time","title":"Created On","description":"When the document was created","readOnly":true},"description":{"type":"string","title":"Description","description":"Document description","default":""},"doc_data":{"items":{"$ref":"#/components/schemas/DocumentDataModel"},"type":"array","title":"Doc Data"},"download_client":{"type":"string","title":"Download Client","description":"The client the last parse actually used - what `web_client` (or its `auto` detection) resolved to","default":"","readOnly":true},"exclude_paths":{"type":"string","title":"Exclude Paths","description":"Exclude paths that match the specified regex, e.g. \"/photos/.*\" excludes links under /photos. Multiple regexes may be specified separated by comma.","default":""},"file_names":{"items":{"type":"string"},"type":"array","title":"File names","description":"List of file names"},"follow_links":{"type":"string","enum":["direct","domain","subdomains","all"],"title":"Follow links","description":"What links to follow during crawling:\n- \"direct\" - follow only direct descendants of the crawled URL - e.g. for \"https://site.com/features\" download \"/features/1\", but not \"/pricing\"\n- \"domain\" - follow all links that belong to the same domain - e.g. for \"https://site.com/features\" download both \"/features/1\" and \"/pricing\"\n- \"subdomains\" - follow all links that belong to the same domain and its subdomains - e.g. for \"https://site.com\" download links under \"https://blog.site.com\" too\n- \"all\" - follow all links regardless of the domain","default":"direct"},"include_paths":{"type":"string","title":"Include Paths","description":"Include paths that match the specified regex, e.g. \"/blogs/.*\" downloads links under /blogs only. Multiple regexes may be specified separated by comma.","default":""},"max_chunks":{"type":"integer","maximum":50000.0,"minimum":250.0,"title":"Max chunks","description":"Maximum number of chunks","default":5000},"max_depth":{"type":"integer","maximum":3.0,"minimum":0.0,"title":"Max depth","description":"Maximum depth for URL crawling","default":0},"max_urls":{"type":"integer","maximum":1000.0,"minimum":1.0,"title":"Max URLs","description":"Maximum number of URLs to process","default":100},"n_chunks":{"type":"integer","title":"N Chunks","description":"Chunks the content was split into","default":0,"readOnly":true},"n_files":{"type":"integer","title":"N Files","description":"Files (or crawled URLs) parsed into the vector store","default":0,"readOnly":true},"n_tokens":{"type":"integer","title":"N Tokens","description":"Tokens across the chunks","default":0,"readOnly":true},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Document name"},"overlap":{"type":"integer","maximum":500.0,"minimum":25.0,"title":"Overlap","description":"Overlap between chunks in tokens","default":64},"sitemap":{"type":"string","enum":["include","skip","only"],"title":"Sitemap","description":"Whether to use URLs from sitemap (if available):\n- \"include\" - use both sitemap and inline HTML links\n- \"skip\" - ignore sitemap and use only inline HTML links\n- \"only\" - use sitemap only and ignore inline HTML links","default":"include"},"status":{"type":"string","title":"Status","description":"Server-managed, read-only: where the document is in its parse cycle (`creating`, `updating`, `ready`, or an error). Anything sent here is overwritten - a create leaves it `creating` and an update resets it to `updating`, since both start a parse. Poll the listing's `processing` flag to find out when it has finished.","default":"creating","readOnly":true},"updated_on":{"type":"string","format":"date-time","title":"Updated On","description":"When the document last changed - an edit and an auto-refresh both move it","readOnly":true},"urls":{"type":"string","title":"URL","description":"List of URLs separated by newlines","default":""},"verify_ssl":{"type":"boolean","title":"Verify SSL","description":"Verify SSL certificates","default":true},"web_client":{"type":"string","enum":["standard","enhanced","advanced","auto"],"title":"Download client","description":"Client used for downloading and rendering web pages:\n- \"standard\" mode is the fastest and uses simple HTTP client\n- \"enhanced\" mode uses headless browser to render complete page including dynamic parts generated by Javascript code\n- \"advanced\" mode is the slowest one, but can overcome geo-location blocking and anti-robot protection\n- \"auto\" mode automatically selects the client based on the web page content","default":"auto"}},"type":"object","required":["name"],"title":"DocumentModel"},"DocumentResponse":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the document"},"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/DocumentAdvancedModel"},{"type":"null"}],"description":"Advanced configuration parameters"},"auto_refresh":{"type":"string","enum":["never","hourly","daily","weekly","monthly"],"title":"Auto refresh","description":"Auto refresh interval","default":"never"},"case_sensitive":{"type":"boolean","title":"Case-sensitive URL matching","description":"Use case-sensitive URL matching when crawling","default":true},"chunk_size":{"type":"integer","maximum":4096.0,"minimum":100.0,"title":"Chunk size","description":"Desired chunk size in tokens","default":512},"content_extraction":{"type":"string","enum":["main","clean","article","all"],"title":"Content extraction","description":"Content extraction method:\n- \"main\" extracts main content of the page, removing navigation, ads, and other irrelevant parts\n- \"clean\" is alternative version of main content extraction that often produces cleaner results but may accidentally remove some useful parts\n- \"article\" is optimized for extracting news articles and blog posts\n- \"all\" returns the full HTML content of the page","default":"main"},"created_on":{"type":"string","format":"date-time","title":"Created On","description":"When the document was created","readOnly":true},"description":{"type":"string","title":"Description","description":"Document description","default":""},"doc_data":{"items":{"$ref":"#/components/schemas/DocumentDataModel"},"type":"array","title":"Doc Data"},"download_client":{"type":"string","title":"Download Client","description":"The client the last parse actually used - what `web_client` (or its `auto` detection) resolved to","default":"","readOnly":true},"exclude_paths":{"type":"string","title":"Exclude Paths","description":"Exclude paths that match the specified regex, e.g. \"/photos/.*\" excludes links under /photos. Multiple regexes may be specified separated by comma.","default":""},"file_names":{"items":{"type":"string"},"type":"array","title":"File names","description":"List of file names"},"follow_links":{"type":"string","enum":["direct","domain","subdomains","all"],"title":"Follow links","description":"What links to follow during crawling:\n- \"direct\" - follow only direct descendants of the crawled URL - e.g. for \"https://site.com/features\" download \"/features/1\", but not \"/pricing\"\n- \"domain\" - follow all links that belong to the same domain - e.g. for \"https://site.com/features\" download both \"/features/1\" and \"/pricing\"\n- \"subdomains\" - follow all links that belong to the same domain and its subdomains - e.g. for \"https://site.com\" download links under \"https://blog.site.com\" too\n- \"all\" - follow all links regardless of the domain","default":"direct"},"id":{"type":"string","title":"Id","description":"Unique document id"},"include_paths":{"type":"string","title":"Include Paths","description":"Include paths that match the specified regex, e.g. \"/blogs/.*\" downloads links under /blogs only. Multiple regexes may be specified separated by comma.","default":""},"max_chunks":{"type":"integer","maximum":50000.0,"minimum":250.0,"title":"Max chunks","description":"Maximum number of chunks","default":5000},"max_depth":{"type":"integer","maximum":3.0,"minimum":0.0,"title":"Max depth","description":"Maximum depth for URL crawling","default":0},"max_urls":{"type":"integer","maximum":1000.0,"minimum":1.0,"title":"Max URLs","description":"Maximum number of URLs to process","default":100},"n_chunks":{"type":"integer","title":"N Chunks","description":"Chunks the content was split into","default":0,"readOnly":true},"n_files":{"type":"integer","title":"N Files","description":"Files (or crawled URLs) parsed into the vector store","default":0,"readOnly":true},"n_tokens":{"type":"integer","title":"N Tokens","description":"Tokens across the chunks","default":0,"readOnly":true},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Document name"},"overlap":{"type":"integer","maximum":500.0,"minimum":25.0,"title":"Overlap","description":"Overlap between chunks in tokens","default":64},"sitemap":{"type":"string","enum":["include","skip","only"],"title":"Sitemap","description":"Whether to use URLs from sitemap (if available):\n- \"include\" - use both sitemap and inline HTML links\n- \"skip\" - ignore sitemap and use only inline HTML links\n- \"only\" - use sitemap only and ignore inline HTML links","default":"include"},"status":{"type":"string","title":"Status","description":"Server-managed, read-only: where the document is in its parse cycle (`creating`, `updating`, `ready`, or an error). Anything sent here is overwritten - a create leaves it `creating` and an update resets it to `updating`, since both start a parse. Poll the listing's `processing` flag to find out when it has finished.","default":"creating","readOnly":true},"type":{"type":"string","enum":["url","file"],"title":"Type","description":"Where the content comes from - 'url' for a crawl, 'file' for uploads. Derived from whether the document has any URLs, not stored"},"updated_on":{"type":"string","format":"date-time","title":"Updated On","description":"When the document last changed - an edit and an auto-refresh both move it","readOnly":true},"urls":{"type":"string","title":"URL","description":"List of URLs separated by newlines","default":""},"verify_ssl":{"type":"boolean","title":"Verify SSL","description":"Verify SSL certificates","default":true},"web_client":{"type":"string","enum":["standard","enhanced","advanced","auto"],"title":"Download client","description":"Client used for downloading and rendering web pages:\n- \"standard\" mode is the fastest and uses simple HTTP client\n- \"enhanced\" mode uses headless browser to render complete page including dynamic parts generated by Javascript code\n- \"advanced\" mode is the slowest one, but can overcome geo-location blocking and anti-robot protection\n- \"auto\" mode automatically selects the client based on the web page content","default":"auto"}},"type":"object","required":["id","name","account_id","type"],"title":"DocumentResponse","description":"A document as create, get and update return it. The crawl settings, the parse counters\nand the advanced configuration all round-trip."},"DocumentUpdateModel":{"properties":{"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/DocumentAdvancedModel"},{"type":"null"}],"description":"Advanced configuration parameters"},"auto_refresh":{"anyOf":[{"type":"string","enum":["never","hourly","daily","weekly","monthly"]},{"type":"null"}],"title":"Auto refresh","description":"Auto refresh interval"},"case_sensitive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Case-sensitive URL matching","description":"Use case-sensitive URL matching when crawling"},"chunk_size":{"anyOf":[{"type":"integer","maximum":4096.0,"minimum":100.0},{"type":"null"}],"title":"Chunk size","description":"Desired chunk size in tokens"},"content_extraction":{"anyOf":[{"type":"string","enum":["main","clean","article","all"]},{"type":"null"}],"title":"Content extraction","description":"Content extraction method:\n- \"main\" extracts main content of the page, removing navigation, ads, and other irrelevant parts\n- \"clean\" is alternative version of main content extraction that often produces cleaner results but may accidentally remove some useful parts\n- \"article\" is optimized for extracting news articles and blog posts\n- \"all\" returns the full HTML content of the page"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Document description"},"exclude_paths":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exclude Paths","description":"Exclude paths that match the specified regex, e.g. \"/photos/.*\" excludes links under /photos. Multiple regexes may be specified separated by comma."},"file_names":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"File names","description":"List of file names"},"follow_links":{"anyOf":[{"type":"string","enum":["direct","domain","subdomains","all"]},{"type":"null"}],"title":"Follow links","description":"What links to follow during crawling:\n- \"direct\" - follow only direct descendants of the crawled URL - e.g. for \"https://site.com/features\" download \"/features/1\", but not \"/pricing\"\n- \"domain\" - follow all links that belong to the same domain - e.g. for \"https://site.com/features\" download both \"/features/1\" and \"/pricing\"\n- \"subdomains\" - follow all links that belong to the same domain and its subdomains - e.g. for \"https://site.com\" download links under \"https://blog.site.com\" too\n- \"all\" - follow all links regardless of the domain"},"include_paths":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Include Paths","description":"Include paths that match the specified regex, e.g. \"/blogs/.*\" downloads links under /blogs only. Multiple regexes may be specified separated by comma."},"max_chunks":{"anyOf":[{"type":"integer","maximum":50000.0,"minimum":250.0},{"type":"null"}],"title":"Max chunks","description":"Maximum number of chunks"},"max_depth":{"anyOf":[{"type":"integer","maximum":3.0,"minimum":0.0},{"type":"null"}],"title":"Max depth","description":"Maximum depth for URL crawling"},"max_urls":{"anyOf":[{"type":"integer","maximum":1000.0,"minimum":1.0},{"type":"null"}],"title":"Max URLs","description":"Maximum number of URLs to process"},"name":{"anyOf":[{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$"},{"type":"null"}],"title":"Name","description":"Document name"},"overlap":{"anyOf":[{"type":"integer","maximum":500.0,"minimum":25.0},{"type":"null"}],"title":"Overlap","description":"Overlap between chunks in tokens"},"sitemap":{"anyOf":[{"type":"string","enum":["include","skip","only"]},{"type":"null"}],"title":"Sitemap","description":"Whether to use URLs from sitemap (if available):\n- \"include\" - use both sitemap and inline HTML links\n- \"skip\" - ignore sitemap and use only inline HTML links\n- \"only\" - use sitemap only and ignore inline HTML links"},"urls":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"URL","description":"List of URLs separated by newlines"},"verify_ssl":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Verify SSL","description":"Verify SSL certificates"},"web_client":{"anyOf":[{"type":"string","enum":["auto","standard","enhanced","advanced"]},{"type":"null"}],"title":"Download client","description":"Client used for downloading and rendering web pages:\n- \"standard\" mode is the fastest and uses simple HTTP client\n- \"enhanced\" mode uses headless browser to render complete page including dynamic parts generated by Javascript code\n- \"advanced\" mode is the slowest one, but can overcome geo-location blocking and anti-robot protection\n- \"auto\" mode automatically selects the client based on the web page content"}},"type":"object","title":"DocumentUpdateModel"},"EmptyLLMResponse":{"type":"string","enum":["ignore","retry","allow"],"title":"EmptyLLMResponse"},"EndCallConfigModel":{"properties":{"default_message":{"type":"string","title":"Default Message","description":"Default termination message to be used if LLM didn't specify one","default":""},"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"tool":{"type":"string","const":"end_call","title":"Tool"}},"type":"object","required":["tool"],"title":"EndCallConfigModel"},"EndCallDetectionModel":{"properties":{"case_sensitive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Case Sensitive","description":"Perform case-sensitive keyword matching"},"keywords":{"items":{"type":"string"},"type":"array","title":"Keywords","description":"List of keywords that indicate the LLM wants to end the call"},"last_sentence":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Last Sentence","description":"Search for keywords in last sentence only"}},"type":"object","title":"EndCallDetectionModel"},"EndCallRequestModel":{"properties":{"message":{"type":"string","title":"Message","description":"Goodbye message to play before hanging up","default":""}},"type":"object","title":"EndCallRequestModel"},"EndCallWidgetModel":{"properties":{"flavor":{"type":"string","const":"end_call","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"type":"string","title":"Global condition","description":"Describe conditions to transition to this node","default":""},"global_widget":{"type":"boolean","title":"Global node","description":"Allow other nodes to transition to this node without edges","default":false},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"text":{"type":"string","title":"Termination message","description":"Message to be played before ending the call","default":""}},"type":"object","required":["flavor"],"title":"EndCallWidgetModel"},"EndCallWidgetUpdateModel":{"properties":{"flavor":{"type":"string","const":"end_call","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Global condition","description":"Describe conditions to transition to this node"},"global_widget":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Global node","description":"Allow other nodes to transition to this node without edges"},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Termination message","description":"Message to be played before ending the call"}},"type":"object","required":["flavor"],"title":"EndCallWidgetUpdateModel"},"ErrorModel":{"properties":{"detail":{"type":"string","title":"Detail","description":"What went wrong","examples":["Agent not found"]}},"type":"object","required":["detail"],"title":"ErrorModel","description":"The body of an error this API raises itself - every 4xx and 5xx listed on an operation.\n\nA `422` is the exception: schema validation happens before the operation runs, and answers\nwith a `detail` that is a list of per-field objects rather than a string."},"ExecutionSound":{"type":"string","enum":["none","typing-1","typing-2","hold-music-1","hold-music-2","hold-music-3","hold-music-4"],"title":"ExecutionSound"},"ExpressionModel":{"properties":{"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition","description":"Condition for the expression to be executed"},"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name","description":"Variable name to be assigned or modified"},"operator":{"type":"string","enum":["=","+=","-=","*=","/=","++","--"],"title":"Operator","description":"Assignment operator","default":"="},"value":{"type":"string","title":"Value","description":"Value to be assigned or modified","default":""}},"type":"object","required":["name"],"title":"ExpressionModel"},"ExtractFromModel":{"type":"string","enum":["last","all"],"title":"ExtractFromModel"},"ExtractVariableModel":{"properties":{"description":{"type":"string","title":"Description","description":"Variable description"},"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name","description":"Variable name"},"type":{"$ref":"#/components/schemas/ExtractVariableType","title":"Type","description":"Variable type","default":"str"}},"type":"object","required":["name","description"],"title":"ExtractVariableModel"},"ExtractVariableType":{"type":"string","enum":["str","int","float","bool"],"title":"ExtractVariableType"},"ExtractWidgetModel":{"properties":{"custom_llm":{"type":"boolean","title":"Custom LLM","description":"Choose a different LLM for this node","default":false},"extract_from":{"$ref":"#/components/schemas/ExtractFromModel","title":"Extract from","description":"Where to extract the variables from","default":"last"},"extract_prompt":{"type":"string","title":"Extract prompt","description":"Custom system prompt for extraction. If empty - default extraction prompt is used.","default":""},"flavor":{"type":"string","const":"extract","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"type":"string","title":"Global condition","description":"Describe conditions to transition to this node","default":""},"global_widget":{"type":"boolean","title":"Global node","description":"Allow other nodes to transition to this node without edges","default":false},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used by this node.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)","default":""},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max output tokens","description":"Maximum number of tokens in LLM response","default":1000},"next_widget":{"type":"string","title":"Continue","description":"Node to transition to","default":""},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"variables":{"items":{"$ref":"#/components/schemas/ExtractVariableModel"},"type":"array","title":"Variables","description":"List of variables to be extracted"}},"type":"object","required":["flavor"],"title":"ExtractWidgetModel"},"ExtractWidgetUpdateModel":{"properties":{"custom_llm":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Custom LLM","description":"Choose a different LLM for this node"},"extract_from":{"anyOf":[{"$ref":"#/components/schemas/ExtractFromModel"},{"type":"null"}],"title":"Extract from","description":"Where to extract the variables from"},"extract_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extract prompt","description":"Custom system prompt for extraction. If empty - default extraction prompt is used."},"flavor":{"type":"string","const":"extract","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Global condition","description":"Describe conditions to transition to this node"},"global_widget":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Global node","description":"Allow other nodes to transition to this node without edges"},"llm":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Large language model","description":"Large language model (LLM) used by this node.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)"},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"max_tokens":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Max output tokens","description":"Maximum number of tokens in LLM response"},"next_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Continue","description":"Node to transition to"},"temperature":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses"},"variables":{"anyOf":[{"items":{"$ref":"#/components/schemas/ExtractVariableModel"},"type":"array"},{"type":"null"}],"title":"Variables","description":"List of variables to be extracted"}},"type":"object","required":["flavor"],"title":"ExtractWidgetUpdateModel"},"FileDocumentListItem":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the document"},"auto_refresh":{"type":"string","title":"Auto Refresh","description":"Re-parse interval","examples":["never"]},"description":{"type":"string","title":"Description","description":"Document description"},"file_names":{"items":{"type":"string"},"type":"array","title":"File Names","description":"Names of the uploaded files"},"id":{"type":"string","title":"Id","description":"Unique document id"},"max_depth":{"type":"integer","title":"Max Depth","description":"How many link levels deep the crawl goes"},"n_chunks":{"type":"integer","title":"N Chunks","description":"Chunks the content was split into"},"n_files":{"type":"integer","title":"N Files","description":"Files (or crawled URLs) parsed into the vector store"},"name":{"type":"string","title":"Name","description":"Document name","examples":["product-manuals"]},"processing":{"type":"boolean","title":"Processing","description":"Whether a parse is still running. Poll the listing while any row has this set - `refresh_needed` says whether any does"},"status":{"type":"string","title":"Status","description":"Parse state, phrased for display: a finished document reads 'ready (3 files, 412 chunks)', one still working reads 'creating' or 'updating', and a failed one carries the parser's own message. Use `processing` rather than parsing this","examples":["ready (3 files, 412 chunks)"]},"type":{"type":"string","const":"file","title":"Type"},"updated":{"type":"string","title":"Updated","description":"How long ago the document last finished parsing, in words","examples":["5 minutes ago"]}},"type":"object","required":["id","account_id","name","description","status","n_files","n_chunks","updated","max_depth","auto_refresh","processing","type","file_names"],"title":"FileDocumentListItem","description":"A row for a document built from uploaded files."},"FlowConfigAdvancedModel":{"properties":{"active_listening":{"anyOf":[{"$ref":"#/components/schemas/ActiveListeningModel"},{"type":"null"}],"description":"Generate LLM responses based on STT hypotheses"},"empty_llm_response":{"anyOf":[{"$ref":"#/components/schemas/EmptyLLMResponse"},{"type":"null"}],"description":"How to treat empty LLM response"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message","description":"Mesage to be played if LLM response couldn't be generated due to some error"},"gemini_api":{"anyOf":[{"type":"string","enum":["openai","google"]},{"type":"null"}],"title":"Gemini Api","description":"API to be used for Gemini models: \"openai\" (OpenAI-compat) or \"google\" (native google-genai SDK). When unset, gemini-3.5 and later default to \"google\" and earlier Gemini models to \"openai\"."},"incomplete_turn":{"anyOf":[{"$ref":"#/components/schemas/IncompleteTurnModel"},{"type":"null"}],"description":"Let the model suppress its response when the user has not finished speaking; applies to conversation nodes"},"init_conditions":{"anyOf":[{"items":{"$ref":"#/components/schemas/InitConditionsModel"},"type":"array"},{"type":"null"}],"title":"Init Conditions","description":"Conditional flow initialization"},"llm_logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Llm Logs","description":"Enable LLM logs for troubleshooting (visible on the backend only)"},"llm_message_with_tool_call":{"anyOf":[{"type":"string","enum":["play","drop"]},{"type":"null"}],"title":"Llm Message With Tool Call","description":"How to handle the LLM text message that accompanies a (non-terminal) tool call: \"play\" (default) delivers it to the user, \"drop\" discards it. Non-streaming path only (streaming always plays it); ignored for call-control tools"},"llm_not_found":{"anyOf":[{"$ref":"#/components/schemas/LLMNotFound"},{"type":"null"}],"description":"What to do when the configured LLM name is not provisioned in the account: \"strict\" (default) fails; \"fallback\" uses any available model"},"max_transitions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Transitions","description":"Maximum number of transitions allowed in the flow"},"max_turns_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Max Turns Message","description":"Message to be played when max turns limit is reached"},"mcp_logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Mcp Logs","description":"Enable additional logs when calling MCP tools"},"no_user_input_repeat":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"No User Input Repeat","description":"NO-USER-INPUT event occurences which trigger repeating the last LLM response"},"openai_api":{"anyOf":[{"type":"string","enum":["chat_completions","responses"]},{"type":"null"}],"title":"Openai Api","description":"API to be used for OpenAI models: \"chat_completions\" (default) or \"responses\" (stateless). Applies only to gpt-5 and later; older / non-OpenAI models always use chat/completions. gpt-5.6 and later always use the Responses API."},"post_call_analysis":{"anyOf":[{"$ref":"#/components/schemas/PostCallAnalysisFlowConfigModel"},{"type":"null"}],"description":"Configuration of post-call analysis behavior"},"prompt_log":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Prompt Log","description":"Log the flow prompt as a separate \"prompt\" entry in the conversation log, at the beginning of the conversation"},"reasoning_effort":{"anyOf":[{"type":"string","enum":["minimal","low","medium","high"]},{"type":"null"}],"title":"Reasoning Effort","description":"Reasoning level for thinking models"},"reasoning_logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Reasoning Logs","description":"Enable reasoning logs for thinking models"},"remove_symbols":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Remove Symbols","description":"Symbols to be removed from user utterance"},"replace_words":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Replace Words","description":"Words to be replaced in user utterance"},"scripts_file":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scripts File","description":"Name of the scripts document whose public functions can be called in expressions"},"send_metadata_init":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Send Metadata Init","description":"Relay the conversation identifiers to the connector as a \"sendMetaData\" event at the beginning of the conversation"},"send_metadata_transcript":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Send Metadata Transcript","description":"Relay the conversation transcript (user and assistant utterances) to the connector as \"sendMetaData\" events"},"start_delay":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Start Delay","description":"Delay in milliseconds before the conversation starts"},"tool_certs":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Tool Certs","description":"Custom certificates for tools calls; key = tool name, value = name of document containing the certificates"},"tool_logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Tool Logs","description":"Enable tool call logs for troubleshooting"},"tts_stream":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Tts Stream","description":"If enabled, the LLM response will be streamed to the TTS engine"},"webchat_config":{"anyOf":[{"$ref":"#/components/schemas/WebChatConfigModel"},{"type":"null"}],"description":"Webchat configuration"}},"type":"object","title":"FlowConfigAdvancedModel"},"FlowDetail":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the flow"},"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/FlowConfigAdvancedModel"},{"type":"null"}],"description":"Configuration with no dedicated field of its own. Absent when the flow has none set"},"api_url":{"type":"string","title":"Api Url","description":"Where a client starts a conversation on this flow. A flow has no websocket URL of its own - an agent does"},"description":{"type":"string","title":"Description","description":"Flow description","default":""},"id":{"type":"string","title":"Id","description":"Unique flow id"},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used by the flow.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)","default":""},"logs":{"anyOf":[{"type":"string","enum":["enabled","disabled","masked"]},{"type":"null"}],"title":"Logs","description":"Logging level for the agent","default":"enabled"},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max output tokens","description":"Maximum number of tokens in LLM response","default":1000},"max_turns":{"type":"integer","maximum":500.0,"minimum":1.0,"title":"Max utterances","description":"Maximum number of turns (user utterance / LLM response) in the conversation","default":50},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Flow name"},"post_call_analysis":{"items":{"type":"string"},"type":"array","title":"Post call analysis","description":"Post call analysis tools to be run at the end of the conversation"},"prompt":{"type":"string","title":"Prompt","description":"Global conversation flow prompt. Use {...} to reference variables.","default":""},"start_mode":{"$ref":"#/components/schemas/ConversationStart","title":"Conversation start","description":"Who starts the conversation","default":"llm"},"start_widget":{"type":"string","title":"Start node","description":"Node that starts the conversation","default":""},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"variables_str":{"type":"string","title":"Variables","description":"Variables that can be used in nodes; use \"NAME = VALUE\" format, for example: \"name = John\"; use multiple lines to specify multiple variables","default":""},"webhooks":{"anyOf":[{"items":{"$ref":"#/components/schemas/WebhookModel"},"type":"array"},{"type":"null"}],"title":"Webhooks","description":"Webhooks to be called during the flow execution"}},"type":"object","required":["id","name","account_id","api_url"],"title":"FlowDetail","description":"What reading one flow adds, and create, update and clone do not."},"FlowList":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account the rows belong to"},"flows":{"items":{"$ref":"#/components/schemas/FlowListItem"},"type":"array","title":"Flows","description":"The requested page of flows"},"total_count":{"type":"integer","title":"Total Count","description":"Rows matching the filter, across every page - not the number returned here","examples":[42]}},"type":"object","required":["total_count","account_id","flows"],"title":"FlowList"},"FlowListItem":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the flow"},"description":{"type":"string","title":"Description","description":"Flow description"},"id":{"type":"string","title":"Id","description":"Unique flow id"},"is_realtime":{"type":"boolean","title":"Is Realtime","description":"Whether the flow runs on a speech-to-speech model"},"llm":{"type":"string","title":"Llm","description":"Name of the model the flow uses, or 'none' for a flow that runs without one","examples":["gpt-4o"]},"logo_url":{"type":"string","title":"Logo Url","description":"URL of the model provider's logo, served by this deployment"},"name":{"type":"string","title":"Name","description":"Flow name","examples":["order-status"]},"widgets_count":{"type":"integer","title":"Widgets Count","description":"Nodes the flow holds"}},"type":"object","required":["id","account_id","name","description","llm","logo_url","is_realtime","widgets_count"],"title":"FlowListItem","description":"One row of the flow listing - a projection, not a whole flow."},"FlowModel":{"properties":{"_id":{"type":"string","title":"Id","description":"Assigned when the entity is created; a create that sends one of its own is rejected","readOnly":true},"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/FlowConfigAdvancedModel"},{"type":"null"}],"description":"Advanced configuration parameters"},"description":{"type":"string","title":"Description","description":"Flow description","default":""},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used by the flow.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)","default":""},"logs":{"anyOf":[{"type":"string","enum":["enabled","disabled","masked"]},{"type":"null"}],"title":"Logs","description":"Logging level for the agent","default":"enabled"},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max output tokens","description":"Maximum number of tokens in LLM response","default":1000},"max_turns":{"type":"integer","maximum":500.0,"minimum":1.0,"title":"Max utterances","description":"Maximum number of turns (user utterance / LLM response) in the conversation","default":50},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Flow name"},"post_call_analysis":{"items":{"type":"string"},"type":"array","title":"Post call analysis","description":"Post call analysis tools to be run at the end of the conversation"},"prompt":{"type":"string","title":"Prompt","description":"Global conversation flow prompt. Use {...} to reference variables.","default":""},"start_mode":{"$ref":"#/components/schemas/ConversationStart","title":"Conversation start","description":"Who starts the conversation","default":"llm"},"start_widget":{"type":"string","title":"Start node","description":"Node that starts the conversation","default":""},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"variables_str":{"type":"string","title":"Variables","description":"Variables that can be used in nodes; use \"NAME = VALUE\" format, for example: \"name = John\"; use multiple lines to specify multiple variables","default":""},"webhooks":{"anyOf":[{"items":{"$ref":"#/components/schemas/WebhookModel"},"type":"array"},{"type":"null"}],"title":"Webhooks","description":"Webhooks to be called during the flow execution"}},"type":"object","required":["name"],"title":"FlowModel"},"FlowResponse":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the flow"},"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/FlowConfigAdvancedModel"},{"type":"null"}],"description":"Configuration with no dedicated field of its own. Absent when the flow has none set"},"description":{"type":"string","title":"Description","description":"Flow description","default":""},"id":{"type":"string","title":"Id","description":"Unique flow id"},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used by the flow.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)","default":""},"logs":{"anyOf":[{"type":"string","enum":["enabled","disabled","masked"]},{"type":"null"}],"title":"Logs","description":"Logging level for the agent","default":"enabled"},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max output tokens","description":"Maximum number of tokens in LLM response","default":1000},"max_turns":{"type":"integer","maximum":500.0,"minimum":1.0,"title":"Max utterances","description":"Maximum number of turns (user utterance / LLM response) in the conversation","default":50},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Flow name"},"post_call_analysis":{"items":{"type":"string"},"type":"array","title":"Post call analysis","description":"Post call analysis tools to be run at the end of the conversation"},"prompt":{"type":"string","title":"Prompt","description":"Global conversation flow prompt. Use {...} to reference variables.","default":""},"start_mode":{"$ref":"#/components/schemas/ConversationStart","title":"Conversation start","description":"Who starts the conversation","default":"llm"},"start_widget":{"type":"string","title":"Start node","description":"Node that starts the conversation","default":""},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"variables_str":{"type":"string","title":"Variables","description":"Variables that can be used in nodes; use \"NAME = VALUE\" format, for example: \"name = John\"; use multiple lines to specify multiple variables","default":""},"webhooks":{"anyOf":[{"items":{"$ref":"#/components/schemas/WebhookModel"},"type":"array"},{"type":"null"}],"title":"Webhooks","description":"Webhooks to be called during the flow execution"}},"type":"object","required":["id","name","account_id"],"title":"FlowResponse","description":"A flow as create, update and clone return it. The nodes are not in it: they are a\nsub-resource, listed by `get_widgets`."},"FlowToolListItem":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the tool"},"auth_type":{"type":"string","title":"Auth Type","description":"How the tool authenticates - 'none', 'basic', 'bearer', 'oauth2', and so on. A projection of `auth.type`","examples":["bearer"]},"description":{"type":"string","title":"Description","description":"What the tool does. This is the text the model reads when deciding whether to call it"},"flow":{"type":"string","title":"Flow","description":"Name of the flow the tool runs - a name here, though the tool stores an id"},"id":{"type":"string","title":"Id","description":"Unique tool id"},"name":{"type":"string","title":"Name","description":"Tool name","examples":["lookup-order"]},"params_count":{"type":"integer","title":"Params Count","description":"Parameters the tool declares"},"type":{"type":"string","const":"flow","title":"Type"}},"type":"object","required":["id","account_id","name","description","auth_type","params_count","type","flow"],"title":"FlowToolListItem","description":"A row for a tool that runs a flow. It has no URL or method of its own."},"FlowUpdateModel":{"properties":{"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/FlowConfigAdvancedModel"},{"type":"null"}],"description":"Advanced configuration parameters"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Flow description"},"llm":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Large language model","description":"Large language model (LLM) used by the flow.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)"},"logs":{"anyOf":[{"type":"string","enum":["enabled","disabled","masked"]},{"type":"null"}],"title":"Logs","description":"Logging level for the agent"},"max_tokens":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Max output tokens","description":"Maximum number of tokens in LLM response"},"max_turns":{"anyOf":[{"type":"integer","maximum":500.0,"minimum":1.0},{"type":"null"}],"title":"Max utterances","description":"Maximum number of turns (user utterance / LLM response) in the conversation"},"name":{"anyOf":[{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$"},{"type":"null"}],"title":"Name","description":"Flow name"},"post_call_analysis":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Post call analysis","description":"Post call analysis tools to be run at the end of the conversation"},"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt","description":"Global conversation flow prompt. Use {...} to reference variables."},"start_mode":{"anyOf":[{"$ref":"#/components/schemas/ConversationStart"},{"type":"null"}],"title":"Conversation start","description":"Who starts the conversation"},"start_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start node","description":"Node that starts the conversation"},"temperature":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses"},"variables_str":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variables","description":"Variables that can be used in nodes; use \"NAME = VALUE\" format, for example: \"name = John\"; use multiple lines to specify multiple variables"},"webhooks":{"anyOf":[{"items":{"$ref":"#/components/schemas/WebhookModel"},"type":"array"},{"type":"null"}],"title":"Webhooks","description":"Webhooks to be called during the flow execution"}},"type":"object","title":"FlowUpdateModel"},"FlowWidgetModel":{"properties":{"_id":{"type":"string","title":"Id","description":"Assigned when the entity is created; a create that sends one of its own is rejected","readOnly":true},"data":{"oneOf":[{"$ref":"#/components/schemas/ConversationWidgetModel"},{"$ref":"#/components/schemas/ExtractWidgetModel"},{"$ref":"#/components/schemas/ConditionWidgetModel"},{"$ref":"#/components/schemas/EndCallWidgetModel"},{"$ref":"#/components/schemas/TransferCallWidgetModel"},{"$ref":"#/components/schemas/ToolWidgetModel"},{"$ref":"#/components/schemas/ApiWidgetModel"},{"$ref":"#/components/schemas/CalculateWidgetModel"},{"$ref":"#/components/schemas/PassWidgetModel"},{"$ref":"#/components/schemas/NoteWidgetModel"}],"title":"Data","discriminator":{"propertyName":"flavor","mapping":{"api":"#/components/schemas/ApiWidgetModel","calculate":"#/components/schemas/CalculateWidgetModel","condition":"#/components/schemas/ConditionWidgetModel","conversation":"#/components/schemas/ConversationWidgetModel","end_call":"#/components/schemas/EndCallWidgetModel","extract":"#/components/schemas/ExtractWidgetModel","note":"#/components/schemas/NoteWidgetModel","pass":"#/components/schemas/PassWidgetModel","tool":"#/components/schemas/ToolWidgetModel","transfer_call":"#/components/schemas/TransferCallWidgetModel"}}},"name":{"type":"string","title":"Name","default":""}},"type":"object","required":["data"],"title":"FlowWidgetModel"},"FlowWidgetUpdateModel":{"properties":{"data":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/StartWidgetUpdateModel"},{"$ref":"#/components/schemas/ConversationWidgetUpdateModel"},{"$ref":"#/components/schemas/ExtractWidgetUpdateModel"},{"$ref":"#/components/schemas/ConditionWidgetUpdateModel"},{"$ref":"#/components/schemas/EndCallWidgetUpdateModel"},{"$ref":"#/components/schemas/TransferCallWidgetUpdateModel"},{"$ref":"#/components/schemas/ToolWidgetUpdateModel"},{"$ref":"#/components/schemas/ApiWidgetUpdateModel"},{"$ref":"#/components/schemas/CalculateWidgetUpdateModel"},{"$ref":"#/components/schemas/PassWidgetUpdateModel"},{"$ref":"#/components/schemas/NoteWidgetUpdateModel"}],"discriminator":{"propertyName":"flavor","mapping":{"api":"#/components/schemas/ApiWidgetUpdateModel","calculate":"#/components/schemas/CalculateWidgetUpdateModel","condition":"#/components/schemas/ConditionWidgetUpdateModel","conversation":"#/components/schemas/ConversationWidgetUpdateModel","end_call":"#/components/schemas/EndCallWidgetUpdateModel","extract":"#/components/schemas/ExtractWidgetUpdateModel","note":"#/components/schemas/NoteWidgetUpdateModel","pass":"#/components/schemas/PassWidgetUpdateModel","start":"#/components/schemas/StartWidgetUpdateModel","tool":"#/components/schemas/ToolWidgetUpdateModel","transfer_call":"#/components/schemas/TransferCallWidgetUpdateModel"}}},{"type":"null"}],"title":"Node data","description":"The node's behaviour. Its shape follows `data.flavor` - see the variant schemas for what each node type accepts."},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Node name, as the canvas labels it. Renaming a node breaks nothing: other nodes point at its id, not its name."}},"type":"object","title":"FlowWidgetUpdateModel"},"GeminiAudioModel":{"properties":{"barge_in":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Barge In","description":"Whether the user starting to speak interrupts the model. Disable it for an agent that speaks over a conversation instead of taking turns in it"},"context_compression_target_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Context Compression Target Tokens","description":"The target number of tokens to keep for context window"},"context_compression_trigger_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Context Compression Trigger Tokens","description":"The number of tokens required to trigger context window compression"},"enable_affective_dialog":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enable Affective Dialog","description":"If enabled, the model will detect emotions and adapt its responses accordingly. Only for native-audio models."},"freeze_watch_timeout_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Freeze Watch Timeout Ms","description":"Timeout to detect model freeze and trigger session failover; applicable only for mixed VAD mode"},"model_version":{"anyOf":[{"type":"string","enum":["preview-09-2025","preview-12-2025"]},{"type":"null"}],"title":"Model Version","description":"Specific model version to be used"},"proactive_audio":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Proactive Audio","description":"If enabled, the model can reject responding to the last prompt. Only for native-audio models."},"thinking_budget":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Thinking Budget","description":"Thinking budget in tokens"},"top_k":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Top K","description":"For each token selection step, the top_k tokens with the highest probabilities are sampled"},"top_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Top P","description":"Tokens are selected from the most to least probable until the sum of their probabilities equals this value"},"vad_end_of_speech_sensitivity":{"anyOf":[{"type":"string","enum":["low","high"]},{"type":"null"}],"title":"Vad End Of Speech Sensitivity","description":"Determines how likely the end of speech is detected"},"vad_mode":{"anyOf":[{"type":"string","enum":["automatic","manual","mixed","silero"]},{"type":"null"}],"title":"Vad Mode","description":"VAD mode: \"automatic\" (Gemini), \"manual\" / \"mixed\" (external voiceDetected events), or \"silero\" (local Silero VAD)"},"vad_prefix_padding_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Vad Prefix Padding Ms","description":"The required duration of detected speech before start-of-speech is committed"},"vad_silence_duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Vad Silence Duration Ms","description":"The required duration of detected non-speech (e.g. silence) before end-of-speech is committed"},"vad_start_of_speech_sensitivity":{"anyOf":[{"type":"string","enum":["low","high"]},{"type":"null"}],"title":"Vad Start Of Speech Sensitivity","description":"Determines how likely speech is detected"},"voice":{"anyOf":[{"type":"string","enum":["Zephyr","Puck","Charon","Kore","Fenrir","Leda","Orus","Aoede","Callirrhoe","Autonoe","Enceladus","Iapetus","Umbriel","Algieba","Despina","Erinome","Algenib","Rasalgethi","Laomedeia","Achernar","Alnilam","Schedar","Gacrux","Pulcherrima","Achird","Zubenelgenubi","Vindemiatrix","Sadachbia","Sadaltager","Sulafat"]},{"type":"null"}],"title":"Voice","description":"Voice name"}},"type":"object","title":"GeminiAudioModel"},"GetConversationDataConfigModel":{"properties":{"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"tool":{"type":"string","const":"get_conversation_data","title":"Tool"}},"type":"object","required":["tool"],"title":"GetConversationDataConfigModel"},"GetCountersConfigModel":{"properties":{"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"tool":{"type":"string","const":"get_counters","title":"Tool"}},"type":"object","required":["tool"],"title":"GetCountersConfigModel"},"GetTimeConfigModel":{"properties":{"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"tool":{"type":"string","const":"get_time","title":"Tool"}},"type":"object","required":["tool"],"title":"GetTimeConfigModel"},"GrokVoiceModel":{"properties":{"eagerness":{"anyOf":[{"type":"string","enum":["low","medium","high","auto"]},{"type":"null"}],"title":"Eagerness","description":"Eagerness level for semantic VAD"},"prefix_padding_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Prefix Padding Ms","description":"Amount of audio to include before the VAD detected speech (in milliseconds) for server VAD"},"silence_duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Silence Duration Ms","description":"Duration of silence to wait before considering the speech finished (in milliseconds) for server VAD"},"threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Threshold","description":"Activation threshold for server VAD (0.0 to 1.0)"},"voice":{"anyOf":[{"type":"string","enum":["Ara","Rex","Sal","Eve","Leo"]},{"type":"null"}],"title":"Voice","description":"Voice name"}},"type":"object","title":"GrokVoiceModel"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HistoryDataModel":{"properties":{"from_name":{"type":"string","title":"From Name"},"label":{"type":"string","title":"Label"},"message":{"type":"string","title":"Message"},"next_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Widget"},"previous_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previous Widget"},"task_name":{"type":"string","title":"Task Name"},"time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Time"},"to_name":{"type":"string","title":"To Name"},"type":{"type":"string","title":"Type"},"visibility":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Visibility"}},"type":"object","required":["task_name","from_name","to_name","message","label","type"],"title":"HistoryDataModel"},"InactivityReminderModel":{"properties":{"repeat":{"anyOf":[{"type":"integer","maximum":10.0,"minimum":1.0},{"type":"null"}],"title":"Repeat","description":"Maximum number of reminders sent during a single silence period; default is 3, maximum is 10"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text","description":"Reminder text; supports {count}, {timeout} and {silence_time} variables"},"timeout":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Timeout","description":"Timeout (in milliseconds) of user silence after which inactivity reminder is sent to the model; feature is disabled when not set or set to 0"}},"type":"object","title":"InactivityReminderModel"},"IncompleteTurnModel":{"properties":{"instructions":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instructions","description":"Replaces the whole instructions block added to the prompt. Intended for AudioCodes support engineers fine-tuning the feature; text that drops a marker character silently disables detection"},"logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Logs","description":"Write an incomplete_turn log entry whenever a turn is judged incomplete (default: enabled)"},"long_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Long Prompt","description":"How the model should re-engage a user who asked for time to think"},"long_timeout":{"anyOf":[{"type":"integer","maximum":60000.0,"minimum":500.0},{"type":"null"}],"title":"Long Timeout","description":"Time (in milliseconds) to wait after the user asked for time to think before re-engaging; default is 10000"},"mode":{"type":"string","enum":["disabled","enabled"],"title":"Mode","description":"Incomplete turn detection mode"},"short_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Short Prompt","description":"How the model should re-engage a user who was cut off mid-sentence"},"short_timeout":{"anyOf":[{"type":"integer","maximum":60000.0,"minimum":500.0},{"type":"null"}],"title":"Short Timeout","description":"Time (in milliseconds) to wait after the user was cut off mid-sentence before re-engaging; default is 5000"}},"type":"object","required":["mode"],"title":"IncompleteTurnModel"},"IncrementCounterCallTransferModel":{"properties":{"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message","description":"Message to be played before the call transfer"},"name":{"type":"string","title":"Name","description":"Counter name"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone","description":"Phone number to transfer the call to"},"threshold":{"type":"integer","title":"Threshold","description":"Threshold value that triggers call transfer, default = 1","default":1}},"type":"object","required":["name"],"title":"IncrementCounterCallTransferModel"},"IncrementCounterConditionsModel":{"properties":{"counter":{"type":"string","title":"Counter","description":"Name of the dynamic counter to increment"},"patterns":{"items":{"type":"string"},"type":"array","title":"Patterns","description":"List of phrases to match"},"sender":{"$ref":"#/components/schemas/InrementCounterConditionsMessage","description":"Message sender"}},"type":"object","required":["sender","counter"],"title":"IncrementCounterConditionsModel"},"IncrementCounterConfigModel":{"properties":{"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"override_name":{"type":"string","title":"Override Name","description":"Override counter name specified by LLM","default":""},"tool":{"type":"string","const":"increment_counter","title":"Tool"}},"type":"object","required":["tool"],"title":"IncrementCounterConfigModel"},"InitConditionsModel":{"properties":{"agent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent","description":"Name of the agent to start the conversation (instead of the \"top-level\" agent)"},"config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Config","description":"Additional configuration parameters to be set during agent initialization; key = parameter name, value = parameter value"},"documents":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Documents","description":"List of document names that can be used by the agent; use it to \"filter\" available documents based on certain conditions"},"match":{"additionalProperties":{"type":"string"},"type":"object","title":"Match","description":"Match conditions; key = variable name or conversation data element (e.g. \"callee\"), value = expected value"},"variables":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Variables","description":"Additional variables to be set during agent initialization; key = variable name, value = variable value"}},"type":"object","title":"InitConditionsModel"},"InitToolModel":{"properties":{"extract":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Extract","description":"Variables to extract from tool response; key = variable name, value = extract expression"},"params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Params","description":"Tool parameters; key = parameter name, value = parameter value"},"response":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Response","description":"Add response to conversation context"},"tool":{"type":"string","title":"Tool","description":"Name of the tool"}},"type":"object","required":["tool"],"title":"InitToolModel"},"InrementCounterConditionsMessage":{"type":"string","enum":["llm","user"],"title":"InrementCounterConditionsMessage"},"LLMList":{"properties":{"models":{"items":{"$ref":"#/components/schemas/LLMListItem"},"type":"array","title":"Models","description":"The requested page of models"},"total_count":{"type":"integer","title":"Total Count","description":"Rows matching the filter, across every page - not the number returned here","examples":[42]}},"type":"object","required":["total_count","models"],"title":"LLMList"},"LLMListItem":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the model"},"id":{"type":"string","title":"Id","description":"Unique model id"},"is_realtime":{"type":"boolean","title":"Is Realtime","description":"Whether this is a speech-to-speech model, which an agent can use but a flow or a post-call analysis cannot"},"logo_url":{"type":"string","title":"Logo Url","description":"URL of the provider's logo, served by this deployment"},"model_name":{"type":"string","title":"Model Name","description":"Model name as the provider knows it","examples":["gpt-4o"]},"name":{"type":"string","title":"Name","description":"Model name","examples":["my-gpt-deployment"]},"provider":{"type":"string","title":"Provider","description":"Model provider","examples":["azure-openai"]},"provider_display_name":{"type":"string","title":"Provider Display Name","description":"The provider's name as the dashboard shows it"}},"type":"object","required":["id","account_id","name","provider","model_name","is_realtime","provider_display_name","logo_url"],"title":"LLMListItem","description":"One row of the model listing - a projection, not a whole model."},"LLMModel":{"properties":{"_id":{"type":"string","title":"Id","description":"Assigned when the entity is created; a create that sends one of its own is rejected","readOnly":true},"api_base":{"type":"string","title":"API base URL","description":"API base URL","default":""},"api_key":{"type":"string","title":"API key","description":"API key","default":""},"api_version":{"type":"string","title":"API version","description":"API version","default":""},"aws_access_key_id":{"type":"string","title":"AWS access key ID","description":"AWS access key ID","default":""},"aws_region_name":{"type":"string","title":"AWS region name","description":"AWS region name","default":""},"aws_secret_access_key":{"type":"string","title":"AWS secret access key","description":"AWS secret access key","default":""},"context_len":{"type":"integer","title":"Context length","description":"Context length (in tokens) for \"custom\" provider models","default":65535},"deployment_name":{"type":"string","title":"Deployment name","description":"Deployment name","default":""},"model_name":{"type":"string","title":"Model name","description":"Model name as recognized by the provider","default":""},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Model name"},"provider":{"type":"string","title":"Provider","description":"Model provider"},"streaming":{"type":"boolean","title":"Streaming","description":"Stream LLM responses for \"custom\" provider models (forced off when \"tools_api\" is \"n/a\")","default":true},"structured_output":{"type":"boolean","title":"Structured output","description":"\"custom\" provider model supports structured output (JSON schema response format)","default":true},"thought_delimiter":{"type":"string","title":"Thought delimiter","description":"For \"custom\" provider reasoning models that emit their chain-of-thought inline: the tag name that wraps the model's reasoning (\"thought\") block, e.g. \"think\" for a \"<think>...</think>\" block. The wrapped reasoning is stripped from the response, leaving only the actual reply. Leave empty if the model does not emit inline reasoning.","default":""},"tools_api":{"type":"string","enum":["tools","functions","n/a"],"title":"Tools API","description":"Tool-calling API for \"custom\" provider models: \"tools\" (OpenAI tools API), \"functions\" (legacy functions API) or \"n/a\" (no native tool calling)","default":"tools"},"vertex_key":{"type":"string","title":"API key","description":"API key for Vertex AI models","default":""},"vertex_key_name":{"type":"string","title":"API key name","description":"Name of the API key for Vertex AI models","default":""},"vertex_project_id":{"type":"string","title":"Google project ID","description":"Google project ID for Vertex AI models","default":""},"vertex_region":{"type":"string","title":"Region","description":"Region for Vertex AI models","default":""}},"type":"object","required":["name","provider"],"title":"LLMModel"},"LLMNotFound":{"type":"string","enum":["strict","fallback"],"title":"LLMNotFound"},"LLMResponse":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the model"},"api_base":{"type":"string","title":"API base URL","description":"API base URL","default":""},"api_key":{"type":"string","title":"API key","description":"API key","default":""},"api_version":{"type":"string","title":"API version","description":"API version","default":""},"aws_access_key_id":{"type":"string","title":"AWS access key ID","description":"AWS access key ID","default":""},"aws_region_name":{"type":"string","title":"AWS region name","description":"AWS region name","default":""},"aws_secret_access_key":{"type":"string","title":"AWS secret access key","description":"AWS secret access key","default":""},"context_len":{"type":"integer","title":"Context length","description":"Context length (in tokens) for \"custom\" provider models","default":65535},"deployment_name":{"type":"string","title":"Deployment name","description":"Deployment name","default":""},"id":{"type":"string","title":"Id","description":"Unique model id"},"model_name":{"type":"string","title":"Model name","description":"Model name as recognized by the provider","default":""},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Model name"},"provider":{"type":"string","title":"Provider","description":"Model provider"},"provider_display_name":{"type":"string","title":"Provider Display Name","description":"The provider's name as the dashboard shows it, e.g. 'Azure OpenAI' for 'azure-openai'","examples":["OpenAI"]},"streaming":{"type":"boolean","title":"Streaming","description":"Stream LLM responses for \"custom\" provider models (forced off when \"tools_api\" is \"n/a\")","default":true},"structured_output":{"type":"boolean","title":"Structured output","description":"\"custom\" provider model supports structured output (JSON schema response format)","default":true},"thought_delimiter":{"type":"string","title":"Thought delimiter","description":"For \"custom\" provider reasoning models that emit their chain-of-thought inline: the tag name that wraps the model's reasoning (\"thought\") block, e.g. \"think\" for a \"<think>...</think>\" block. The wrapped reasoning is stripped from the response, leaving only the actual reply. Leave empty if the model does not emit inline reasoning.","default":""},"tools_api":{"type":"string","enum":["tools","functions","n/a"],"title":"Tools API","description":"Tool-calling API for \"custom\" provider models: \"tools\" (OpenAI tools API), \"functions\" (legacy functions API) or \"n/a\" (no native tool calling)","default":"tools"},"vertex_key":{"type":"string","title":"API key","description":"API key for Vertex AI models","default":""},"vertex_key_name":{"type":"string","title":"API key name","description":"Name of the API key for Vertex AI models","default":""},"vertex_project_id":{"type":"string","title":"Google project ID","description":"Google project ID for Vertex AI models","default":""},"vertex_region":{"type":"string","title":"Region","description":"Region for Vertex AI models","default":""}},"type":"object","required":["id","name","provider","account_id","provider_display_name"],"title":"LLMResponse","description":"A model as create, get and update return it."},"LLMUpdateModel":{"properties":{"api_base":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"API base URL","description":"API base URL"},"api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"API key","description":"API key"},"api_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"API version","description":"API version"},"aws_access_key_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"AWS access key ID","description":"AWS access key ID"},"aws_region_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"AWS region name","description":"AWS region name"},"aws_secret_access_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"AWS secret access key","description":"AWS secret access key"},"context_len":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Context length","description":"Context length (in tokens) for \"custom\" provider models"},"deployment_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deployment name","description":"Deployment name"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model name","description":"Model name as recognized by the provider"},"name":{"anyOf":[{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$"},{"type":"null"}],"title":"Name","description":"Model name"},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider","description":"Model provider"},"streaming":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Streaming","description":"Stream LLM responses for \"custom\" provider models (forced off when \"tools_api\" is \"n/a\")"},"structured_output":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Structured output","description":"\"custom\" provider model supports structured output (JSON schema response format)"},"thought_delimiter":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thought delimiter","description":"For \"custom\" provider reasoning models that emit their chain-of-thought inline: the tag name that wraps the model's reasoning (\"thought\") block, e.g. \"think\" for a \"<think>...</think>\" block. The wrapped reasoning is stripped from the response, leaving only the actual reply. Leave empty if the model does not emit inline reasoning."},"tools_api":{"anyOf":[{"type":"string","enum":["tools","functions","n/a"]},{"type":"null"}],"title":"Tools API","description":"Tool-calling API for \"custom\" provider models: \"tools\" (OpenAI tools API), \"functions\" (legacy functions API) or \"n/a\" (no native tool calling)"},"vertex_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"API key","description":"API key for Vertex AI models"},"vertex_key_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"API key name","description":"Name of the API key for Vertex AI models"},"vertex_project_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Google project ID","description":"Google project ID for Vertex AI models"},"vertex_region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region","description":"Region for Vertex AI models"}},"type":"object","title":"LLMUpdateModel"},"LanguageDetectedModel":{"properties":{"ignore_phrases":{"items":{"type":"string"},"type":"array","title":"Ignore Phrases","description":"List of phrases to be ignored during language detection"},"pass_question":{"additionalProperties":{"type":"string"},"type":"object","title":"Pass Question","description":"Pass question to sub-agent upon language detection; key = language name (e.g. \"en-US\"); value = sub-agent name"}},"type":"object","title":"LanguageDetectedModel"},"LiveCommandAccepted":{"properties":{"status":{"type":"string","title":"Status","description":"Always 'accepted'","examples":["accepted"]}},"type":"object","required":["status"],"title":"LiveCommandAccepted","description":"The answer to a supervisor action on a live conversation.\n\n`accepted` is as strong as it gets: the action reached the platform carrying the call, and what\nthat platform does with it is not something this API can see. Hence 202 rather than 200."},"LiveConversationList":{"properties":{"live_conversations":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Live Conversations","description":"One entry per running conversation - its id, type, agent and caller, minus the routing internals"},"total_count":{"type":"integer","title":"Total Count","description":"Entries returned. There is no paging here: the set is small by nature"}},"type":"object","required":["live_conversations","total_count"],"title":"LiveConversationList","description":"The conversations running right now.\n\nEntries come from what is currently serving the conversations rather than from stored records, so\na conversation appears here while it is happening and is gone once it ends - at which point it\nturns up under `/conversations` instead."},"LogsModel":{"type":"string","enum":["inherit","enabled","disabled","masked"],"title":"LogsModel"},"McpTool":{"properties":{"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Always null here - an unreachable server or an unknown tool name is reported as a **400** instead"},"tool":{"anyOf":[{"$ref":"#/components/schemas/McpToolDetail"},{"type":"null"}],"description":"The named tool"}},"type":"object","required":["tool"],"title":"McpTool"},"McpToolDetail":{"properties":{"description":{"type":"string","title":"Description","description":"What the server says the tool does"},"name":{"type":"string","title":"Name","description":"Tool name, as the MCP server advertises it"},"params":{"items":{"$ref":"#/components/schemas/ToolTestParam"},"type":"array","title":"Params","description":"The tool's parameters, from its input schema"}},"type":"object","required":["name","description","params"],"title":"McpToolDetail","description":"One MCP tool with its parameter schema, translated into the same parameter shape the REST\ntesting endpoints use."},"McpToolList":{"properties":{"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Always null here - a server that could not be reached is reported as a **400** instead"},"tools":{"items":{"$ref":"#/components/schemas/McpToolSummary"},"type":"array","title":"Tools","description":"The tools this tool exposes - what the server advertises, narrowed by the tool's own `mcp_tools` allow-list where it sets one"}},"type":"object","required":["tools"],"title":"McpToolList"},"McpToolListItem":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the tool"},"auth_type":{"type":"string","title":"Auth Type","description":"How the tool authenticates - 'none', 'basic', 'bearer', 'oauth2', and so on. A projection of `auth.type`","examples":["bearer"]},"description":{"type":"string","title":"Description","description":"What the tool does. This is the text the model reads when deciding whether to call it"},"id":{"type":"string","title":"Id","description":"Unique tool id"},"name":{"type":"string","title":"Name","description":"Tool name","examples":["lookup-order"]},"params_count":{"type":"integer","title":"Params Count","description":"Parameters the tool declares"},"type":{"type":"string","const":"mcp","title":"Type"},"url":{"type":"string","title":"Url","description":"The MCP server's URL"}},"type":"object","required":["id","account_id","name","description","auth_type","params_count","type","url"],"title":"McpToolListItem","description":"A row for a tool backed by an MCP server."},"McpToolSummary":{"properties":{"description":{"type":"string","title":"Description","description":"What the server says the tool does"},"name":{"type":"string","title":"Name","description":"Tool name, as the MCP server advertises it"}},"type":"object","required":["name","description"],"title":"McpToolSummary","description":"One tool advertised by an MCP server, name and description only."},"NoteWidgetModel":{"properties":{"flavor":{"type":"string","const":"note","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"text":{"type":"string","title":"Text","description":"The note text","default":""},"width":{"type":"number","title":"Width","description":"The node width in pixels","default":200}},"type":"object","required":["flavor"],"title":"NoteWidgetModel"},"NoteWidgetUpdateModel":{"properties":{"flavor":{"type":"string","const":"note","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text","description":"The note text"},"width":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Width","description":"The node width in pixels"}},"type":"object","required":["flavor"],"title":"NoteWidgetUpdateModel"},"NovaSonicModel":{"properties":{"endpointing_sensitivity":{"anyOf":[{"type":"string","enum":["low","medium","high"]},{"type":"null"}],"title":"Endpointing Sensitivity","description":"Configures turn detection sensitivity"},"top_k":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Top K","description":"Only sample from the top K options for each subsequent token"},"top_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Top P","description":"The percentage of most-likely candidates that the model considers for the next token"},"voice":{"anyOf":[{"type":"string","enum":["tiffany","matthew","amy","olivia","kiara","arjun","ambre","florian","beatrice","lorenzo","greta","tina","lennart","lupe","carlos","carolina","leo"]},{"type":"null"}],"title":"Voice","description":"Voice name"}},"type":"object","title":"NovaSonicModel"},"NumbersSequenceMode":{"type":"string","enum":["auto","join","sum"],"title":"NumbersSequenceMode"},"NumbersSequenceModel":{"properties":{"mode":{"anyOf":[{"$ref":"#/components/schemas/NumbersSequenceMode"},{"type":"null"}],"description":"How to process numbers sequence in user utterance"},"prefixes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Prefixes","description":"Prefixes after which numbers sequence should be processed"}},"type":"object","title":"NumbersSequenceModel"},"OpenAIRealtimeModel":{"properties":{"eagerness":{"anyOf":[{"type":"string","enum":["low","medium","high","auto"]},{"type":"null"}],"title":"Eagerness","description":"Eagerness level for semantic VAD"},"input_audio_noise_reduction":{"anyOf":[{"type":"string","enum":["near_field","far_field"]},{"type":"null"}],"title":"Input Audio Noise Reduction","description":"Input audio noise reduction"},"input_audio_transcription_language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Input Audio Transcription Language","description":"Language for input audio transcription; use ISO 639-1 code (e.g. \"en\" for English, \"fr\" for French)"},"input_audio_transcription_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Input Audio Transcription Prompt","description":"Input audio transcription model prompt"},"prefix_padding_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Prefix Padding Ms","description":"Amount of audio to include before the VAD detected speech (in milliseconds) for server VAD"},"silence_duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Silence Duration Ms","description":"Duration of silence to wait before considering the speech finished (in milliseconds) for server VAD"},"threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Threshold","description":"Activation threshold for server VAD (0.0 to 1.0)"},"turn_detection":{"anyOf":[{"type":"string","enum":["server_vad","semantic_vad"]},{"type":"null"}],"title":"Turn Detection","description":"Turn detection mode"},"voice":{"anyOf":[{"type":"string","enum":["alloy","ash","ballad","coral","echo","sage","shimmer","verse","marin","cedar"]},{"type":"null"}],"title":"Voice","description":"Voice name"}},"type":"object","title":"OpenAIRealtimeModel"},"OrchestrationMode":{"type":"string","enum":["consult","consult_with_history","delegate","delegate_with_history"],"title":"OrchestrationMode"},"PassQuestionConfigModel":{"properties":{"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"tool":{"type":"string","const":"pass_question","title":"Tool"}},"type":"object","required":["tool"],"title":"PassQuestionConfigModel"},"PassWidgetModel":{"properties":{"agent":{"type":"string","title":"Agent name","description":"Agent to pass the call to","default":""},"flavor":{"type":"string","const":"pass","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"flow":{"type":"string","title":"Flow name","description":"Flow to pass the call to (ignored when agent is set)","default":""},"global_condition":{"type":"string","title":"Global condition","description":"Describe conditions to transition to this node","default":""},"global_widget":{"type":"boolean","title":"Global node","description":"Allow other nodes to transition to this node without edges","default":false},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"message":{"type":"string","title":"Pass message","description":"Message to be passed instead of the last user utterance","default":""},"share_history":{"type":"boolean","title":"Share history","description":"Share conversation history with the target agent or flow","default":false}},"type":"object","required":["flavor"],"title":"PassWidgetModel"},"PassWidgetUpdateModel":{"properties":{"agent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent name","description":"Agent to pass the call to"},"flavor":{"type":"string","const":"pass","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"flow":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flow name","description":"Flow to pass the call to (ignored when agent is set)"},"global_condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Global condition","description":"Describe conditions to transition to this node"},"global_widget":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Global node","description":"Allow other nodes to transition to this node without edges"},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pass message","description":"Message to be passed instead of the last user utterance"},"share_history":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Share history","description":"Share conversation history with the target agent or flow"}},"type":"object","required":["flavor"],"title":"PassWidgetUpdateModel"},"PdfParserAdvancedModel":{"properties":{"detect_tables":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Detect Tables","description":"Whether we should format detected tables When `true` (default), detected tables are rendered as Markdown tables. Set `false` to keep them as flowing text."},"strip_running_headers":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Strip Running Headers","description":"When `true` (default), repeated text near the top/bottom margins of the page (running headers/footers/page numbers) is removed."}},"type":"object","title":"PdfParserAdvancedModel"},"PlayUrlConfigModel":{"properties":{"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"format":{"type":"string","title":"Format","description":"Audio format to be used; default = \"wav/lpcm16\"","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"tool":{"type":"string","const":"play_url","title":"Tool"}},"type":"object","required":["tool"],"title":"PlayUrlConfigModel"},"PostCallAnalysisAuthModel":{"properties":{"token":{"type":"string","title":"Bearer key","description":"Bearer token","default":""},"type":{"type":"string","title":"Authentication","description":"Authentication type"}},"type":"object","required":["type"],"title":"PostCallAnalysisAuthModel"},"PostCallAnalysisConfigModel":{"properties":{"conditions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Conditions","description":"Conditions for running post-call analysis"},"include_logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Include Logs","description":"Include logs in post-call analysis transcript"},"join":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Join","description":"Join data from all post-call analysis instances into a single webhook call"},"last_agent":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Last Agent","description":"For multi-agent topologies run the post-call analysis on the agent that finishes the call"},"no_user_input":{"anyOf":[{"type":"string","enum":["keep","drop"]},{"type":"null"}],"title":"No User Input","description":"How to handle NO-USER-INPUT in the transcript"},"timeout":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Timeout","description":"Timeout in seconds for the LLM call during post-call analysis"},"transcript_format":{"anyOf":[{"type":"string","enum":["text","json"]},{"type":"null"}],"title":"Transcript Format","description":"Format of the transcript for post-call analysis"},"webhook_content":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Webhook Content","description":"Custom content for webhook calls; key = PCA name, value = body content"},"webhook_headers":{"anyOf":[{"additionalProperties":{"additionalProperties":{"type":"string"},"type":"object"},"type":"object"},{"type":"null"}],"title":"Webhook Headers","description":"Custom headers for webhook calls; key = PCA name, value = dict of header keys and values"}},"type":"object","title":"PostCallAnalysisConfigModel"},"PostCallAnalysisData":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account the conversation belongs to"},"agent":{"type":"string","title":"Agent","description":"Name of the agent or flow that handled the conversation"},"callee":{"type":"string","title":"Callee","description":"Called party","default":""},"caller":{"type":"string","title":"Caller","description":"Calling party","default":""},"id":{"type":"string","title":"Id","description":"Id of the conversation the analysis ran on"},"results":{"items":{"$ref":"#/components/schemas/PostCallAnalysisResultModel"},"type":"array","title":"Results","description":"One entry per definition that ran, its output under `data`. `type` says how to read it: a `transcript` carries the conversation, a `summarize` its summary under `output`, and an `extract` the variables it pulled out. An `insights` definition reports as `extract`, since that is what it does"},"time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string"}],"title":"Time","description":"When the analysis ran"}},"type":"object","required":["id","account_id","time","agent"],"title":"PostCallAnalysisData","description":"Everything the post-call analyses produced for one conversation."},"PostCallAnalysisDataList":{"properties":{"post_call_analysis_data":{"items":{"$ref":"#/components/schemas/PostCallAnalysisDataListItem"},"type":"array","title":"Post Call Analysis Data","description":"The requested page of results, newest first by default"},"total_count":{"type":"integer","title":"Total Count","description":"Rows matching the filter, across every page - not the number returned here","examples":[42]}},"type":"object","required":["total_count","post_call_analysis_data"],"title":"PostCallAnalysisDataList"},"PostCallAnalysisDataListItem":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account the conversation belongs to"},"agent":{"type":"string","title":"Agent","description":"Name of the agent or flow that handled the conversation"},"callee":{"type":"string","title":"Callee","description":"Called party"},"caller":{"type":"string","title":"Caller","description":"Calling party"},"id":{"type":"string","title":"Id","description":"Id of the conversation the analysis ran on - this is what addresses the result"},"names":{"type":"string","title":"Names","description":"Comma-separated names of the definitions that produced results, as a hint of what the full record holds","examples":["call-summary,extract-order"]},"time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string"}],"title":"Time","description":"When the analysis ran"}},"type":"object","required":["id","account_id","time","agent","caller","callee","names"],"title":"PostCallAnalysisDataListItem","description":"One row of the results listing, keyed by the conversation the analysis ran on."},"PostCallAnalysisDataTypeModel":{"properties":{"description":{"type":"string","title":"Description","description":"Variable description"},"display_name":{"type":"string","title":"Display name","description":"Optional human-friendly name for the insight variable","default":""},"name":{"type":"string","title":"Name","description":"Variable name"},"required":{"type":"boolean","title":"Required","description":"Whether the variable is required","default":true},"type":{"type":"string","title":"Type","description":"Variable type"}},"type":"object","required":["name","type","description"],"title":"PostCallAnalysisDataTypeModel"},"PostCallAnalysisFlowConfigModel":{"properties":{"conditions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Conditions","description":"Conditions for running post-call analysis"},"include_logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Include Logs","description":"Include logs in post-call analysis transcript"},"join":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Join","description":"Join data from all post-call analysis instances into a single webhook call"}},"type":"object","title":"PostCallAnalysisFlowConfigModel"},"PostCallAnalysisList":{"properties":{"post_call_analysis":{"items":{"$ref":"#/components/schemas/PostCallAnalysisListItem"},"type":"array","title":"Post Call Analysis","description":"The requested page of post-call analysis definitions"},"total_count":{"type":"integer","title":"Total Count","description":"Rows matching the filter, across every page - not the number returned here","examples":[42]}},"type":"object","required":["total_count","post_call_analysis"],"title":"PostCallAnalysisList"},"PostCallAnalysisListItem":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns it"},"auth_type":{"type":"string","title":"Auth Type","description":"How the webhook authenticates - a projection of `auth.type`","examples":["none"]},"description":{"type":"string","title":"Description","description":"What it is for"},"id":{"type":"string","title":"Id","description":"Unique post-call analysis id"},"is_realtime":{"type":"boolean","title":"Is Realtime","description":"Whether that model is a speech-to-speech one - which post-call analysis cannot use, so this flags a broken definition"},"llm":{"type":"string","title":"Llm","description":"Name of the model it runs on, resolved even where a custom model is stored by id. Empty for 'transcript', which runs no model"},"name":{"type":"string","title":"Name","description":"Post-call analysis name","examples":["call-summary"]},"params_count":{"type":"integer","title":"Params Count","description":"Variables the definition extracts"},"type":{"type":"string","title":"Type","description":"What it produces - 'extract', 'summarize', 'insights' or 'transcript'","examples":["summarize"]},"webHookUrl":{"type":"string","title":"Webhookurl","description":"Where the result is posted, if anywhere"}},"type":"object","required":["id","account_id","name","description","type","llm","is_realtime","webHookUrl","auth_type","params_count"],"title":"PostCallAnalysisListItem","description":"One row of the post-call analysis listing - a projection, not a whole definition."},"PostCallAnalysisModel":{"properties":{"_id":{"type":"string","title":"Id","description":"Assigned when the entity is created; a create that sends one of its own is rejected","readOnly":true},"auth":{"$ref":"#/components/schemas/PostCallAnalysisAuthModel","title":"Authentication","description":"Authentication type"},"description":{"type":"string","title":"Description","description":"Post call analysis description","default":""},"extract_prompt":{"type":"string","title":"Extract prompt","description":"Prompt for variables extraction. If empty - default extraction prompt is used.","default":""},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used for post call analysis. Required for all types except \"transcript\".\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)","default":""},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max tokens","description":"Maximum number of tokens for LLM output","default":1024},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Post call analysis name"},"params":{"items":{"$ref":"#/components/schemas/PostCallAnalysisDataTypeModel"},"type":"array","title":"Variables","description":"Variables to be extracted"},"prompt":{"type":"string","title":"Prompt","description":"Prompt for post call analysis","default":""},"summarize_prompt":{"type":"string","title":"Summarize prompt","description":"Prompt for call summarization. If empty - default summarization prompt is used.","default":""},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"type":{"$ref":"#/components/schemas/PostCallAnalysisType","title":"Type","description":"Post call analysis type","default":"extract"},"webHookUrl":{"type":"string","title":"Webhook URL","description":"Webhook URL","default":""}},"type":"object","required":["name"],"title":"PostCallAnalysisModel"},"PostCallAnalysisResponse":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns it"},"auth":{"$ref":"#/components/schemas/PostCallAnalysisAuthModel","title":"Authentication","description":"Authentication type"},"description":{"type":"string","title":"Description","description":"Post call analysis description","default":""},"extract_prompt":{"type":"string","title":"Extract prompt","description":"Prompt for variables extraction. If empty - default extraction prompt is used.","default":""},"id":{"type":"string","title":"Id","description":"Unique post-call analysis id"},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used for post call analysis. Required for all types except \"transcript\".\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)","default":""},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max tokens","description":"Maximum number of tokens for LLM output","default":1024},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Post call analysis name"},"params":{"items":{"$ref":"#/components/schemas/PostCallAnalysisDataTypeModel"},"type":"array","title":"Variables","description":"Variables to be extracted"},"prompt":{"type":"string","title":"Prompt","description":"Prompt for post call analysis","default":""},"summarize_prompt":{"type":"string","title":"Summarize prompt","description":"Prompt for call summarization. If empty - default summarization prompt is used.","default":""},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"type":{"$ref":"#/components/schemas/PostCallAnalysisType","title":"Type","description":"Post call analysis type","default":"extract"},"webHookUrl":{"type":"string","title":"Webhook URL","description":"Webhook URL","default":""}},"type":"object","required":["id","name","account_id"],"title":"PostCallAnalysisResponse","description":"A post-call analysis as create, get, update and clone return it."},"PostCallAnalysisResultModel":{"properties":{"data":{"additionalProperties":true,"type":"object","title":"Data"},"name":{"type":"string","title":"Name"},"time":{"type":"string","format":"date-time","title":"Time"},"type":{"anyOf":[{"type":"string","enum":["extract","summarize","transcript"]},{"type":"null"}],"title":"Type"}},"type":"object","required":["name"],"title":"PostCallAnalysisResultModel"},"PostCallAnalysisType":{"type":"string","enum":["extract","summarize","transcript","insights"],"title":"PostCallAnalysisType"},"PostCallAnalysisUpdateModel":{"properties":{"auth":{"anyOf":[{"$ref":"#/components/schemas/PostCallAnalysisAuthModel"},{"type":"null"}],"title":"Authentication","description":"Authentication type"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Post call analysis description"},"extract_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extract prompt","description":"Prompt for variables extraction. If empty - default extraction prompt is used."},"llm":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Large language model","description":"Large language model (LLM) used for post call analysis. Required for all types except \"transcript\".\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)"},"max_tokens":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Max tokens","description":"Maximum number of tokens for LLM output"},"name":{"anyOf":[{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$"},{"type":"null"}],"title":"Name","description":"Post call analysis name"},"params":{"anyOf":[{"items":{"$ref":"#/components/schemas/PostCallAnalysisDataTypeModel"},"type":"array"},{"type":"null"}],"title":"Variables","description":"Variables to be extracted"},"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt","description":"Prompt for post call analysis"},"summarize_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summarize prompt","description":"Prompt for call summarization. If empty - default summarization prompt is used."},"temperature":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses"},"type":{"anyOf":[{"$ref":"#/components/schemas/PostCallAnalysisType"},{"type":"null"}],"title":"Type","description":"Post call analysis type"},"webHookUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook URL","description":"Webhook URL"}},"type":"object","title":"PostCallAnalysisUpdateModel"},"PredefinedTool":{"properties":{"category":{"type":"string","title":"Category","description":"What the tool is for, as the dashboard groups them","examples":["Call control"]},"deprecation_notice":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deprecation Notice","description":"What to use in place of this tool, where it has been superseded. The tool keeps working. Absent on tools in normal use, which is how a client tells the two apart","examples":["Use the `current_datetime` variable instead."]},"description":{"type":"string","title":"Description","description":"What the tool does"},"name":{"type":"string","title":"Name","description":"What an agent references the tool by","examples":["transfer_call"]}},"type":"object","required":["name","description","category"],"title":"PredefinedTool","description":"Pre-defined tool."},"PredefinedToolList":{"properties":{"tools":{"items":{"$ref":"#/components/schemas/PredefinedTool"},"type":"array","title":"Tools","description":"Every pre-defined tool, grouped by category"}},"type":"object","required":["tools"],"title":"PredefinedToolList","description":"List of pre-defined tools."},"PredeployedModel":{"properties":{"input_cost_per_million":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Input Cost Per Million","description":"Price per million input tokens, in US dollars"},"intelligence_index":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Intelligence Index","description":"Artificial Analysis Intelligence Index. A model carries this or `s2s_index`, never both"},"is_realtime":{"type":"boolean","title":"Is Realtime","description":"Whether this is a speech-to-speech model"},"latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency Ms","description":"Response latency as last probed, in milliseconds"},"name":{"type":"string","title":"Name","description":"What an agent, flow or post-call analysis references the model by","examples":["gpt-4o"]},"output_cost_per_million":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Output Cost Per Million","description":"Price per million output tokens, in US dollars"},"s2s_index":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"S2S Index","description":"Artificial Analysis Speech to Speech Index, as a percentage - the realtime counterpart of `intelligence_index`"}},"type":"object","required":["name","is_realtime"],"title":"PredeployedModel","description":"Pre-deployed LLM model."},"PredeployedModelList":{"properties":{"models":{"items":{"$ref":"#/components/schemas/PredeployedModel"},"type":"array","title":"Models","description":"Every pre-deployed model"}},"type":"object","required":["models"],"title":"PredeployedModelList","description":"List of pre-deployed LLM models."},"PrerecordedAudioConfigModel":{"properties":{"format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Format","description":"Audio format to be used; default = \"wav/lpcm16\""},"phrases":{"additionalProperties":{"type":"string"},"type":"object","title":"Phrases","description":"LLM response phrases that are replaced by prerecorded audio files; key = phrase, value = audio file ID or name"}},"type":"object","required":["phrases"],"title":"PrerecordedAudioConfigModel"},"ProgressMessageConditionModel":{"properties":{"condition":{"type":"string","title":"Condition","description":"Condition for playing the progress message - tool name or \"enter\""},"messages":{"items":{"type":"string"},"type":"array","title":"Messages","description":"Progress message to be played; if more than one message is specified - message will be selected randomly"}},"type":"object","required":["condition","messages"],"title":"ProgressMessageConditionModel"},"PromptHistoryItem":{"properties":{"created_at":{"type":"string","format":"date-time","title":"Created At","description":"When this version took effect"},"id":{"type":"string","title":"Id","description":"Unique id of this history entry"},"prompt":{"type":"string","title":"Prompt","description":"The prompt text of this version"}},"type":"object","required":["id","prompt","created_at"],"title":"PromptHistoryItem","description":"One version of an agent's prompt."},"RedactToolResponse":{"type":"string","enum":["keep","redact"],"title":"RedactToolResponse"},"RestToolListItem":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the tool"},"auth_type":{"type":"string","title":"Auth Type","description":"How the tool authenticates - 'none', 'basic', 'bearer', 'oauth2', and so on. A projection of `auth.type`","examples":["bearer"]},"description":{"type":"string","title":"Description","description":"What the tool does. This is the text the model reads when deciding whether to call it"},"id":{"type":"string","title":"Id","description":"Unique tool id"},"method":{"type":"string","title":"Method","description":"HTTP method. Only a REST tool has one","examples":["POST"]},"name":{"type":"string","title":"Name","description":"Tool name","examples":["lookup-order"]},"params_count":{"type":"integer","title":"Params Count","description":"Parameters the tool declares"},"type":{"type":"string","const":"rest","title":"Type"},"url":{"type":"string","title":"Url","description":"Request URL, with any `{...}` references left as they are"}},"type":"object","required":["id","account_id","name","description","auth_type","params_count","type","method","url"],"title":"RestToolListItem","description":"A row for a tool that calls a REST endpoint."},"ScriptedLLMModel":{"properties":{"default":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default","description":"Fallback response when nothing matches"},"rules":{"anyOf":[{"items":{"$ref":"#/components/schemas/ScriptedLLMRuleModel"},"type":"array"},{"type":"null"}],"title":"Rules","description":"Match rules in priority order"},"sequence":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Sequence","description":"Sequenced (FIFO) responses for unmatched calls"}},"type":"object","title":"ScriptedLLMModel","description":"Configuration for `agent_flavor='scripted'`.\n\nLookup order on each LLM call:\n  1. rules with match_type='exact' matching user's last message (case-insensitive)\n  2. rules with match_type='regex' matching user's last message\n  3. sequence — FIFO, consume one entry per call\n  4. default — fallback"},"ScriptedLLMRuleModel":{"properties":{"delay_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Delay Ms","description":"Delay before returning this rule's response, in milliseconds"},"match":{"type":"string","title":"Match","description":"Utterance or regex to match against the last user message","default":""},"match_type":{"anyOf":[{"type":"string","enum":["exact","regex"]},{"type":"null"}],"title":"Match Type","description":"How to match against the user message; default = \"exact\""},"reply":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reply","description":"Response text the LLM \"says\""},"tool":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool","description":"Optional tool call to emit instead of/along with text"},"tool_args":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tool Args","description":"Arguments for the tool call"}},"type":"object","title":"ScriptedLLMRuleModel"},"SendMessageConfigModel":{"properties":{"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"tool":{"type":"string","const":"send_message","title":"Tool"}},"type":"object","required":["tool"],"title":"SendMessageConfigModel"},"SendMessageRequestModel":{"properties":{"message":{"type":"string","title":"Message","description":"Message to play into the conversation"}},"type":"object","required":["message"],"title":"SendMessageRequestModel"},"SendMetadataToolModel":{"properties":{"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Description of the send metadata tool"},"name":{"type":"string","title":"Name","description":"Name of the send metadata tool"},"params":{"anyOf":[{"items":{"$ref":"#/components/schemas/ToolParamModel"},"type":"array"},{"type":"null"}],"title":"Params","description":"Parameters the LLM must provide when calling the tool; the supplied values are emitted as the \"data\" of the \"sendMetaData\" event"}},"type":"object","required":["name"],"title":"SendMetadataToolModel"},"SessionParamsToolModel":{"properties":{"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Description of the session parameters tool"},"name":{"type":"string","title":"Name","description":"Name of the session parameters tool"},"session_params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Session Params","description":"Session parameters; key = parameter name, value = parameter value"}},"type":"object","required":["name"],"title":"SessionParamsToolModel"},"SessionReminderModel":{"properties":{"duration":{"type":"integer","title":"Duration","description":"Duration of the session (in seconds) after which reminder is sent"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text","description":"Reminder text; include some prefix like \"REMINDER:\" so that LLM can distinguish it from user utterance"}},"type":"object","required":["duration"],"title":"SessionReminderModel"},"SetCounterConfigModel":{"properties":{"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"tool":{"type":"string","const":"set_counter","title":"Tool"}},"type":"object","required":["tool"],"title":"SetCounterConfigModel"},"SileroVadModel":{"properties":{"debug":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Debug","description":"Enable debug data collection for VAD threshold tuning"},"min_speech_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Speech Ms","description":"Minimum speech duration (ms) required before confirming speech start"},"negative_speech_threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Negative Speech Threshold","description":"Threshold below which a frame is considered non-speech"},"positive_speech_threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Positive Speech Threshold","description":"Threshold above which a frame is considered speech"},"pre_speech_pad_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pre Speech Pad Ms","description":"Amount of pre-speech audio (ms) to prepend when speech starts"},"redemption_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Redemption Ms","description":"Duration of consecutive non-speech before ending speech segment"}},"type":"object","title":"SileroVadModel"},"SipHeadersModel":{"properties":{"name":{"type":"string","title":"Name","description":"SIP header name"},"value":{"type":"string","title":"Value","description":"SIP header value; use \"{...}\" to include variables or conversation data"}},"type":"object","required":["name","value"],"title":"SipHeadersModel"},"StartTestModel":{"properties":{"iterations":{"anyOf":[{"type":"integer","maximum":10.0,"minimum":1.0},{"type":"null"}],"title":"Iterations","description":"Number of test iterations (1-10)"},"test_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Name"}},"type":"object","title":"StartTestModel"},"StartWidgetResponse":{"properties":{"data":{"$ref":"#/components/schemas/StartWidgetUpdateModel"},"id":{"type":"string","title":"Id","description":"The flow's id, which is what addresses this node"},"name":{"type":"string","const":"start","title":"Name"}},"type":"object","required":["id","name","data"],"title":"StartWidgetResponse","description":"The flow's `start` node.\n\nSynthesized rather than stored: there is no node behind it, so it carries no `account_id` or\n`flow`, and its id is the **flow's** id. All it holds is where the conversation begins, which\nis the flow's own `start_widget` under another name."},"StartWidgetUpdateModel":{"properties":{"flavor":{"type":"string","const":"start","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"next_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next node","description":"Id of the node the conversation begins at. Node references are ids, not names - the flow runtime looks the node up by it directly."}},"type":"object","required":["flavor"],"title":"StartWidgetUpdateModel"},"TestParamModel":{"properties":{"name":{"type":"string","title":"Name","description":"Parameter name"},"value":{"title":"Value","description":"Parameter value"}},"type":"object","required":["name"],"title":"TestParamModel"},"TestRunCancelled":{"properties":{"message":{"type":"string","title":"Message","description":"Human-readable confirmation"},"status":{"type":"string","title":"Status","description":"Always `cancelled`","examples":["cancelled"]}},"type":"object","required":["status","message"],"title":"TestRunCancelled","description":"The runtime's answer to a cancel request, passed through as it comes."},"TestRunList":{"properties":{"tests":{"items":{"$ref":"#/components/schemas/TestRunListItem"},"type":"array","title":"Tests","description":"The requested page of runs, newest first by default"},"total_count":{"type":"integer","title":"Total Count","description":"Rows matching the filter, across every page - not the number returned here","examples":[42]}},"type":"object","required":["total_count","tests"],"title":"TestRunList"},"TestRunListItem":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account the run belongs to"},"agent":{"type":"string","title":"Agent","description":"Id of the agent or flow that was tested"},"agent_name":{"type":"string","title":"Agent Name","description":"Name of that agent or flow"},"completion_status":{"type":"string","title":"Completion Status","description":"The same state with progress appended, for display"},"end_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string"}],"title":"End Time","description":"When it finished, empty while it is still running"},"id":{"type":"string","title":"Id","description":"Unique run id"},"name":{"type":"string","title":"Name","description":"The suite's name at the time of the run"},"start_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string"}],"title":"Start Time","description":"When the run started"},"target_type":{"type":"string","title":"Target Type","description":"Whether the target was an 'agent' or a 'flow'"},"test_status":{"type":"string","title":"Test Status","description":"Where the run is","examples":["completed"]},"test_suite_id":{"type":"string","title":"Test Suite Id","description":"Suite the run belongs to"},"total_failed":{"type":"integer","title":"Total Failed","description":"Tests that failed"},"total_passed":{"type":"integer","title":"Total Passed","description":"Tests that passed"},"total_warning":{"type":"integer","title":"Total Warning","description":"Tests that passed with reservations"}},"type":"object","required":["id","test_suite_id","name","account_id","start_time","end_time","agent","agent_name","target_type","test_status","completion_status","total_passed","total_warning","total_failed"],"title":"TestRunListItem","description":"One row of the runs listing - the same shape as a single run, minus the per-test outcomes."},"TestRunRequestModel":{"properties":{"mcp_tool_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mcp Tool Name","description":"For MCP tools: name of the MCP tool to invoke"},"params":{"items":{"$ref":"#/components/schemas/TestParamModel"},"type":"array","title":"Params","description":"Parameter values for the test"},"tool":{"anyOf":[{"$ref":"#/components/schemas/ToolModel"},{"type":"null"}],"description":"Optional in-memory tool definition; when provided, used instead of the saved tool"}},"type":"object","title":"TestRunRequestModel"},"TestRunResult":{"properties":{"details":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Details","description":"What the judging model said about it"},"name":{"type":"string","title":"Name","description":"Test name, as the suite declares it"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status","description":"How it ended - 'passed', 'warning' or 'failed'"}},"type":"object","required":["name"],"title":"TestRunResult","description":"One test's outcome within a run."},"TestRunStarted":{"properties":{"_id":{"type":"string","title":"Id","description":"Id of the run that has just started. This is what the status and cancel operations take"},"message":{"type":"string","title":"Message","description":"Human-readable confirmation"},"status":{"type":"string","title":"Status","description":"Always `started` - a run that could not start is an error status","examples":["started"]}},"type":"object","required":["_id","status","message"],"title":"TestRunStarted","description":"The answer to a start request, passed through from whatever will run the tests.\n\nNote `_id` rather than `id`: this body is not built by the configuration API, and it is forwarded\nunchanged."},"TestRunStatus":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account the run belongs to"},"agent":{"type":"string","title":"Agent","description":"Id of the agent or flow that was tested"},"agent_name":{"type":"string","title":"Agent Name","description":"Name of that agent or flow"},"completion_status":{"type":"string","title":"Completion Status","description":"The same state with progress appended, for display","examples":["completed - 100%"]},"end_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string"}],"title":"End Time","description":"When it finished, empty while it is still running"},"id":{"type":"string","title":"Id","description":"Unique run id"},"name":{"type":"string","title":"Name","description":"The suite's name at the time of the run"},"start_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"string"}],"title":"Start Time","description":"When the run started"},"target_type":{"type":"string","title":"Target Type","description":"Whether the target was an 'agent' or a 'flow'"},"test_status":{"type":"string","title":"Test Status","description":"Where the run is - 'running', 'completed', 'failed', 'cancelled', or 'unknown' for a run this deployment has no record of","examples":["completed"]},"test_suite_id":{"type":"string","title":"Test Suite Id","description":"Suite the run belongs to"},"tests":{"items":{"$ref":"#/components/schemas/TestRunResult"},"type":"array","title":"Tests","description":"Per-test outcomes. Empty in the listing, which reports only the totals"},"total_failed":{"type":"integer","title":"Total Failed","description":"Tests that failed"},"total_passed":{"type":"integer","title":"Total Passed","description":"Tests that passed"},"total_warning":{"type":"integer","title":"Total Warning","description":"Tests that passed with reservations"}},"type":"object","required":["id","test_suite_id","name","account_id","start_time","end_time","agent","agent_name","target_type","test_status","completion_status","total_passed","total_warning","total_failed"],"title":"TestRunStatus","description":"A run, in progress or finished."},"TestStartMode":{"type":"string","enum":["start_immediate","wait_for_agent"],"title":"TestStartMode"},"TestSuiteDataTypeModel":{"properties":{"content":{"type":"string","minLength":1,"title":"Conversation prompt","description":"Test content"},"description":{"type":"string","title":"Description","description":"Test description","default":""},"enabled":{"type":"boolean","title":"Enabled","description":"Is the test enabled when running full test suite?","default":true},"fail_threshold":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Fail threshold","description":"Score below which the test is considered failed","default":50},"max_turns":{"type":"integer","maximum":500.0,"minimum":1.0,"title":"Max turns","description":"Maximum number of turns in the test","default":50},"name":{"type":"string","minLength":1,"title":"Name","description":"Test name"},"pass_threshold":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Pass threshold","description":"Score above which the test is considered passed","default":80},"success_criteria":{"type":"string","minLength":1,"title":"Success criteria","description":"Test success criteria"},"test_start_mode":{"$ref":"#/components/schemas/TestStartMode","title":"Start mode","description":"Test start mode:\n- \"wait_for_agent\" - sends a start event and waits for the agent's initial greeting before the test conversation begins\n- \"start_immediate\" - the test conversation begins immediately with the first test utterance, without waiting for the agent to initiate","default":"wait_for_agent"},"test_type":{"$ref":"#/components/schemas/TestType","title":"Type","description":"Test type:\n- \"free conversation\" - an LLM-driven test agent conducts an open-ended conversation with the tested agent using the prompt you provide\n- \"fixed phrases\" - a list of fixed user utterances sent sequentially to the tested agent, one per turn","default":"free conversation"}},"type":"object","required":["name","content","success_criteria"],"title":"TestSuiteDataTypeModel"},"TestSuiteExportRequest":{"properties":{"test_suites":{"items":{"type":"string"},"type":"array","title":"Test Suites"}},"type":"object","required":["test_suites"],"title":"TestSuiteExportRequest"},"TestSuiteImport":{"properties":{"skipped":{"items":{"type":"string"},"type":"array","title":"Skipped","description":"Names of suites in the file that could not be imported - unnamed, or failing validation. Absent when everything imported"},"test_suites":{"items":{"type":"string"},"type":"array","title":"Test Suites","description":"Ids of the suites imported, in file order. A suite whose name already existed keeps its id"}},"type":"object","required":["test_suites"],"title":"TestSuiteImport","description":"What an import archive turned into."},"TestSuiteList":{"properties":{"test_suites":{"items":{"$ref":"#/components/schemas/TestSuiteListItem"},"type":"array","title":"Test Suites","description":"The requested page of test suites"},"total_count":{"type":"integer","title":"Total Count","description":"Rows matching the filter, across every page - not the number returned here","examples":[42]}},"type":"object","required":["total_count","test_suites"],"title":"TestSuiteList"},"TestSuiteListItem":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the suite"},"agent":{"type":"string","title":"Agent","description":"Id of the agent or flow under test"},"agent_name":{"type":"string","title":"Agent Name","description":"Name of that agent or flow, or empty where it has been deleted - which is what a broken suite looks like"},"description":{"type":"string","title":"Description","description":"What the suite covers"},"id":{"type":"string","title":"Id","description":"Unique test suite id"},"llm":{"type":"string","title":"Llm","description":"Name of the model that plays the caller"},"max_tokens":{"type":"integer","title":"Max Tokens","description":"Token cap for the simulated caller"},"name":{"type":"string","title":"Name","description":"Test suite name","examples":["order-status-regression"]},"target_type":{"type":"string","title":"Target Type","description":"Whether the target is an 'agent' or a 'flow'","examples":["agent"]},"temperature":{"type":"number","title":"Temperature","description":"That model's temperature"},"test_count":{"type":"integer","title":"Test Count","description":"Tests in the suite"},"tests_names":{"items":{"type":"string"},"type":"array","title":"Tests Names","description":"Their names, so a client can offer one to run on its own"}},"type":"object","required":["id","account_id","name","description","agent","agent_name","target_type","llm","temperature","max_tokens","test_count","tests_names"],"title":"TestSuiteListItem","description":"One row of the test suite listing."},"TestSuiteModel":{"properties":{"_id":{"type":"string","title":"Id","description":"Assigned when the entity is created; a create that sends one of its own is rejected","readOnly":true},"agent":{"type":"string","minLength":1,"title":"Agent","description":"Agent or flow to be tested"},"description":{"type":"string","title":"Description","description":"Test suite description","default":""},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used for the test suite.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)"},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max output tokens","description":"Maximum number of tokens in LLM response","default":1000},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Test suite name"},"target_type":{"$ref":"#/components/schemas/TestTargetType","title":"Target type","description":"Whether the test target is an agent or a flow","default":"agent"},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"tests":{"items":{"$ref":"#/components/schemas/TestSuiteDataTypeModel"},"type":"array","title":"Tests in this suite","description":"List of tests in the test suite"}},"type":"object","required":["name","llm","agent"],"title":"TestSuiteModel"},"TestSuiteResponse":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the suite"},"agent":{"type":"string","minLength":1,"title":"Agent","description":"Agent or flow to be tested"},"agent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Name","description":"Name of the agent or flow under test, resolved from `agent`. Empty where the target has since been deleted"},"description":{"type":"string","title":"Description","description":"Test suite description","default":""},"id":{"type":"string","title":"Id","description":"Unique test suite id"},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used for the test suite.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)"},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max output tokens","description":"Maximum number of tokens in LLM response","default":1000},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Test suite name"},"target_type":{"$ref":"#/components/schemas/TestTargetType","title":"Target type","description":"Whether the test target is an agent or a flow","default":"agent"},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"tests":{"items":{"$ref":"#/components/schemas/TestSuiteDataTypeModel"},"type":"array","title":"Tests in this suite","description":"List of tests in the test suite"}},"type":"object","required":["id","name","llm","agent","account_id"],"title":"TestSuiteResponse","description":"A test suite as create, get and update return it. The target and the model come back\nas **names** here."},"TestSuiteUpdateModel":{"properties":{"agent":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Agent","description":"Agent or flow to be tested"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Test suite description"},"llm":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Large language model","description":"Large language model (LLM) used for the test suite.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)"},"max_tokens":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Max output tokens","description":"Maximum number of tokens in LLM response"},"name":{"anyOf":[{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$"},{"type":"null"}],"title":"Name","description":"Test suite name"},"target_type":{"anyOf":[{"$ref":"#/components/schemas/TestTargetType"},{"type":"null"}],"title":"Target type","description":"Whether the test target is an agent or a flow"},"temperature":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses"},"tests":{"anyOf":[{"items":{"$ref":"#/components/schemas/TestSuiteDataTypeModel"},"type":"array"},{"type":"null"}],"title":"Tests in this suite","description":"List of tests in the test suite"}},"type":"object","title":"TestSuiteUpdateModel"},"TestTargetType":{"type":"string","enum":["agent","flow"],"title":"TestTargetType"},"TestType":{"type":"string","enum":["free conversation","fixed phrases"],"title":"TestType"},"ToolAdvancedModel":{"properties":{"allow_path_segments":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Allow path segments in values","description":"Allow a parameter or variable value to add path segments to the request URL. By default a \"/\" in a substituted value is encoded as \"%2F\", so the value cannot change which resource the URL addresses. Enable only for a parameter that is meant to carry a multi-segment path."},"explicit_errors":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Explicit Errors","description":"Enable explicit errors in tool response to LLM (equivalent to \"explicit_tool_errors\" in agent)"},"logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Logs","description":"Enable tool call logs for troubleshooting (alternative to \"tool_logs\" in agent)"},"send_metadata":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Send Metadata","description":"After the tool succeeds, send a \"sendMetaData\" event carrying the tool call parameters and response"}},"type":"object","title":"ToolAdvancedModel"},"ToolAuthModel":{"properties":{"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"OAuth2 client ID","description":"OAuth2 client ID"},"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"OAuth2 client secret","description":"OAuth2 client secret"},"password":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Password","description":"Basic auth password"},"scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"OAuth2 scope","description":"OAuth2 scope"},"token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bearer key","description":"Bearer token"},"type":{"$ref":"#/components/schemas/ToolAuthType","title":"Authentication","description":"Authentication type","default":"none"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"OAuth2 token URL","description":"OAuth2 token URL"},"username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username","description":"Basic auth username"}},"type":"object","title":"ToolAuthModel"},"ToolAuthType":{"type":"string","enum":["none","basic","bearer","oauth2"],"title":"ToolAuthType"},"ToolCustomizeModel":{"properties":{"oauth2":{"anyOf":[{"$ref":"#/components/schemas/ToolOAuth2Model"},{"type":"null"}],"description":"OAuth2 configuration for the tool"},"redact_msg":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Redact Msg","description":"Redact message to be used in message history if tool response is redacted; default=\"<redacted>\""},"redact_response":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Redact Response","description":"Redact tool response from message history"},"response_len":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Response Len","description":"Maximum length of tool response to be returned to LLM"}},"type":"object","title":"ToolCustomizeModel"},"ToolList":{"properties":{"tools":{"items":{"oneOf":[{"$ref":"#/components/schemas/RestToolListItem"},{"$ref":"#/components/schemas/McpToolListItem"},{"$ref":"#/components/schemas/FlowToolListItem"}],"discriminator":{"propertyName":"type","mapping":{"flow":"#/components/schemas/FlowToolListItem","mcp":"#/components/schemas/McpToolListItem","rest":"#/components/schemas/RestToolListItem"}}},"type":"array","title":"Tools","description":"The requested page of tools"},"total_count":{"type":"integer","title":"Total Count","description":"Rows matching the filter, across every page - not the number returned here","examples":[42]}},"type":"object","required":["total_count","tools"],"title":"ToolList"},"ToolModel":{"properties":{"_id":{"type":"string","title":"Id","description":"Assigned when the entity is created; a create that sends one of its own is rejected","readOnly":true},"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/ToolAdvancedModel"},{"type":"null"}],"description":"Advanced configuration"},"auth":{"$ref":"#/components/schemas/ToolAuthModel","title":"Authentication","description":"Authentication type"},"content":{"type":"string","title":"Content","description":"Request body. Use {...} to reference parameters or variables. If empty, all parameters not referenced in URL or Headers will be included.","default":""},"description":{"type":"string","title":"Description","description":"Tool description","default":""},"flow":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flow","description":"For Flow tools: the flow to run. The flow runs to completion and returns the variables it added or changed."},"headers":{"type":"string","title":"Headers","description":"Request headers. Use {...} to reference parameters or variables. For example: \"api-version: {api_version}\"","default":""},"mcp_tools":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"MCP tools","description":"For MCP tools: comma-separated allow-list of MCP tool names to expose to the agent. Empty means all tools advertised by the MCP server are exposed."},"method":{"type":"string","title":"Method","description":"HTTP method to use","default":"POST"},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Tool name"},"params":{"items":{"$ref":"#/components/schemas/ToolParamModel"},"type":"array","title":"Parameters","description":"Tool parameters"},"progress_messages":{"anyOf":[{"$ref":"#/components/schemas/ToolProgressMessagesModel"},{"type":"null"}],"title":"Progress messages","description":"Spoken progress messages played during / after tool execution. Not played for speech-to-speech models."},"realtime_async_mode":{"type":"boolean","title":"Allow model to speak during tool execution","description":"When on, the model can keep talking and call other tools while this tool runs; when off it waits for the result before responding.","default":true},"response_len":{"type":"integer","title":"Max response length","description":"Maximum response length in bytes","default":100000},"response_reshape":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response reshape (jq or JMESPath statement)","description":"jq or JMESPath statement to reshape the tool response. Interpreted as jq if it starts with \".\" else JMESPath."},"timeout":{"type":"integer","title":"Timeout (sec)","description":"Request timeout in seconds","default":10},"tool_response":{"$ref":"#/components/schemas/RedactToolResponse","title":"Response in message history","description":"Whether to keep tool response in conversation history","default":"keep"},"type":{"$ref":"#/components/schemas/ToolType","title":"Type","description":"Tool type","default":"rest"},"url":{"type":"string","title":"URL","description":"Request URL. Use {...} to reference parameters or variables.","default":""},"variables":{"items":{"$ref":"#/components/schemas/ToolVariableModel"},"type":"array","title":"Variables","description":"Tool-level variables used to expand URL, headers or content. Reference as {name}."},"wait_response":{"type":"boolean","title":"Wait for response","description":"Wait for the tool response before returning to the agent","default":true}},"type":"object","required":["name"],"title":"ToolModel"},"ToolOAuth2Model":{"properties":{"client_id":{"type":"string","title":"Client Id","description":"OAuth2 client ID"},"client_secret":{"type":"string","title":"Client Secret","description":"OAuth2 client secret"},"scope":{"type":"string","title":"Scope","description":"OAuth2 scope","default":""},"url":{"type":"string","title":"Url","description":"OAuth2 token URL"}},"type":"object","required":["client_id","client_secret","url"],"title":"ToolOAuth2Model"},"ToolOverrideRequestModel":{"properties":{"tool":{"anyOf":[{"$ref":"#/components/schemas/ToolModel"},{"type":"null"}],"description":"Optional in-memory tool definition; when provided, used instead of the saved tool (with masked secrets unmasked from the saved copy)"}},"type":"object","title":"ToolOverrideRequestModel"},"ToolParamModel":{"properties":{"description":{"type":"string","title":"Description","description":"Parameter description"},"name":{"type":"string","title":"Name","description":"Parameter name"},"required":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Required","description":"Whether the parameter is required","default":true},"type":{"$ref":"#/components/schemas/ToolParamType","description":"Parameter type","default":"str"}},"type":"object","required":["name","description"],"title":"ToolParamModel"},"ToolParamType":{"type":"string","enum":["str","int","float","bool","list[str]","list[int]","list[float]","list[bool]"],"title":"ToolParamType"},"ToolProgressMessageModel":{"properties":{"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition","description":"Optional condition evaluated against the agent / flow variables - e.g., `caller == \"1234\"`. The message is eligible when this is empty or evaluates to true."},"text":{"type":"string","title":"Message","description":"Message text to play. Supports {variable} expansion."}},"type":"object","required":["text"],"title":"ToolProgressMessageModel"},"ToolProgressMessagesModel":{"properties":{"before":{"items":{"$ref":"#/components/schemas/ToolProgressMessageModel"},"type":"array","title":"During execution","description":"Messages played while the tool runs."},"before_llm_message":{"type":"boolean","title":"Message source","description":"Who composes the message played while the tool runs.\n**Pre-defined**: plays a message configured here - the same wording every time, optionally chosen by condition.\n**Dynamic**: the model writes the line per call, so it describes that specific call.","default":false},"execution_sound":{"$ref":"#/components/schemas/ExecutionSound","title":"Sound during execution","description":"Sound played to the caller while the tool runs, stopped when it returns. Not played for speech-to-speech models or background tools.","default":"none"},"failure":{"items":{"$ref":"#/components/schemas/ToolProgressMessageModel"},"type":"array","title":"On failure","description":"Messages played after the tool fails."},"success":{"items":{"$ref":"#/components/schemas/ToolProgressMessageModel"},"type":"array","title":"On success","description":"Messages played after the tool succeeds."}},"type":"object","title":"ToolProgressMessagesModel"},"ToolResponse":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the tool"},"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/ToolAdvancedModel"},{"type":"null"}],"description":"Advanced configuration"},"auth":{"$ref":"#/components/schemas/ToolAuthModel","title":"Authentication","description":"Authentication type"},"content":{"type":"string","title":"Content","description":"Request body. Use {...} to reference parameters or variables. If empty, all parameters not referenced in URL or Headers will be included.","default":""},"description":{"type":"string","title":"Description","description":"Tool description","default":""},"flow":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flow","description":"For Flow tools: the flow to run. The flow runs to completion and returns the variables it added or changed."},"headers":{"type":"string","title":"Headers","description":"Request headers. Use {...} to reference parameters or variables. For example: \"api-version: {api_version}\"","default":""},"id":{"type":"string","title":"Id","description":"Unique tool id"},"mcp_tools":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"MCP tools","description":"For MCP tools: comma-separated allow-list of MCP tool names to expose to the agent. Empty means all tools advertised by the MCP server are exposed."},"method":{"type":"string","title":"Method","description":"HTTP method to use","default":"POST"},"name":{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$","title":"Name","description":"Tool name"},"params":{"items":{"$ref":"#/components/schemas/ToolParamModel"},"type":"array","title":"Parameters","description":"Tool parameters"},"progress_messages":{"anyOf":[{"$ref":"#/components/schemas/ToolProgressMessagesModel"},{"type":"null"}],"title":"Progress messages","description":"Spoken progress messages played during / after tool execution. Not played for speech-to-speech models."},"realtime_async_mode":{"type":"boolean","title":"Allow model to speak during tool execution","description":"When on, the model can keep talking and call other tools while this tool runs; when off it waits for the result before responding.","default":true},"response_len":{"type":"integer","title":"Max response length","description":"Maximum response length in bytes","default":100000},"response_reshape":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response reshape (jq or JMESPath statement)","description":"jq or JMESPath statement to reshape the tool response. Interpreted as jq if it starts with \".\" else JMESPath."},"timeout":{"type":"integer","title":"Timeout (sec)","description":"Request timeout in seconds","default":10},"tool_response":{"$ref":"#/components/schemas/RedactToolResponse","title":"Response in message history","description":"Whether to keep tool response in conversation history","default":"keep"},"type":{"$ref":"#/components/schemas/ToolType","title":"Type","description":"Tool type","default":"rest"},"url":{"type":"string","title":"URL","description":"Request URL. Use {...} to reference parameters or variables.","default":""},"variables":{"items":{"$ref":"#/components/schemas/ToolVariableModel"},"type":"array","title":"Variables","description":"Tool-level variables used to expand URL, headers or content. Reference as {name}."},"wait_response":{"type":"boolean","title":"Wait for response","description":"Wait for the tool response before returning to the agent","default":true}},"type":"object","required":["id","name","account_id"],"title":"ToolResponse","description":"A tool as create, get, update and clone return it."},"ToolTestParam":{"properties":{"default":{"anyOf":[{},{"type":"null"}],"title":"Default","description":"Value used when none is supplied"},"description":{"type":"string","title":"Description","description":"What the parameter is for, as the model sees it. A description starting with '=' declares a default rather than describing anything"},"name":{"type":"string","title":"Name","description":"Parameter name, as a test run passes it"},"required":{"type":"boolean","title":"Required","description":"Whether a test run has to supply it"},"type":{"type":"string","title":"Type","description":"Value type - 'str', 'int', 'float', 'bool', 'list'","examples":["str"]}},"type":"object","required":["name","description","type","required"],"title":"ToolTestParam","description":"One value a test run has to be given."},"ToolTestParams":{"properties":{"params":{"items":{"$ref":"#/components/schemas/ToolTestParam"},"type":"array","title":"Params","description":"The tool's own declared parameters, plus - for a REST tool - every `{name}` its URL, headers, body, reshape or authentication references without declaring as a variable"}},"type":"object","required":["params"],"title":"ToolTestParams"},"ToolTestRun":{"properties":{"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Why the call could not be made, or null if it was. A 4xx or 5xx *from a REST endpoint* is not an error here - it comes back as its status code and body. An MCP tool reporting failure sets this **and** a **500**"},"reshaped_response_body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reshaped Response Body","description":"What `response_reshape` made of the body, or null when the tool sets none. This is what the model would actually receive"},"response_body":{"type":"string","title":"Response Body","description":"The response exactly as it arrived, before any reshaping. For a flow tool, the variables the flow added or changed, as JSON"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code","description":"For a REST tool, the HTTP status the endpoint answered with. For an MCP tool, a synthesized 200 or **500** - it has no HTTP status of its own. Null where the call never got that far, and on a flow tool, which has none either","examples":[200]}},"type":"object","required":["status_code","response_body","reshaped_response_body","error"],"title":"ToolTestRun","description":"What one test call did. This is not the shape an agent sees at conversation time - it is the\nraw result plus whatever the reshape made of it, so both can be compared."},"ToolType":{"type":"string","enum":["rest","mcp","flow"],"title":"ToolType"},"ToolUpdateModel":{"properties":{"advanced_config":{"anyOf":[{"$ref":"#/components/schemas/ToolAdvancedModel"},{"type":"null"}],"description":"Advanced configuration"},"auth":{"anyOf":[{"$ref":"#/components/schemas/ToolAuthModel"},{"type":"null"}],"title":"Authentication","description":"Authentication type"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content","description":"Request body. Use {...} to reference parameters or variables. If empty, all parameters not referenced in URL or Headers will be included."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Tool description"},"flow":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flow","description":"For Flow tools: the flow to run. The flow runs to completion and returns the variables it added or changed."},"headers":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headers","description":"Request headers. Use {...} to reference parameters or variables. For example: \"api-version: {api_version}\""},"mcp_tools":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"MCP tools","description":"For MCP tools: comma-separated allow-list of MCP tool names to expose to the agent. Empty means all tools advertised by the MCP server are exposed."},"method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Method","description":"HTTP method to use"},"name":{"anyOf":[{"type":"string","maxLength":64,"minLength":3,"pattern":"^[A-Za-z0-9_\\- ]+$"},{"type":"null"}],"title":"Name","description":"Tool name"},"params":{"anyOf":[{"items":{"$ref":"#/components/schemas/ToolParamModel"},"type":"array"},{"type":"null"}],"title":"Parameters","description":"Tool parameters"},"progress_messages":{"anyOf":[{"$ref":"#/components/schemas/ToolProgressMessagesModel"},{"type":"null"}],"title":"Progress messages","description":"Spoken progress messages played during / after tool execution. Not played for speech-to-speech models."},"realtime_async_mode":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Allow model to speak during tool execution","description":"When on, the model can keep talking and call other tools while this tool runs; when off it waits for the result before responding."},"response_len":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max response length","description":"Maximum response length in bytes"},"response_reshape":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response reshape (jq or JMESPath statement)","description":"jq or JMESPath statement to reshape the tool response. Interpreted as jq if it starts with \".\" else JMESPath."},"timeout":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Timeout (sec)","description":"Request timeout in seconds"},"tool_response":{"anyOf":[{"$ref":"#/components/schemas/RedactToolResponse"},{"type":"null"}],"title":"Response in message history","description":"Whether to keep tool response in conversation history"},"type":{"anyOf":[{"$ref":"#/components/schemas/ToolType"},{"type":"null"}],"title":"Type","description":"Tool type"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"URL","description":"Request URL. Use {...} to reference parameters or variables."},"variables":{"anyOf":[{"items":{"$ref":"#/components/schemas/ToolVariableModel"},"type":"array"},{"type":"null"}],"title":"Variables","description":"Tool-level variables used to expand URL, headers or content. Reference as {name}."},"wait_response":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Wait for response","description":"Wait for the tool response before returning to the agent"}},"type":"object","title":"ToolUpdateModel"},"ToolVariableModel":{"properties":{"name":{"type":"string","title":"Name","description":"Variable name. Reference as {name} in URL, headers or content."},"type":{"$ref":"#/components/schemas/ToolVariableType","title":"Type","description":"Variable type","default":"str"},"value":{"type":"string","title":"Value","description":"Variable value","default":""}},"type":"object","required":["name"],"title":"ToolVariableModel"},"ToolVariableType":{"type":"string","enum":["str","int","float","bool","secret"],"title":"ToolVariableType"},"ToolWidgetModel":{"properties":{"custom_llm":{"type":"boolean","title":"Custom LLM","description":"Choose a different LLM for this node","default":false},"discard_response":{"type":"boolean","title":"Discard response","description":"Discard tool response from the conversation history","default":false},"extract_variables":{"type":"boolean","title":"Extract variables","description":"Extract variables from tool response","default":false},"failed_widget":{"type":"string","title":"Failed","description":"Node to transition to if tool fails","default":""},"flavor":{"type":"string","const":"tool","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"type":"string","title":"Global condition","description":"Describe conditions to transition to this node","default":""},"global_widget":{"type":"boolean","title":"Global node","description":"Allow other nodes to transition to this node without edges","default":false},"llm":{"type":"string","title":"Large language model","description":"Large language model (LLM) used by this node.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)","default":""},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"max_tokens":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Max output tokens","description":"Maximum number of tokens in LLM response","default":1000},"next_widget":{"type":"string","title":"Success","description":"Node to transition to","default":""},"temperature":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses","default":0.2},"text":{"type":"string","title":"Text","description":"Message to be played before using the tool","default":""},"tool":{"type":"string","title":"Tool","description":"Tool to be used","default":""},"variables":{"items":{"$ref":"#/components/schemas/ExtractVariableModel"},"type":"array","title":"Variables","description":"List of variables to be extracted"},"wait_response":{"type":"boolean","title":"Wait for response","description":"Wait for tool response before proceeding to next node","default":true}},"type":"object","required":["flavor"],"title":"ToolWidgetModel"},"ToolWidgetUpdateModel":{"properties":{"custom_llm":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Custom LLM","description":"Choose a different LLM for this node"},"discard_response":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Discard response","description":"Discard tool response from the conversation history"},"extract_variables":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Extract variables","description":"Extract variables from tool response"},"failed_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failed","description":"Node to transition to if tool fails"},"flavor":{"type":"string","const":"tool","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Global condition","description":"Describe conditions to transition to this node"},"global_widget":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Global node","description":"Allow other nodes to transition to this node without edges"},"llm":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Large language model","description":"Large language model (LLM) used by this node.\nEach pre-deployed model shows:\n- latency\n- input / output token cost\n- intelligence index (from artificialanalysis.ai)"},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"max_tokens":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Max output tokens","description":"Maximum number of tokens in LLM response"},"next_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Success","description":"Node to transition to"},"temperature":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Temperature","description":"Controls the randomness of LLM generation, where lower values (closer to 0) produce more predictable and focused outputs while higher values (closer to 1) create more creative and varied responses"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text","description":"Message to be played before using the tool"},"tool":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool","description":"Tool to be used"},"variables":{"anyOf":[{"items":{"$ref":"#/components/schemas/ExtractVariableModel"},"type":"array"},{"type":"null"}],"title":"Variables","description":"List of variables to be extracted"},"wait_response":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Wait for response","description":"Wait for tool response before proceeding to next node"}},"type":"object","required":["flavor"],"title":"ToolWidgetUpdateModel"},"TransferCallConfigModel":{"properties":{"default_message":{"type":"string","title":"Default Message","description":"Default transfer message to be used if LLM didn't specify one","default":""},"default_number":{"type":"string","title":"Default Number","description":"Default transfer number to be used if LLM didn't specify one","default":""},"description":{"type":"string","title":"Description","description":"Custom tool description","default":""},"name":{"type":"string","title":"Name","description":"Custom tool name","default":""},"tool":{"type":"string","const":"transfer_call","title":"Tool"},"valid_numbers":{"type":"string","title":"Valid Numbers","description":"Comma-separated list of valid transfer numbers; default = <empty> - no validation","default":""},"wait_result":{"type":"boolean","title":"Wait Result","description":"Wait for call transfer result","default":false}},"type":"object","required":["tool"],"title":"TransferCallConfigModel"},"TransferCallRequestModel":{"properties":{"message":{"type":"string","title":"Message","description":"Message to play before transferring","default":""},"phone":{"type":"string","title":"Phone","description":"Phone number (e.g. +12024561111) or SIP URI"}},"type":"object","required":["phone"],"title":"TransferCallRequestModel"},"TransferCallWidgetModel":{"properties":{"failed_widget":{"type":"string","title":"Transfer failed","description":"Node to transition to if transfer fails","default":""},"flavor":{"type":"string","const":"transfer_call","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"type":"string","title":"Global condition","description":"Describe conditions to transition to this node","default":""},"global_widget":{"type":"boolean","title":"Global node","description":"Allow other nodes to transition to this node without edges","default":false},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"phone":{"type":"string","title":"Phone number","description":"Phone number to transfer the call to","default":""},"sip_headers":{"anyOf":[{"items":{"$ref":"#/components/schemas/SipHeadersModel"},"type":"array"},{"type":"null"}],"title":"SIP headers","description":"SIP headers to be included in the REFER request"},"text":{"type":"string","title":"Transfer message","description":"Message to be played before transferring the call","default":""}},"type":"object","required":["flavor"],"title":"TransferCallWidgetModel"},"TransferCallWidgetUpdateModel":{"properties":{"failed_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transfer failed","description":"Node to transition to if transfer fails"},"flavor":{"type":"string","const":"transfer_call","title":"Node type","description":"Node type. Picks which shape the rest of the node's data takes, and cannot be changed once the node exists."},"global_condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Global condition","description":"Describe conditions to transition to this node"},"global_widget":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Global node","description":"Allow other nodes to transition to this node without edges"},"logs":{"anyOf":[{"$ref":"#/components/schemas/LogsModel"},{"type":"null"}],"title":"Logging","description":"Enable or disable logging for this node"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone number","description":"Phone number to transfer the call to"},"sip_headers":{"anyOf":[{"items":{"$ref":"#/components/schemas/SipHeadersModel"},"type":"array"},{"type":"null"}],"title":"SIP headers","description":"SIP headers to be included in the REFER request"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transfer message","description":"Message to be played before transferring the call"}},"type":"object","required":["flavor"],"title":"TransferCallWidgetUpdateModel"},"UrlDocumentListItem":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the document"},"auto_refresh":{"type":"string","title":"Auto Refresh","description":"Re-parse interval","examples":["never"]},"description":{"type":"string","title":"Description","description":"Document description"},"id":{"type":"string","title":"Id","description":"Unique document id"},"max_depth":{"type":"integer","title":"Max Depth","description":"How many link levels deep the crawl goes"},"n_chunks":{"type":"integer","title":"N Chunks","description":"Chunks the content was split into"},"n_files":{"type":"integer","title":"N Files","description":"Files (or crawled URLs) parsed into the vector store"},"name":{"type":"string","title":"Name","description":"Document name","examples":["product-manuals"]},"processing":{"type":"boolean","title":"Processing","description":"Whether a parse is still running. Poll the listing while any row has this set - `refresh_needed` says whether any does"},"status":{"type":"string","title":"Status","description":"Parse state, phrased for display: a finished document reads 'ready (3 files, 412 chunks)', one still working reads 'creating' or 'updating', and a failed one carries the parser's own message. Use `processing` rather than parsing this","examples":["ready (3 files, 412 chunks)"]},"type":{"type":"string","const":"url","title":"Type"},"updated":{"type":"string","title":"Updated","description":"How long ago the document last finished parsing, in words","examples":["5 minutes ago"]},"urls":{"type":"string","title":"Urls","description":"The first three URLs, newline-separated, with a trailing '...' when the document has more"}},"type":"object","required":["id","account_id","name","description","status","n_files","n_chunks","updated","max_depth","auto_refresh","processing","type","urls"],"title":"UrlDocumentListItem","description":"A row for a document built by crawling URLs."},"ValidationError":{"properties":{"ctx":{"type":"object","title":"Context"},"input":{"title":"Input"},"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WebChatConfigModel":{"properties":{"allowed_origins":{"items":{"type":"string"},"type":"array","title":"Allowed Origins","description":"List of allowed webchat origins; use full origin URL (e.g. \"https://example.com\")"},"max_sessions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Sessions","description":"Maximum number of concurrent webchat sessions"},"session_timeout":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Session Timeout","description":"Session timeout in seconds"}},"type":"object","title":"WebChatConfigModel"},"WebSocketToken":{"properties":{"expires_in":{"type":"integer","title":"Expires In","description":"Seconds the token stays valid, counted from this answer","examples":[60]},"token":{"type":"string","title":"Token","description":"Pass as the `token` query parameter of the WebSocket URL","examples":["wst_hZ3n4Kc0Q1uT8pR2vXbL9sYwE7mA6dJf0gN5iOqB3kU"]}},"type":"object","required":["token","expires_in"],"title":"WebSocketToken","description":"A token for opening one WebSocket connection.\n\nShort-lived and accepted once - the connection spends it."},"WebhookAuth":{"type":"string","enum":["none","bearer"],"title":"WebhookAuth"},"WebhookModel":{"properties":{"auth":{"anyOf":[{"$ref":"#/components/schemas/WebhookAuth"},{"type":"null"}],"description":"Authentication type; default = \"none\""},"events":{"items":{"type":"string","enum":["init","user","llm","finish"]},"type":"array","title":"Events","description":"List of events to trigger the webhook"},"logs":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Logs","description":"Enable webhook logs (records the webhook call and, when waiting for a response, the response received); default = false"},"response":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Response","description":"Wait for webhook response; default = false"},"timeout":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Timeout","description":"Timeout for the webhook call in seconds; default = 10 sec"},"token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token","description":"Bearer token; applicable only when (auth == \"bearer\")"},"url":{"type":"string","title":"Url","description":"Webhook URL that starts with \"http://\" or \"https://\"","default":""}},"type":"object","title":"WebhookModel"},"WelcomeMessagePartModel":{"properties":{"barge_in":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Barge In","description":"Enable barge-in during this part of the welcome message"},"message":{"type":"string","title":"Message","description":"Welcome message part to be played"}},"type":"object","required":["message"],"title":"WelcomeMessagePartModel"},"WelcomeModel":{"properties":{"message":{"type":"string","title":"Welcome message","description":"Welcome message to be played at the beginning of the conversation","default":""},"reverse_message":{"type":"string","title":"Initial user utterance","description":"User message sent to LLM to generate dynamic welcome message","default":""},"type":{"$ref":"#/components/schemas/WelcomeType","title":"Conversation start","description":"Welcome message type","default":"static"}},"type":"object","title":"WelcomeModel"},"WelcomeType":{"type":"string","enum":["static","dynamic","wait_for_user"],"title":"WelcomeType"},"WidgetList":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the flow"},"flow":{"type":"string","title":"Flow","description":"Id of the flow the nodes belong to"},"widgets":{"items":{"$ref":"#/components/schemas/WidgetListItem"},"type":"array","title":"Widgets","description":"The flow's nodes, the synthesized `start` node first"}},"type":"object","required":["account_id","flow","widgets"],"title":"WidgetList","description":"Every node of one flow. No paging, no filter: a flow's nodes are a bounded set, and the\ncanvas needs all of them at once."},"WidgetListItem":{"properties":{"agent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent","description":"Name of the agent this node hands off to"},"behavior":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Behavior"},"else_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Else Widget"},"expressions":{"anyOf":[{"items":{"$ref":"#/components/schemas/ExpressionModel"},"type":"array"},{"type":"null"}],"title":"Expressions"},"extract_variables":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Extract Variables"},"failed_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failed Widget"},"flavor":{"type":"string","title":"Flavor","description":"Node type - 'conversation', 'condition', 'api', and so on, or 'start' for the flow's synthesized entry node","examples":["conversation"]},"flow":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flow","description":"Name of the flow this node runs. Note that the envelope's `flow` is an id - this is a name"},"global_widget":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Global Widget"},"id":{"type":"string","title":"Id","description":"Unique node id. This is what other nodes point at"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Method"},"name":{"type":"string","title":"Name","description":"Node name, as the canvas labels it"},"next_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Widget"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"skip_response":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Skip Response"},"skip_widget":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Skip Widget"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"},"tool":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool","description":"Name of the tool this node calls"},"transitions":{"anyOf":[{"items":{"anyOf":[{"$ref":"#/components/schemas/ConversationTransitionModel"},{"$ref":"#/components/schemas/ConditionTransitionModel"}]},"type":"array"},{"type":"null"}],"title":"Transitions"},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"variables":{"anyOf":[{"items":{"$ref":"#/components/schemas/ExtractVariableModel"},"type":"array"},{"type":"null"}],"title":"Variables"},"wait_response":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Wait Response"},"width":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Width"}},"type":"object","required":["id","name","flavor"],"title":"WidgetListItem","description":"One node as the canvas listing returns it.\n\nA projection with the node's own data keys **lifted to the top level**, rather than the nested\n`data` that `get_widget` answers with - and only a fixed subset of them, so a node's full\nsettings need the single read. Which keys a row carries follows from `flavor`; the rest are\nabsent."},"WidgetResponse":{"properties":{"account_id":{"type":"string","title":"Account Id","description":"Account that owns the flow this node belongs to"},"data":{"oneOf":[{"$ref":"#/components/schemas/ConversationWidgetModel"},{"$ref":"#/components/schemas/ExtractWidgetModel"},{"$ref":"#/components/schemas/ConditionWidgetModel"},{"$ref":"#/components/schemas/EndCallWidgetModel"},{"$ref":"#/components/schemas/TransferCallWidgetModel"},{"$ref":"#/components/schemas/ToolWidgetModel"},{"$ref":"#/components/schemas/ApiWidgetModel"},{"$ref":"#/components/schemas/CalculateWidgetModel"},{"$ref":"#/components/schemas/PassWidgetModel"},{"$ref":"#/components/schemas/NoteWidgetModel"}],"title":"Data","discriminator":{"propertyName":"flavor","mapping":{"api":"#/components/schemas/ApiWidgetModel","calculate":"#/components/schemas/CalculateWidgetModel","condition":"#/components/schemas/ConditionWidgetModel","conversation":"#/components/schemas/ConversationWidgetModel","end_call":"#/components/schemas/EndCallWidgetModel","extract":"#/components/schemas/ExtractWidgetModel","note":"#/components/schemas/NoteWidgetModel","pass":"#/components/schemas/PassWidgetModel","tool":"#/components/schemas/ToolWidgetModel","transfer_call":"#/components/schemas/TransferCallWidgetModel"}}},"flow":{"type":"string","title":"Flow","description":"Id of the flow this node belongs to"},"id":{"type":"string","title":"Id","description":"Unique node id. This is what other nodes point at"},"name":{"type":"string","title":"Name","description":"Node name, as the canvas labels it","examples":["ask-order-number"]}},"type":"object","required":["id","account_id","flow","name","data"],"title":"WidgetResponse","description":"One node of a flow, as create, get and update return it.\n\nThe node's behaviour sits nested under `data`, whose shape follows `data.flavor`. That is the\ndifference from the listing, which lifts a subset of those keys to the top level."}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer","description":"Paste an access token you already hold - the access_token a POST to https://livehub.audiocodes.io/oauth/token returns. To have this page fetch one from an API client's credentials instead, fill in OAuth2ClientCredentials below."},"OAuth2ClientCredentials":{"type":"oauth2","description":"Enter a LiveHub API client's credentials and this page exchanges them for an access token, then sends it with every request you try out.","flows":{"clientCredentials":{"tokenUrl":"https://livehub.audiocodes.io/oauth/token","scopes":{}}}}}},"tags":[{"name":"Agents","description":"LLM-driven conversational agents - prompt, model, tools, documents, sub-agents, webhooks, post call analyses - plus prompt history."},{"name":"Flows","description":"Deterministic conversations as a graph of nodes - the flow itself and the nodes it is built from."},{"name":"Documents","description":"Knowledge sources - uploaded files and crawled URLs - chunked for retrieval, with their parse status and extracted content."},{"name":"Tools","description":"Operations an agent can call: a REST endpoint, an MCP server or a flow. Includes a test-run endpoint for trying one out before an agent uses it."},{"name":"LLMs","description":"Models the account defines itself: its own API keys, Azure deployments and OpenAI-compatible endpoints, alongside the pre-defined ones."},{"name":"Post Call Analysis","description":"Analysis run over a transcript after hangup - the definitions, and the results they produced."},{"name":"Test Suites","description":"Scripted conversations run against an agent or a flow, the runs they produced, and the scored results of each run."},{"name":"Conversations","description":"Finished conversations: find them, read one whole with its transcript, and delete one."},{"name":"Live Conversations","description":"Conversations happening right now: list them, stream their logs, and end, transfer or inject a message into one."},{"name":"WebSocket Tokens","description":"Short-lived, single-use tokens for opening a WebSocket, which cannot carry an Authorization header."},{"name":"Backup","description":"Export an account's configuration as an archive and restore one, either directly or after previewing what the operation would touch."},{"name":"Info","description":"Pre-deployed models and pre-defined tools."}],"externalDocs":{"description":"LiveHub API security and access tokens","url":"https://techdocs.audiocodes.com/livehub/#LiveHub/API/api-security.htm"},"servers":[{"url":"/ai-framework-management"}]}