diff --git a/src/libs/Speechify/Generated/Speechify.Models.TtsConversation.g.cs b/src/libs/Speechify/Generated/Speechify.Models.TtsConversation.g.cs
index c80d1d1..c266aa9 100644
--- a/src/libs/Speechify/Generated/Speechify.Models.TtsConversation.g.cs
+++ b/src/libs/Speechify/Generated/Speechify.Models.TtsConversation.g.cs
@@ -128,6 +128,7 @@ public sealed partial class TtsConversation
/// * `inactivity_timeout` — worker's inactivity handler fired terminate after the configured silence window.
/// * `loop_detected` — worker's runtime loop guard force-ended the call after N consecutive near-identical user turns (typically an IVR replaying its menu while the LLM kept reacting instead of calling end_call).
/// * `max_duration_reached` - worker's max-call-duration watchdog force-ended the call at the platform ceiling (a safety bound on runaway calls).
+ /// * `over_capacity` — inbound call refused because the workspace was over its active-call concurrency cap; the busy message played and the call hung up. Stamped server-side and excluded from billing.
/// * `caller_hangup` — caller's leg went away. Precise when the worker observed the SIP `participant_disconnected` event (stamped immediately); otherwise stamped server-side ~10s after `room_finished` as a catch-all (web tab close, network blip, worker crash, etc.).
/// * `null` — pre-rollout calls only (anything that landed after the rollout completes without a stamp gets `caller_hangup` from the post-call goroutine).
///
@@ -295,6 +296,7 @@ public sealed partial class TtsConversation
/// * `inactivity_timeout` — worker's inactivity handler fired terminate after the configured silence window.
/// * `loop_detected` — worker's runtime loop guard force-ended the call after N consecutive near-identical user turns (typically an IVR replaying its menu while the LLM kept reacting instead of calling end_call).
/// * `max_duration_reached` - worker's max-call-duration watchdog force-ended the call at the platform ceiling (a safety bound on runaway calls).
+ /// * `over_capacity` — inbound call refused because the workspace was over its active-call concurrency cap; the busy message played and the call hung up. Stamped server-side and excluded from billing.
/// * `caller_hangup` — caller's leg went away. Precise when the worker observed the SIP `participant_disconnected` event (stamped immediately); otherwise stamped server-side ~10s after `room_finished` as a catch-all (web tab close, network blip, worker crash, etc.).
/// * `null` — pre-rollout calls only (anything that landed after the rollout completes without a stamp gets `caller_hangup` from the post-call goroutine).
///
diff --git a/src/libs/Speechify/Generated/Speechify.Models.TtsConversationEndReason.g.cs b/src/libs/Speechify/Generated/Speechify.Models.TtsConversationEndReason.g.cs
index b9a5caf..a33faaf 100644
--- a/src/libs/Speechify/Generated/Speechify.Models.TtsConversationEndReason.g.cs
+++ b/src/libs/Speechify/Generated/Speechify.Models.TtsConversationEndReason.g.cs
@@ -16,6 +16,7 @@ namespace Speechify
/// * `inactivity_timeout` — worker's inactivity handler fired terminate after the configured silence window.
/// * `loop_detected` — worker's runtime loop guard force-ended the call after N consecutive near-identical user turns (typically an IVR replaying its menu while the LLM kept reacting instead of calling end_call).
/// * `max_duration_reached` - worker's max-call-duration watchdog force-ended the call at the platform ceiling (a safety bound on runaway calls).
+ /// * `over_capacity` — inbound call refused because the workspace was over its active-call concurrency cap; the busy message played and the call hung up. Stamped server-side and excluded from billing.
/// * `caller_hangup` — caller's leg went away. Precise when the worker observed the SIP `participant_disconnected` event (stamped immediately); otherwise stamped server-side ~10s after `room_finished` as a catch-all (web tab close, network blip, worker crash, etc.).
/// * `null` — pre-rollout calls only (anything that landed after the rollout completes without a stamp gets `caller_hangup` from the post-call goroutine).
///
@@ -48,6 +49,10 @@ public enum TtsConversationEndReason
///
///
///
+ OverCapacity,
+ ///
+ ///
+ ///
UnavailableHangup,
///
///
@@ -77,6 +82,7 @@ public static string ToValueString(this TtsConversationEndReason value)
TtsConversationEndReason.IvrHangup => "ivr_hangup",
TtsConversationEndReason.LoopDetected => "loop_detected",
TtsConversationEndReason.MaxDurationReached => "max_duration_reached",
+ TtsConversationEndReason.OverCapacity => "over_capacity",
TtsConversationEndReason.UnavailableHangup => "unavailable_hangup",
TtsConversationEndReason.VoicemailHangup => "voicemail_hangup",
TtsConversationEndReason.VoicemailMessageLeft => "voicemail_message_left",
@@ -96,6 +102,7 @@ public static string ToValueString(this TtsConversationEndReason value)
"ivr_hangup" => TtsConversationEndReason.IvrHangup,
"loop_detected" => TtsConversationEndReason.LoopDetected,
"max_duration_reached" => TtsConversationEndReason.MaxDurationReached,
+ "over_capacity" => TtsConversationEndReason.OverCapacity,
"unavailable_hangup" => TtsConversationEndReason.UnavailableHangup,
"voicemail_hangup" => TtsConversationEndReason.VoicemailHangup,
"voicemail_message_left" => TtsConversationEndReason.VoicemailMessageLeft,
diff --git a/src/libs/Speechify/openapi.yaml b/src/libs/Speechify/openapi.yaml
index 9d38578..0add2d9 100644
--- a/src/libs/Speechify/openapi.yaml
+++ b/src/libs/Speechify/openapi.yaml
@@ -1 +1 @@
-{"openapi":"3.1.0","info":{"title":"API Reference","version":"1.0.0"},"paths":{"/v1/audio/speech":{"post":{"operationId":"speech","summary":"Create Speech","description":"Synthesize speech audio from text or SSML. Returns the complete audio\nfile plus billing and speech-mark metadata in a single response. For\nlow-latency playback or long-form text, use POST /v1/audio/stream.","tags":["subpackage_tts.subpackage_tts/audio"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Synthesized speech audio for the requested input.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetSpeechResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"402":{"description":"The workspace has insufficient credits, or the request needs a\nplan tier the workspace is not on (e.g. voice cloning). Distinct\nfrom `Forbidden` so SDK consumers can drive upgrade UX.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"403":{"description":"The credential authenticated, but is not authorised for this\nresource - typically a workspace-role gate (owner / admin\nrequired) or a cross-tenant access attempt.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetSpeechRequest"}}}}}},"/v1/audio/stream":{"post":{"operationId":"stream","summary":"Stream Speech","description":"Synthesize speech and stream the audio back as it is generated, for\nlow-latency playback. The Accept header selects the audio container.\nFor short text where receiving the whole file at once is fine, use\nPOST /v1/audio/speech.","tags":["subpackage_tts.subpackage_tts/audio"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}},{"name":"Accept","in":"header","required":true,"schema":{"$ref":"#/components/schemas/tts:V1AudioStreamPostParametersAccept"}}],"responses":{"200":{"description":"Chunked audio stream for the requested input.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"402":{"description":"The workspace has insufficient credits, or the request needs a\nplan tier the workspace is not on (e.g. voice cloning). Distinct\nfrom `Forbidden` so SDK consumers can drive upgrade UX.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"403":{"description":"The credential authenticated, but is not authorised for this\nresource - typically a workspace-role gate (owner / admin\nrequired) or a cross-tenant access attempt.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetStreamRequest"}}}}}},"/v1/voices":{"get":{"operationId":"list","summary":"List Voices","description":"Gets the list of voices available for the user","tags":["subpackage_tts.subpackage_tts/voices"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of voices","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/tts:GetVoice"}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"post":{"operationId":"create","summary":"Create Voice","description":"Create a personal (cloned) voice for the user","tags":["subpackage_tts.subpackage_tts/voices"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A created voice","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreatedVoice"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"402":{"description":"The workspace has insufficient credits, or the request needs a\nplan tier the workspace is not on (e.g. voice cloning). Distinct\nfrom `Forbidden` so SDK consumers can drive upgrade UX.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Name of the personal voice"},"locale":{"type":"string","default":"en-US","description":"Native language (locale) of the personal voice (e.g. en-US, es-ES, etc.)"},"gender":{"$ref":"#/components/schemas/tts:V1VoicesPostRequestBodyContentMultipartFormDataSchemaGender","description":"Gender marker for the personal voice\nmale GenderMale\nfemale GenderFemale\nnotSpecified GenderNotSpecified"},"sample":{"type":"string","format":"binary","description":"Audio sample file"},"avatar":{"type":"string","format":"binary","description":"Avatar image file"},"consent":{"type":"string","description":"A **string** representing the user consent information in JSON format\nThis should include the fullName and email of the consenting individual.\nFor example, `{\"fullName\": \"John Doe\", \"email\": \"john@example.com\"}`"}},"required":["name","gender","sample","consent"]}}}}}},"/v1/voices/{id}":{"delete":{"operationId":"delete","summary":"Delete Voice","description":"Delete a personal (cloned) voice","tags":["subpackage_tts.subpackage_tts/voices"],"parameters":[{"name":"id","in":"path","description":"The ID of the voice to delete","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Voice deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/voices/{id}/sample":{"get":{"operationId":"download-sample","summary":"Download Voice Sample","description":"Download a personal (cloned) voice sample","tags":["subpackage_tts.subpackage_tts/voices"],"parameters":[{"name":"id","in":"path","description":"The ID of the voice to download sample for","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Voice sample audio file","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents":{"post":{"operationId":"create","summary":"Create Agent","description":"Create a voice agent.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Agent"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateAgentRequest"}}}}},"get":{"operationId":"list","summary":"List Agents","description":"List voice agents owned by the caller.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of voice agents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAgentsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}":{"get":{"operationId":"get","summary":"Get Agent","description":"Retrieve a voice agent by ID.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Agent"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update","summary":"Update Agent","description":"Update a voice agent. Only fields present on the request body are changed.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Agent"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateAgentRequest"}}}}},"delete":{"operationId":"delete","summary":"Delete Agent","description":"Delete a voice agent. Conversations and attached tools remain.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Agent deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/conversations":{"post":{"operationId":"create-conversation","summary":"Create Conversation","description":"Start a new voice conversation with the agent. Returns a realtime\nvoice session + short-lived client token so the caller can\nconnect the audio pipeline directly. The agent is dispatched\nserver-side; no additional client action required.\n\nPass `dynamic_variables` to supply per-session values that override\nthe agent's stored variable defaults for this one conversation.\nKeys in the `system__` namespace are rejected at this boundary.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created conversation with its realtime session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateConversationResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateConversationRequest"}}}}}},"/v1/agents/{id}/sessions":{"post":{"operationId":"create-session","summary":"Create Session","description":"Mint a realtime voice session for the given agent. Widget-friendly\ncounterpart to `createConversation` \u2014 same response shape, dual\nauthentication:\n\n* **Authenticated (Bearer)**: works for any agent the caller\n owns. Typical server-to-server flow where the embedding\n site's backend mints a token and hands it to the browser so\n the API key never reaches the client.\n* **Unauthenticated**: works only when `agent.is_public = true`\n AND the request's `Origin` header matches `agent.allowed_origins`\n (or that list is empty). When `agent.hostname_allowlist` is\n non-empty, the `Origin` hostname must additionally be a\n member of that list. Used directly by the\n `` web component.\n\nResponds with the same `CreateConversationResponse` as\n`createConversation`.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The created session with its realtime token + URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateConversationResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"403":{"description":"The credential authenticated, but is not authorised for this\nresource - typically a workspace-role gate (owner / admin\nrequired) or a cross-tenant access attempt.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateSessionRequest"}}}}}},"/v1/agents/voices":{"get":{"operationId":"list-agent-voices","summary":"List Agent Voices","description":"List the curated voice catalogue available for voice agents.\nMatches the `ai-api-agents` VMS scope one-for-one, so the same\nslug set is accepted by POST/PATCH /v1/agents. Personal\n(cloned) voices are NOT included \u2014 they stay on\n`GET /v1/voices`. The JSON layout intentionally mirrors the\nTTS `/v1/voices` shape so the console feeds both endpoints\ninto the same voice-picker component.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The curated agent voice catalogue.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentVoice"}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/builtins":{"post":{"operationId":"create-builtin","summary":"Create Agent Builtin","description":"Create a new builtin instance on this agent. `builtin` must\nresolve to one of the names returned by\n`GET /v1/agents/tools/system-builtins`; unknown values are rejected.\n`name` is the LLM-facing identifier the model uses to call the\ntool; it must match the tool-name regex and be unique within\nthe agent's builtin set.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created builtin instance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentBuiltin"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateAgentBuiltinRequest"}}}}},"get":{"operationId":"list-builtins","summary":"List Agent Builtins","description":"List every builtin instance configured on this agent. Each row\nis one instance of a worker-resident capability (`end_call`,\n`play_audio`, etc.) bound to this specific agent with its own\nLLM-facing name, description, and per-call config. Same builtin\nmay appear N times on one agent \u2014 typically two `play_audio`\nrows bound to different audio assets.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The agent's builtin instances.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAgentBuiltinsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/builtins/{builtinId}":{"get":{"operationId":"get-builtin","summary":"Get Agent Builtin","description":"Fetch one builtin instance by ID.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"builtinId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The builtin instance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentBuiltin"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-builtin","summary":"Update Agent Builtin","description":"Update a builtin instance. All fields optional; omitting a\nfield leaves it unchanged. The underlying `builtin` (which\ncapability the instance maps to) is intentionally NOT\npatchable \u2014 change of identity would surprise the worker, so\nthe customer should delete and recreate instead.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"builtinId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated builtin instance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentBuiltin"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateAgentBuiltinRequest"}}}}},"delete":{"operationId":"delete-builtin","summary":"Delete Agent Builtin","description":"Delete a builtin instance from this agent. Idempotent on\nalready-deleted ids (404). Does NOT detach references from\nflow nodes that name the instance; the worker logs and skips\non missing-row at session start (fail-soft).\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"builtinId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Builtin instance deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/variables":{"get":{"operationId":"get-dynamic-variables","summary":"Get Dynamic Variables","description":"Retrieve the agent's customer-scope dynamic variables and the read-only\ncatalogue of reserved `system__*` keys. The system variables list is\nprovided so editor UIs can render the reference list without maintaining\na client-side copy of the catalogue.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The agent's variable catalogue.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListDynamicVariablesResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-dynamic-variables","summary":"Update Dynamic Variables","description":"Replace the agent's customer-scope dynamic variable definitions.\nThe supplied list overwrites the stored list wholesale (same\nsemantics as `updateEvaluationConfig`). Pass an empty array to\nclear all variables. Up to 20 variables per agent. Keys must\nmatch `[a-zA-Z0-9_]+` and must not start with the reserved\n`system__` prefix.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated variable catalogue.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListDynamicVariablesResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateDynamicVariablesRequest"}}}}}},"/v1/agents/{id}/evaluation-config":{"get":{"operationId":"get-evaluation-config","summary":"Get Evaluation Config","description":"Retrieve the agent's post-call evaluation criteria + data-collection config.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The evaluation config for the agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:EvaluationConfig"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-evaluation-config","summary":"Update Evaluation Config","description":"Replace the agent's evaluation criteria + data-collection fields.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated evaluation config.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:EvaluationConfig"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateEvaluationConfigRequest"}}}}}},"/v1/agents/{id}/knowledge-bases":{"get":{"operationId":"list-agent-knowledge-bases","summary":"List Agent Knowledge Bases","description":"List knowledge bases attached to an agent. Bare list \u2014 the\nattachment count is bounded by configuration, not by data\nscale, so this endpoint does not paginate.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The knowledge bases attached to the agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AttachedKnowledgeBasesResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/knowledge-bases/{kbId}":{"post":{"operationId":"attach-knowledge-base","summary":"Attach Agent Knowledge Base","description":"Attach a knowledge base to an agent. The `search_knowledge` tool\nis auto-registered on the next conversation and can only query the\nattached knowledge bases.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"kbId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Knowledge base attached.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"detach-knowledge-base","summary":"Detach Agent Knowledge Base","description":"Detach a knowledge base from an agent.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"kbId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Knowledge base detached.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/memories":{"get":{"operationId":"list-memories","summary":"List Agent Memories","description":"List per-caller memories extracted for an agent. Memories are\nwritten post-call by the built-in extractor when `memory_enabled`\nis true on the agent; the list is sorted newest-first.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Maximum rows to return. Defaults to 100, capped at 200.","required":false,"schema":{"type":"integer","default":100}},{"name":"offset","in":"query","description":"Number of rows to skip. Combine with `limit` to page through older memories.","required":false,"schema":{"type":"integer","default":0}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Memories for the agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListMemoriesResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/memories/delete":{"post":{"operationId":"delete-memories-by-caller","summary":"Delete Memories by Caller","description":"Delete every memory ever extracted for a specific caller on\nthis agent. Privacy / GDPR surface. Returns the count of rows\nsoft-deleted; rows become permanently unreachable immediately\nand are hard-deleted by the retention job after the tenant's\nconfigured retention window.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deletion summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:DeleteMemoriesByCallerResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:DeleteMemoriesByCallerRequest"}}}}}},"/v1/agents/{id}/tests":{"get":{"operationId":"list-tests","summary":"List Agent Tests","description":"List all tests configured for the agent. Each entry includes the\nmost recent run so the console can render pass/fail badges without\nan extra round-trip.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tests for the agent with last-run summaries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAgentTestsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"post":{"operationId":"create-test","summary":"Create Agent Test","description":"Create a new test for the agent.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created test.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTest"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateAgentTestRequest"}}}}}},"/v1/agents/{id}/tests/runs":{"post":{"operationId":"run-all-tests","summary":"Run All Agent Tests","description":"Enqueue runs for every test on the agent concurrently. Up to 50\ntests are dispatched in one call. Each returned run starts in\n`queued` status; poll `GET /v1/agents/tests/runs/{id}` for the terminal\nresult.\n\nAn optional request body (AIS-3443) runs the whole suite against\na proposed config: a `config_override` (prompt / model / tools)\napplied to every test without editing the tests, and/or a\n`flow_version_id` to target a specific flow version instead of\nthe agent's active flow. Omit the body to run against the\nagent's live config and active flow.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Queued runs for all tests on the agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RunAgentTestsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RunAllTestsRequest"}}}}}},"/v1/agents/{id}/tools":{"get":{"operationId":"list-tools","summary":"List Agent Tools","description":"List tools currently attached to the agent. Bare list \u2014 an\nagent's tool attachment count is bounded by configuration, so\nthis endpoint does not paginate.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Attached tools for the agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AttachedToolsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/tools/{toolId}":{"post":{"operationId":"attach-tool","summary":"Attach Tool","description":"Attach an existing tool to the agent so the LLM can call it.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"toolId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Tool attached.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"detach-tool","summary":"Detach Tool","description":"Detach a tool from the agent.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"toolId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Tool detached.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/widget-config":{"get":{"operationId":"get-widget-config","summary":"Get Agent Widget Config","description":"Return the embed-widget appearance config for an agent. Works\nunauthenticated for public agents; the body is cosmetic only.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The agent's widget configuration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:WidgetConfig"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations":{"get":{"operationId":"list","summary":"List Conversations","description":"List conversations owned by the caller, ordered by most recent.\nCursor-paginated: omit `cursor` to fetch the first page; pass the\nprevious response's `next_cursor` back to fetch the next page.\nWalk pages while `has_more` is true.","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max conversations per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"agent_id","in":"query","description":"Filter to conversations for this agent.","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Filter by conversation status.","required":false,"schema":{"$ref":"#/components/schemas/tts:ConversationStatus"}},{"name":"transport","in":"query","description":"Filter by transport.","required":false,"schema":{"$ref":"#/components/schemas/tts:ConversationTransport"}},{"name":"caller_identity","in":"query","description":"Filter by caller identity.","required":false,"schema":{"type":"string"}},{"name":"search","in":"query","description":"Free-text search across conversation content.","required":false,"schema":{"type":"string"}},{"name":"started_after","in":"query","description":"Only conversations started at or after this RFC 3339 timestamp.","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"started_before","in":"query","description":"Only conversations started at or before this RFC 3339 timestamp.","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"duration_min_ms","in":"query","description":"Minimum conversation duration in milliseconds.","required":false,"schema":{"type":"integer"}},{"name":"duration_max_ms","in":"query","description":"Maximum conversation duration in milliseconds.","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of conversations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListConversationsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}":{"get":{"operationId":"get","summary":"Get Conversation","description":"Retrieve a conversation by ID.","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested conversation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Conversation"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/messages":{"get":{"operationId":"list-messages","summary":"List Messages","description":"Retrieve the transcript for a conversation in started_at order\n(oldest first). Cursor-paginated: omit `cursor` to fetch the\nfirst page. Default page size is 50 and max is 200. Walk pages\nwhile `has_more` is true.","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max messages per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The messages for the conversation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListMessagesResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/evaluations":{"get":{"operationId":"list-evaluations","summary":"List Evaluations","description":"Retrieve post-call evaluation results for a conversation.","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The evaluations for the conversation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListEvaluationsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/memories":{"get":{"operationId":"list-memories","summary":"List Conversation Memories","description":"List memories extracted from a specific conversation.","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Memories written during this conversation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListMemoriesResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/stats":{"get":{"operationId":"stats","summary":"Conversation stats","description":"Aggregated counts and averages over the caller's conversations, scoped by the same filters as the list endpoint.","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"agent_id","in":"query","description":"Filter to conversations for this agent.","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Filter by conversation status.","required":false,"schema":{"$ref":"#/components/schemas/tts:ConversationStatus"}},{"name":"transport","in":"query","description":"Filter by transport.","required":false,"schema":{"$ref":"#/components/schemas/tts:ConversationTransport"}},{"name":"caller_identity","in":"query","description":"Filter by caller identity.","required":false,"schema":{"type":"string"}},{"name":"search","in":"query","description":"Free-text search across conversation content.","required":false,"schema":{"type":"string"}},{"name":"started_after","in":"query","description":"Only conversations started at or after this RFC 3339 timestamp.","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"started_before","in":"query","description":"Only conversations started at or before this RFC 3339 timestamp.","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"duration_min_ms","in":"query","description":"Minimum conversation duration in milliseconds.","required":false,"schema":{"type":"integer"}},{"name":"duration_max_ms","in":"query","description":"Maximum conversation duration in milliseconds.","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Stats for the matched conversations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ConversationStats"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/recent-callees":{"get":{"operationId":"recent-callees","summary":"List recent callees","description":"Distinct phone numbers the caller's workspace has dialled on\noutbound calls, ordered by most recent. Feeds the batch-calls\ncomposer's \"Suggested from history\" surface. Cursor-paginated:\nomit `cursor` to fetch the first page. Default page size is 50\nand max is 200. Walk pages while `has_more` is true.\n","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max number of distinct phone numbers per page. Defaults to 50; clamped to 200.","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recent callees for the caller's workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListRecentCalleesResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/recording":{"get":{"operationId":"stream-recording","summary":"Stream Recording","description":"Proxy the GCS-stored audio recording for a conversation through\nthe Cloud Run service identity. Returns OGG/Opus bytes (LiveKit\nroom-composite egress default). The response is streamed so a\nlong recording does not buffer in memory; `` consumers\ncan seek directly. Only present when the agent had\n`save_audio_recording` enabled at session start.\n","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The recorded audio.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/webhook-deliveries":{"get":{"operationId":"list-webhook-deliveries","summary":"List Webhook Deliveries","description":"List post-call webhook delivery attempts for a conversation,\nnewest first. Rows appear once the LiveKit `room_finished`\nwebhook has fired and the post-call webhook has been\ndispatched to the agent's configured URL. One row per\n`(conversation, webhook-url)`, updated in place across retries.\nCursor-paginated: omit `cursor` to fetch the first page.\nDefault page size is 50 and max is 200. Walk pages while\n`has_more` is true.\n","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max deliveries per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The post-call webhook deliveries for the conversation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListWebhookDeliveriesResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/retrieval-log":{"get":{"operationId":"list-retrieval-log","summary":"List Retrieval Log","description":"Per-conversation retrieval log, newest first \u2014 one row per\n`search_knowledge` invocation made during the call. Each entry\nrecords the query, ranked chunks (denormalised so deletions\ndon't render history unreadable), `top_k`, and hit count.\nPowers the Retrieval panel on the conversation detail view.\nCursor-paginated: omit `cursor` to fetch the first page.\nDefault page size is 50 and max is 200. Walk pages while\n`has_more` is true.\n","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max retrieval log entries per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The retrieval log entries for the conversation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListRetrievalLogsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases":{"post":{"operationId":"create","summary":"Create Knowledge Base","description":"Create a new knowledge base.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created knowledge base.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBase"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateKnowledgeBaseRequest"}}}}},"get":{"operationId":"list","summary":"List Knowledge Bases","description":"List knowledge bases owned by the caller. Cursor-paginated:\nomit `cursor` to fetch the first page. The default page size is\n50 and the max is 200; values outside that range are clamped.\nWalk pages while `has_more` is true.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max knowledge bases per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The knowledge bases for the caller.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListKnowledgeBasesResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/{id}":{"get":{"operationId":"get","summary":"Get Knowledge Base","description":"Retrieve a knowledge base by ID.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested knowledge base.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBase"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update","summary":"Update Knowledge Base","description":"Update a knowledge base.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated knowledge base.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBase"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateKnowledgeBaseRequest"}}}}},"delete":{"operationId":"delete","summary":"Delete Knowledge Base","description":"Soft-delete a knowledge base. Documents and chunks are cascaded.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Knowledge base deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/{id}/documents":{"post":{"operationId":"upload-document","summary":"Upload Knowledge Base Document","description":"Upload a document (PDF, plain text, markdown, or HTML) to a\nknowledge base. The document is extracted, chunked, embedded, and\nindexed synchronously; expect a few seconds per MB of input.\nMaximum 10 MB per upload.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The ingested document record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocument"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"413":{"description":"Request body exceeded a per-endpoint size limit (e.g. KB\ndocument upload cap, batch-call CSV cap, audio-asset WAV cap).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}}},"get":{"operationId":"list-documents","summary":"List Knowledge Base Documents","description":"List documents ingested into a knowledge base. Cursor-paginated:\nomit `cursor` to fetch the first page. Default page size is 50\nand max is 200. Walk pages while `has_more` is true.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"folder_id","in":"query","description":"Folder filter: omit for root-level documents, pass `all` for\nevery document in the KB, or a folder id to scope to that\nfolder.\n","required":false,"schema":{"type":"string"}},{"name":"q","in":"query","description":"Substring match on filename and source_url.","required":false,"schema":{"type":"string"}},{"name":"source_kind","in":"query","description":"Comma-separated source kinds (file|url|text).","required":false,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max documents per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The documents in the knowledge base.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListKnowledgeBaseDocumentsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/{id}/documents/{docId}":{"get":{"operationId":"get-document","summary":"Get Knowledge Base Document","description":"Retrieve a document by ID.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"docId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The document record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocumentDetail"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"delete-document","summary":"Delete Knowledge Base Document","description":"Delete a document and all its chunks.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"docId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Document deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-document","summary":"Update Knowledge Base Document","description":"Update a document. Currently supports moving the document\nbetween folders via `folder_id`.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"docId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Document updated.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"folder_id":{"type":["string","null"],"description":"Destination folder. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null moves the\ndocument to the knowledge base root.\n"}}}}}}}},"/v1/agents/knowledge-bases/{id}/documents/{docId}/chunks":{"get":{"operationId":"list-chunks","summary":"List Knowledge Base Chunks","description":"List the chunks for a document. Cursor-paginated: omit `cursor`\nto fetch the first page. Default page size is 50 and max is 200.\nWalk pages while `has_more` is true.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"docId","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max chunks per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The chunks for the document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListKnowledgeBaseChunksResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/search":{"post":{"operationId":"search","summary":"Search Knowledge Bases","description":"Semantic search across a caller-owned list of knowledge bases.\nReturns ranked chunks with source filename and a cosine-similarity\nscore. Limited to 50 results per request.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Ranked search hits across the selected knowledge bases.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:SearchKnowledgeBasesResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:SearchKnowledgeBasesRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/text":{"post":{"operationId":"create-text-document","summary":"Create Text Document","description":"Create a document from inline pasted text. Content is chunked,\nembedded, and indexed synchronously.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocument"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateTextDocumentRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/url":{"post":{"operationId":"create-url-document","summary":"Create URL Document","description":"Fetch a URL via Firecrawl and ingest the rendered content as a\ndocument. The fetch happens synchronously; expect a few\nseconds per page. Use the sitemap / crawl endpoints for\nmulti-page imports.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocument"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateURLDocumentRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/sitemap":{"post":{"operationId":"create-sitemap-import","summary":"Create Sitemap Import","description":"Kick off an async sitemap import. Returns 202 with the import\njob row; client polls `GET /{id}/imports` for progress.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Import job queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ImportJobResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateSitemapImportRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/crawl":{"post":{"operationId":"create-crawl-import","summary":"Create Crawl Import","description":"Kick off an async website crawl. Returns 202 with the import\njob row; client polls `GET /{id}/imports` for progress.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Import job queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ImportJobResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateCrawlImportRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/urls":{"post":{"operationId":"create-url-batch-import","summary":"Create Multi-URL Import","description":"Kick off an async multi-URL import. Accepts 1..N URLs in a\nsingle job (capped per-deployment, default 50) and runs the\nsame per-URL pipeline as the sitemap worker. Returns 202 with\nthe import job row; client polls `GET /{id}/imports` for\nprogress.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Import job queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ImportJobResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateURLBatchImportRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/imports":{"get":{"operationId":"list-import-jobs","summary":"List Import Jobs","description":"List import jobs (sitemap / crawl / refresh) for a knowledge base.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The import jobs for the knowledge base.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListImportJobsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/{id}/imports/{importId}/cancel":{"post":{"operationId":"cancel-import-job","summary":"Cancel Import Job","description":"Cancel a non-terminal import job. Idempotent on terminal jobs\n(completed / failed / cancelled) \u2014 the cancel call returns the\nunchanged row.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"importId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The (possibly already-terminal) import job row.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ImportJob"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/{id}/documents/batch":{"delete":{"operationId":"batch-delete-documents","summary":"Batch Delete Documents","description":"Delete multiple documents in a single transaction. All ids\nmust belong to the supplied knowledge base; mismatches fail\nthe request with 400 before any rows are touched. Capped at\n200 ids per call.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Documents deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:BatchDeleteDocumentsRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/batch/move":{"patch":{"operationId":"batch-move-documents","summary":"Batch Move Documents","description":"Move multiple documents into a folder in a single transaction.\nPass `folder_id: null` to move every doc to root. Capped at\n200 ids per call.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Documents moved.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:BatchMoveDocumentsRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/{docId}/refresh-config":{"patch":{"operationId":"update-refresh-config","summary":"Update Refresh Config","description":"Update the per-document auto-refresh state. Only meaningful\nfor url-sourced documents; file and text rows reject the\nrequest.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"docId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated refresh config.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RefreshConfig"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateRefreshConfigRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/{docId}/refresh-history":{"get":{"operationId":"list-refresh-history","summary":"List Refresh History","description":"List recent auto-refresh attempts for a document.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"docId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recent refresh attempts for the document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListRefreshHistoryResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/{id}/folders":{"get":{"operationId":"list-folders","summary":"List Folders","description":"List folders inside a knowledge base. Root-level folders have\n`parent_folder_id: null`. Cursor-paginated: omit `cursor` to\nfetch the first page. Default page size is 50 and max is 200.\nThe console builds the folder tree from `parent_folder_id`, so\nconsumers should walk every page until `has_more` is `false`\nbefore rendering the tree.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max folders per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Folders in the knowledge base.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListKnowledgeBaseFoldersResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"post":{"operationId":"create-folder","summary":"Create Folder","description":"Create a folder inside a knowledge base.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created folder.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBaseFolder"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateFolderRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/folders/{folderId}":{"delete":{"operationId":"delete-folder","summary":"Delete Folder","description":"Delete a folder. Documents inside the folder are moved to root\n(not deleted). Sub-folders are detached likewise.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"folderId","in":"path","required":true,"schema":{"type":"string"}},{"name":"force","in":"query","description":"When true, delete the folder even if it still contains documents or sub-folders; contents are moved to root.","required":false,"schema":{"type":"boolean"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Folder deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-folder","summary":"Update Folder","description":"Update a folder. Pass `parent_folder_id: null` to move to\nroot; omit the field to leave it unchanged.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"folderId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated folder.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBaseFolder"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateFolderRequest"}}}}}},"/v1/agents/memories/{memoryId}":{"delete":{"operationId":"delete","summary":"Delete Memory","description":"Soft-delete one memory row.","tags":["subpackage_tts.subpackage_tts/memories"],"parameters":[{"name":"memoryId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Memory deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests":{"get":{"operationId":"list-all-tests","summary":"List Tests","description":"Workspace-wide list of tests across every agent the caller owns.\nSupports filters (agent, type, last-run status, folder), full-text\nsearch on name/description, and cursor pagination. Each row carries\nits newest run and attached agent IDs so the list renders without\nN+1 round-trips. Walk pages while `has_more` is true.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"agent_id","in":"query","description":"Comma-separated agent IDs to filter on.","required":false,"schema":{"type":"string"}},{"name":"type","in":"query","description":"Comma-separated test types (reply|tool|simulation).","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Comma-separated last-run statuses.","required":false,"schema":{"type":"string"}},{"name":"folder_id","in":"query","description":"Folder ID to filter on, or \"root\" for unfiled tests.","required":false,"schema":{"type":"string"}},{"name":"updated_after","in":"query","description":"Only return tests updated after this RFC3339 timestamp.","required":false,"schema":{"type":"string"}},{"name":"q","in":"query","description":"Substring match on name or description.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max tests per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListTestsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/stats":{"get":{"operationId":"get-test-stats","summary":"Get Test Stats","description":"Aggregate pass-rate metrics over the last N days. Returns dense\ndaily buckets (one entry per day, zero-filled) plus totals and a\nper-type breakdown. Powers the header chart on the global tests\npage. Default window is 30 days, max 90.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"window_days","in":"query","description":"Trailing window in days (default 30, max 90).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Stats payload.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:TestStats"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/{id}":{"get":{"operationId":"get-test","summary":"Get Agent Test","description":"Retrieve a test by ID.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested test.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTest"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-test","summary":"Update Agent Test","description":"Update a test. Only fields present on the request body are changed.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated test.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTest"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateAgentTestRequest"}}}}},"delete":{"operationId":"delete-test","summary":"Delete Agent Test","description":"Delete a test and all its run history.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Test deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/{id}/attachments":{"get":{"operationId":"list-test-attachments","summary":"List Test Attachments","description":"List every agent a test is attached to.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Attachment list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAgentTestAttachmentsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/{id}/attachments/{agentId}":{"post":{"operationId":"attach-test","summary":"Attach Test","description":"Attach a test to an additional agent. After this call, the test\nwill also run as part of that agent's regression suite (and\nagainst its prompt + tool config when invoked with\n`agent_id = {agentId}`). Idempotent.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"agentId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Attached.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"detach-test","summary":"Detach Test","description":"Detach a test from an agent. The owner agent (the agent the test\nwas authored against) cannot be detached; delete the test\ninstead.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"agentId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Detached.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/folders":{"get":{"operationId":"list-test-folders","summary":"List Test Folders","description":"List every test folder the caller owns. Flat list; build the tree client-side.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Folder list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAgentTestFoldersResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"post":{"operationId":"create-test-folder","summary":"Create Test Folder","description":"Create a test folder. Max depth is 3.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Created folder.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTestFolder"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateAgentTestFolderRequest"}}}}}},"/v1/agents/tests/folders/{id}":{"patch":{"operationId":"update-test-folder","summary":"Update Test Folder","description":"Rename or reparent a test folder. Cycles are rejected.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Updated folder.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTestFolder"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateAgentTestFolderRequest"}}}}},"delete":{"operationId":"delete-test-folder","summary":"Delete Test Folder","description":"Soft-delete a folder. Child tests drop back to root.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/{id}/runs":{"post":{"operationId":"run-test","summary":"Run Agent Test","description":"Enqueue a single run of the test. The returned run starts in\n`queued` status. Poll `GET /v1/agents/tests/runs/{id}` until the status\nreaches a terminal state (`passed`, `failed`, or `error`).","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"The queued run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTestRun"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string","description":"Run the test against this agent instead of the test's default agent."}}}}}}},"get":{"operationId":"list-test-runs","summary":"List Agent Test Runs","description":"List one page of run history for a test, newest first.\nPaginate by passing `cursor` from the previous response.\n","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque cursor from a prior response's `next_cursor`.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size. Defaults to 50; capped at 200.","required":false,"schema":{"type":"integer","default":50}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Run history for the test.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAgentTestRunsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/runs/{id}":{"get":{"operationId":"get-test-run","summary":"Get Agent Test Run","description":"Retrieve a single test run by ID. Poll this endpoint until\n`status` reaches a terminal state (`passed`, `failed`, or `error`).\nThe `result` field is populated on terminal states.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The test run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTestRun"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/runs/batch":{"post":{"operationId":"run-tests-batch","summary":"Run Tests (Batch)","description":"Queue runs for every (test, agent) pair in the body. Entries\nwithout an `agent_id` fan out to every agent the test is\nattached to. Total expanded runs are capped at 100 per call.\nEach entry in the response is a queued run; poll\n`GET /v1/agents/tests/runs/{id}` for each.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Runs queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RunBatchResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RunBatchRequest"}}}}}},"/v1/agents/tests/suite-runs":{"get":{"operationId":"list-suite-runs","summary":"List Suite Runs","description":"List one page of suite runs (test invocations), newest first.\nA suite run groups every test run dispatched by one Run All,\nbatch, or resubmit call. Paginate by passing `cursor` from the\nprevious response.\n","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"agent_id","in":"query","description":"Narrow the list to the suite runs of one agent.","required":false,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque cursor from a prior response's `next_cursor`.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size. Defaults to 50; capped at 200.","required":false,"schema":{"type":"integer","default":50}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"One page of suite runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListSuiteRunsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/suite-runs/{id}":{"get":{"operationId":"get-suite-run","summary":"Get Suite Run","description":"Retrieve a suite run by ID with its child runs and the derived\naggregate status and pass/fail/error counts.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The suite run with its child runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTestSuiteRunWithRuns"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/suite-runs/{id}/resubmit":{"post":{"operationId":"resubmit-suite-run","summary":"Resubmit Suite Run","description":"Re-run the failed and errored tests of a suite run as a fresh\nsuite run, linked back to the original via\n`parent_suite_run_id`. Returns 400 when the suite run has no\nfailed or errored tests to re-run.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"The new suite run and its queued child runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RunAgentTestsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tools":{"post":{"operationId":"create","summary":"Create Tool","description":"Create a tool. For webhook tools, the response includes the HMAC\n`webhook_secret` exactly once \u2014 store it immediately; subsequent\nreads return a masked placeholder.\n","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Tool"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateToolRequest"}}}}},"get":{"operationId":"list","summary":"List Tools","description":"List tools in the caller's workspace, most recently updated\nfirst. Cursor-paginated: omit `cursor` to fetch the first page.\nDefault page size is 50 and max is 200. Walk pages while\n`has_more` is true.","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max tools per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of tools.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListToolsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tools/{id}":{"get":{"operationId":"get","summary":"Get Tool","description":"Retrieve a tool by ID. Webhook secrets are always masked here.","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Tool"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update","summary":"Update Tool","description":"Update a tool. Tool kind is immutable \u2014 create a new tool to change it.","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Tool"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateToolRequest"}}}}},"delete":{"operationId":"delete","summary":"Delete Tool","description":"Delete a tool. Agents that had it attached get a soft-detach.","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Tool deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tools/system-builtins":{"get":{"operationId":"list-system-builtins","summary":"List System Builtins","description":"Read-only catalogue of every system builtin the worker knows\nabout. The console fetches this at runtime rather than\nmaintaining a parallel client-side list (AIS-3074); the server\nis the single source of truth for the label and description\ncopy a customer sees in the builtin-instance picker.\n","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The catalogue of registered system builtins.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListSystemBuiltinsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tools/{id}/attached-agents":{"get":{"operationId":"list-attached-agents","summary":"List Tool Attached Agents","description":"List the agents in the caller's workspace that currently have\nthis tool attached. Useful before deleting a tool, to surface\nwhich agents will lose access. Soft-deleted agents are filtered\nout. Bounded by the number of agents per workspace (tens), so\nthe response is not paginated (see ADR 0013).\n","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Agents in the caller's workspace attached to the tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListToolAttachedAgentsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tools/{id}/rotate-secret":{"post":{"operationId":"rotate-secret","summary":"Rotate Tool Webhook Secret","description":"Rotate the HMAC signing secret on a webhook tool. The tool id\nis preserved so attached agents keep working; only the secret\nrolls. The new plaintext is returned on `webhook_secret`\nexactly once \u2014 store it immediately, subsequent reads always\nreturn the masked placeholder. The previous secret is\ninvalidated immediately on success.\n","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The tool with its newly-rotated webhook_secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Tool"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tools/test-mcp-connection":{"post":{"operationId":"test-mcp-connection","summary":"Test MCP Connection","description":"Probe a customer-supplied MCP server config without persisting\nanything. The server opens the configured transport, runs the\n`initialize` + `list_tools` handshake, and returns either the\ndiscovered tool catalogue or a structured error string. Pass\n`tool_id` from the edit-form flow when the auth payload carries\n`_set` markers but no plaintext, so the server can hydrate the\nstored secret from the encrypted column before probing.\n","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Probe result. The 200 envelope is used for both success and\nstructured failure \u2014 inspect `error` to disambiguate. Network\nand validation failures never bubble up as non-2xx so the\nconsole can render them inline next to the form.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:MCPProbeResult"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:TestMCPConnectionRequest"}}}}}},"/v1/agents/tools/test-webhook-connection":{"post":{"operationId":"test-webhook-connection","summary":"Test Webhook Connection","description":"Probe a customer-supplied webhook tool config without persisting\nanything. The server fires the exact request shape the worker\nsends on a real invocation \u2014 same JSON body, same HMAC-SHA256\nsignature \u2014 with an empty argument set, and reports the\nendpoint's status code, latency, and a truncated response body,\nor a transport-level failure reason. The probe carries an\n`X-Speechify-Webhook-Test: true` header so a careful endpoint\ncan recognise the test and skip its real side effect. Pass\n`tool_id` from the edit-form flow so the server signs the probe\nwith the tool's stored HMAC secret.\n","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Probe result. The 200 envelope is used for both success and\nstructured failure \u2014 inspect `error` to disambiguate. A\nnon-2xx response from the endpoint is NOT an `error`: it\npopulates `status_code` / `response_body` with `ok=false`.\nTransport and validation failures never bubble up as non-2xx\nso the console can render them inline next to the form.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:WebhookProbeResult"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:TestWebhookConnectionRequest"}}}}}},"/v1/agents/callers":{"get":{"operationId":"list","summary":"List Callers","description":"List the workspace's callers, ordered by most-recently-seen first.\nA caller is the per-(tenant, agent, identity) entity that owns\nlong-term memories and conversation history. Phase 2 of ADR 0011.\n","tags":["subpackage_tts.subpackage_tts/callers"],"parameters":[{"name":"agent_id","in":"query","description":"Narrow the list to callers attached to one agent.","required":false,"schema":{"type":"string"}},{"name":"q","in":"query","description":"Identity-prefix search. Filters to rows where `identity LIKE q + '%'`\n(`%`/`_` characters in the input are escaped as literals).\n","required":false,"schema":{"type":"string"}},{"name":"last_seen_after","in":"query","description":"RFC 3339 timestamp. Narrows to callers active strictly AFTER the\nsupplied moment. Useful for \"active this week / month\" filters.\n","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor from a prior response's `next_cursor`.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size. Defaults to 50; capped at 200.","required":false,"schema":{"type":"integer","default":50}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListCallersResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/callers/{id}":{"get":{"operationId":"get","summary":"Get Caller","description":"Fetch a single caller by id. Returns 404 for soft-deleted or\nforeign-tenant rows \u2014 GDPR-purged callers appear as \"not found\"\nto the API.\n","tags":["subpackage_tts.subpackage_tts/callers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetCallerResponse"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"delete","summary":"Delete Caller (GDPR purge)","description":"Soft-delete the caller AND cascade soft-delete every memory row\npointing at it. Conversations survive (forensic / billing records)\nbut their caller pointer surfaces as \"deleted\" through the API.\n\nIdempotent \u2014 re-deleting an already-purged caller returns\n`{caller_purged: 0, memories_purged: 0}`. Audit row counts\naccompany every response so a privacy operator has direct\nevidence of the purge without re-querying.\n","tags":["subpackage_tts.subpackage_tts/callers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Soft-delete completed; row counts in the body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:DeleteCallerResponse"}}}}}},"patch":{"operationId":"update","summary":"Update Caller","description":"Update the customer-editable fields on a caller. PATCH semantics:\nomitted fields are unchanged, present fields overwrite. To clear\na nullable field (`display_name`, `external_ref`) pass an empty\nstring. `metadata` REPLACES the existing JSONB blob when supplied.\n","tags":["subpackage_tts.subpackage_tts/callers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The refreshed caller row.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetCallerResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateCallerRequest"}}}}}},"/v1/agents/callers/{id}/memories":{"get":{"operationId":"list-memories","summary":"List Memories For Caller","description":"List one page of memories belonging to the caller, newest first.\nSoft-deleted memories AND memories whose parent caller is\nsoft-deleted are hidden \u2014 the GDPR purge semantics require the\nAPI to behave as if those rows do not exist.\n","tags":["subpackage_tts.subpackage_tts/callers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque cursor from a prior response's `next_cursor`.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size. Defaults to 50; capped at 200.","required":false,"schema":{"type":"integer","default":50}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListCallerMemoriesResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/callers/{id}/conversations":{"get":{"operationId":"list-conversations","summary":"List Conversations For Caller","description":"List one page of conversations belonging to the caller, newest\nstarted first. Same wire envelope as the workspace-wide\n`GET /v1/agents/conversations`, narrowed to one caller.\n","tags":["subpackage_tts.subpackage_tts/callers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque cursor from a prior response's `next_cursor`.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size. Defaults to 50; capped at 200.","required":false,"schema":{"type":"integer","default":50}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListCallerConversationsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/audio-assets":{"get":{"operationId":"list","summary":"List Audio Assets","description":"List every non-deleted audio asset in the caller's workspace.\nAudio assets are pre-recorded WAV clips (intro jingles, legal\ndisclaimers, hold cues) referenced from `play_audio` flow nodes\nand the corresponding system builtin.\n","tags":["subpackage_tts.subpackage_tts/audioAssets"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of audio assets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAudioAssetsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"post":{"operationId":"upload","summary":"Upload Audio Asset","description":"Upload a new audio asset. The body is a multipart/form-data\nrequest with a single `file` field carrying the WAV bytes.\n\nThe WAV is validated server-side against a strict format\ncontract \u2014 PCM 16-bit signed, mono, 48000 Hz, \u226430s, \u22644 MiB \u2014\nbefore any bytes hit storage. The strict shape matches the\nLiveKit room sample rate so the worker reads bytes straight\ninto `rtc.AudioFrame` with no decode dependency on either side;\nconvert MP3 sources with `ffmpeg -i in.mp3 -ar 48000 -ac 1\n-sample_fmt s16 out.wav`.\n","tags":["subpackage_tts.subpackage_tts/audioAssets"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The uploaded asset's metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UploadAudioAssetResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"The WAV file bytes. Must be PCM 16-bit signed, mono,\n48000 Hz, \u226430s duration, \u22644 MiB total.\n"}},"required":["file"]}}}}}},"/v1/agents/audio-assets/{id}":{"get":{"operationId":"get","summary":"Get Audio Asset","description":"Fetch one audio asset's metadata. Returns 404 for missing,\nsoft-deleted, or foreign-tenant assets \u2014 existence information\nis never leaked across tenants.\n","tags":["subpackage_tts.subpackage_tts/audioAssets"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The audio asset's metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AudioAsset"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"delete","summary":"Delete Audio Asset","description":"Soft-delete an audio asset. The underlying GCS object is\nretained so any flow node or tool still referencing the asset\nkeeps working until the config is updated; the worker logs\nand skips on missing-row at session start (fail-soft).\n","tags":["subpackage_tts.subpackage_tts/audioAssets"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Audio asset soft-deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/audio-assets/{id}/bytes":{"get":{"operationId":"get-bytes","summary":"Get Audio Asset Bytes","description":"Stream the raw WAV bytes for an audio asset. Byte-stream\nsibling of the metadata endpoint at /v1/agents/audio-assets/{id}.\nThe LiveKit worker fetches through here for the play_audio\nbuiltin; SDK consumers can also download originals. Returns 404\nfor missing / soft-deleted / foreign-tenant assets.\n","tags":["subpackage_tts.subpackage_tts/audioAssets"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The raw audio bytes (PCM 16-bit signed, mono, 48 kHz, WAV-wrapped).","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}}}}},"/v1/agents/{id}/flow":{"get":{"operationId":"get-flow","summary":"Get Agent Flow","description":"Return the agent's flow graph: the current draft (if any), the\nactive published graph (if any), and the version history.\n","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The draft graph, active graph, and version history.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetFlowResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"put":{"operationId":"update-flow","summary":"Update Agent Flow Draft","description":"Replace the agent's draft flow graph. The graph is validated\nbefore it is stored; publish it separately to make it active.\n","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The stored draft graph.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowGraph"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PutFlowRequest"}}}}}},"/v1/agents/{id}/flow/draft":{"delete":{"operationId":"discard-draft","summary":"Discard Agent Flow Draft","description":"Discard the agent's unpublished draft flow graph.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Draft discarded.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/flow/publish":{"post":{"operationId":"publish","summary":"Publish Agent Flow","description":"Publish the agent's draft graph as a new active flow version.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The newly published flow version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowVersion"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PublishFlowRequest"}}}}}},"/v1/agents/{id}/flow/rollback":{"post":{"operationId":"rollback","summary":"Roll Back Agent Flow","description":"Publish a prior flow version as the active graph.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The flow version that is now active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowVersion"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RollbackFlowRequest"}}}}}},"/v1/agents/{id}/flow/deactivate":{"post":{"operationId":"deactivate","summary":"Deactivate Agent Flow","description":"Deactivate the agent's published flow so the agent runs the synthesized default flow.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Flow deactivated.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/flow/versions":{"get":{"operationId":"list-versions","summary":"List Agent Flow Versions","description":"List every published flow version for the agent, newest first.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The agent's flow version history.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListFlowVersionsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/flow/versions/{versionId}":{"get":{"operationId":"get-version","summary":"Get Agent Flow Version","description":"Return the full flow graph for a specific published version.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"versionId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested flow version's graph.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetFlowVersionResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/flow/schema":{"get":{"operationId":"get-schema","summary":"Get Flow Graph Schema","description":"Return the JSON Schema describing the flow graph node taxonomy.\nUnauthenticated; flow editors fetch it to validate graphs client-side.\n","tags":["subpackage_tts.subpackage_tts/flow"],"responses":{"200":{"description":"A JSON Schema document for the flow graph.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:flow_getSchema_Response_200"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/flow/templates":{"get":{"operationId":"list-templates","summary":"List Flow Templates","description":"List the reusable flow templates available to the workspace.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The available flow templates.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListFlowTemplatesResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"post":{"operationId":"create-template","summary":"Create Flow Template","description":"Create a reusable flow template from a graph.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The created flow template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowTemplate"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateFlowTemplateRequest"}}}}}},"/v1/agents/flow/templates/{id}":{"get":{"operationId":"get-template","summary":"Get Flow Template","description":"Retrieve a flow template by id.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested flow template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowTemplate"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"delete-template","summary":"Delete Flow Template","description":"Delete a flow template.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Template deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-template","summary":"Update Flow Template","description":"Replace a flow template. The whole template is replaced, not patched field-by-field.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated flow template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowTemplate"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateFlowTemplateRequest"}}}}}},"/v1/agents/flow/templates/{id}/clone":{"post":{"operationId":"clone-template","summary":"Clone Flow Template","description":"Clone a flow template onto an agent as a new draft graph.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The agent's new draft graph.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowGraph"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CloneFlowTemplateRequest"}}}}}},"/v1/agents/conversations/{id}/shadow-token":{"post":{"operationId":"shadow-token","summary":"Mint shadow-call token","description":"Mint a listen-only LiveKit access token so an authorized observer\ncan join an ongoing voice-agent conversation as a hidden\nparticipant. Caller must be an `owner` or `admin` of the\nworkspace the conversation belongs to. The token cannot publish\naudio or data; the observer is invisible to the caller and the\nagent. Speechify support engineers reach this endpoint the same\nway as any other observer \u2014 by being granted the owner/admin\nrole on the customer's workspace (typically under an NDA-backed\nsupport arrangement).\n","tags":["subpackage_tts.subpackage_tts/admin"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Shadow-call connection details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ShadowConversationResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"403":{"description":"The credential authenticated, but is not authorised for this\nresource - typically a workspace-role gate (owner / admin\nrequired) or a cross-tenant access attempt.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/end":{"post":{"operationId":"force-end","summary":"Force-end conversation","description":"Force-terminate the LiveKit room for an ongoing conversation.\nIdempotent: rooms that LiveKit has already cleaned up return\n204 the same as a successful first-time termination. Same\nowner/admin role gating as the shadow-token endpoint.\n","tags":["subpackage_tts.subpackage_tts/admin"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Conversation ended.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"403":{"description":"The credential authenticated, but is not authorised for this\nresource - typically a workspace-role gate (owner / admin\nrequired) or a cross-tenant access attempt.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/batch-calls":{"post":{"operationId":"create","summary":"Create Batch Call","description":"Dial a list of phone numbers through one of your voice agents in a\nsingle request. Each recipient can receive personalised dynamic\nvariables that your agent prompt references via `{{key}}` placeholders.\nBatches can run immediately or be scheduled up to 30 days in advance.\n\nAccepts `application/json` or `multipart/form-data` (with a CSV file).\nMax 1000 recipients per batch.\n","tags":["subpackage_tts.subpackage_tts/batchCalls"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Batch accepted for processing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateBatchCallResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateBatchCallRequest"}}}}},"get":{"operationId":"list","summary":"List Batch Calls","description":"Returns one page of batch calls for the workspace, newest first.\nPaginate by passing `cursor` from the previous response.\n","tags":["subpackage_tts.subpackage_tts/batchCalls"],"parameters":[{"name":"cursor","in":"query","description":"Opaque cursor from a prior response's `next_cursor`.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size. Defaults to 50; capped at 200.","required":false,"schema":{"type":"integer","default":50}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListBatchCallsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/batch-calls/{id}":{"get":{"operationId":"get","summary":"Get Batch Call","description":"Returns the batch row plus all recipients so the detail view renders\nwithout a second round-trip.\n","tags":["subpackage_tts.subpackage_tts/batchCalls"],"parameters":[{"name":"id","in":"path","description":"Batch call ID.","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetBatchCallResponse"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/batch-calls/{id}/cancel":{"post":{"operationId":"cancel","summary":"Cancel Batch Call","description":"Cancels a scheduled or pending batch before it starts dialing.\nReturns 409 if the batch is already running or completed.\n","tags":["subpackage_tts.subpackage_tts/batchCalls"],"parameters":[{"name":"id","in":"path","description":"Batch call ID.","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Batch cancelled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateBatchCallResponse"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/outbound-calls":{"post":{"operationId":"create","summary":"Create Outbound Call","description":"Place an outbound call from an agent to a phone number. LiveKit\noriginates the SIP INVITE through the outbound trunk bound to the\nagent's workspace; the agent worker is dispatched into the room\nautomatically.\n\nThe response is returned as soon as LiveKit accepts the INVITE.\nPoll `GET /v1/agents/conversations/{conversation_id}` for status\ntransitions: `pending` \u2192 `active` (answered) \u2192 `completed`.\n\nRequires a Twilio or BYOC trunk. LiveKit-native numbers are\ninbound-only.\n","tags":["subpackage_tts.subpackage_tts/outboundCalls"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The outbound call was accepted by LiveKit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateOutboundCallResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateOutboundCallRequest"}}}}}},"/v1/agents/phone-numbers":{"post":{"operationId":"import","summary":"Import Phone Number","description":"Import a phone number into the workspace. The `source` field\ndetermines the provisioning path:\n\n- `livekit` - LiveKit purchases the number on your behalf. US\n inbound only. Quickest path for local testing.\n- `twilio` - Provide your Twilio Account SID, Auth Token, and\n the E.164 number you already own. We provision an Elastic SIP\n Trunk on your Twilio account automatically.\n- `byoc` - Provide an existing SIP trunk ID. The number is\n registered against that trunk.\n\nReturns 402 when the workspace has reached the 100-number cap.\n","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The imported phone number.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PhoneNumber"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"402":{"description":"The workspace has insufficient credits, or the request needs a\nplan tier the workspace is not on (e.g. voice cloning). Distinct\nfrom `Forbidden` so SDK consumers can drive upgrade UX.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ImportPhoneNumberRequest"}}}}},"get":{"operationId":"list","summary":"List Phone Numbers","description":"List all phone numbers in the caller's workspace.","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The phone numbers for the workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListPhoneNumbersResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/phone-numbers/{id}":{"get":{"operationId":"get","summary":"Get Phone Number","description":"Retrieve a phone number by ID.","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested phone number.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PhoneNumber"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update","summary":"Update Phone Number","description":"Update a phone number. Only `label` and `agent_id` are mutable;\n`source` and `e164` are immutable after import. Pass `null` for\n`agent_id` to unbind the number from its current agent.\n","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated phone number.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PhoneNumber"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdatePhoneNumberRequest"}}}}},"delete":{"operationId":"delete","summary":"Delete Phone Number","description":"Delete a phone number from the workspace. For Twilio and LiveKit\nnumbers this also deprovisions the backing SIP trunk and dispatch\nrule on LiveKit Cloud.\n","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Phone number deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/phone-numbers/available":{"get":{"operationId":"search-available","summary":"Search Available Phone Numbers","description":"Search carrier inventory for phone numbers available to purchase.\nCurrently restricted to the US (`country=US`); pass `area_code`\nto narrow to a specific NPA. The returned numbers are not held;\na subsequent `POST /v1/agents/phone-numbers/purchase` against the same\nE.164 may fail with 4xx if the number has been taken in the\nmeantime.\n","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"country","in":"query","description":"ISO-3166 alpha-2 country code. Defaults to \"US\"; only \"US\" is supported in v1.","required":false,"schema":{"type":"string","default":"US"}},{"name":"area_code","in":"query","description":"Three-digit NPA to filter inventory to a region.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max results to return. Capped at 50.","required":false,"schema":{"type":"integer","default":20}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Available numbers (may be empty if no inventory matches).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:SearchAvailablePhoneNumbersResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"503":{"description":"A downstream dependency is degraded or the endpoint is\nintentionally disabled (e.g. phone-number purchase before\nops setup).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/phone-numbers/purchase":{"post":{"operationId":"purchase","summary":"Purchase Phone Number","description":"Purchase a phone number on Speechify's master Twilio account.\nThe number is billed to Speechify until released; each\nworkspace is capped at a small number of purchased numbers\n(see 422 response) independent of the overall 100-number cap.\n`e164` must come from a recent `SearchAvailablePhoneNumbers`\nresponse \u2014 carriers reject buys against numbers that are no\nlonger in inventory. The returned phone number is wired for\nboth inbound (when `agent_id` is set, or after a later\n`PATCH`) and outbound calls (via the workspace's shared\noutbound trunk).\n","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The purchased phone number.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PhoneNumber"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"422":{"description":"The request was well-formed but semantically rejected -\ntypically a referential integrity violation (e.g. flow node\nreferences an audio asset in another workspace) or a state\nmachine refusal.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"503":{"description":"A downstream dependency is degraded or the endpoint is\nintentionally disabled (e.g. phone-number purchase before\nops setup).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PurchasePhoneNumberRequest"}}}}}},"/v1/agents/sip-trunks":{"post":{"operationId":"create","summary":"Create SIP Trunk","description":"Create a SIP trunk. For `kind=byoc` supply `sip_address` plus\noptional digest credentials and IP allowlist. For `kind=twilio`\nuse `ImportPhoneNumber` with a `twilio` spec instead - trunk\ncreation is handled automatically. Returns 402 when the workspace\nhas reached the 20-trunk cap.\n","tags":["subpackage_tts.subpackage_tts/sipTrunks"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created SIP trunk.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:SIPTrunk"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"402":{"description":"The workspace has insufficient credits, or the request needs a\nplan tier the workspace is not on (e.g. voice cloning). Distinct\nfrom `Forbidden` so SDK consumers can drive upgrade UX.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateSIPTrunkRequest"}}}}},"get":{"operationId":"list","summary":"List SIP Trunks","description":"List all SIP trunks in the caller's workspace.","tags":["subpackage_tts.subpackage_tts/sipTrunks"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The SIP trunks for the workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListSIPTrunksResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/sip-trunks/{id}":{"get":{"operationId":"get","summary":"Get SIP Trunk","description":"Retrieve a SIP trunk by ID.","tags":["subpackage_tts.subpackage_tts/sipTrunks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested SIP trunk.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:SIPTrunk"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"delete","summary":"Delete SIP Trunk","description":"Delete a SIP trunk. This also removes the backing LiveKit inbound\ntrunk, outbound trunk, and dispatch rule if they were provisioned\nby us. Phone numbers attached to this trunk are left in place but\nbecome non-functional until rebound to a new trunk.\n","tags":["subpackage_tts.subpackage_tts/sipTrunks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"SIP trunk deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/ivr-menus":{"get":{"operationId":"list","summary":"List IVR Menus","description":"List the active IVR menus the caller's workspace has learned\n(AIS-3267 Phase 2/1.6/3). One row per (fingerprint, tenant).\nInvalidated rows and the cross-tenant shared slot are excluded.\nSorted by `last_observed_at` DESC so the freshest IVRs land at\nthe top. Capped at 200 rows.\n\nSee `docs/adrs/0009-ivr-memory-consume-and-invalidate.md` for the\nmemorization design.\n","tags":["subpackage_tts.subpackage_tts/ivrMemory"],"parameters":[{"name":"fingerprint","in":"query","description":"Optional SHA-256 fingerprint hash to narrow the list to one menu.","required":false,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of cached IVR menus.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListIVRMenusResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/ivr-menus/{id}":{"get":{"operationId":"get","summary":"Get IVR Menu","description":"Fetch one menu's full shape. Returns 404 for missing,\nsoft-deleted, or foreign-tenant menus \u2014 existence information\nis never leaked across tenants.\n","tags":["subpackage_tts.subpackage_tts/ivrMemory"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The IVR menu detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:IVRMenu"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-label","summary":"Update IVR Menu Option Label","description":"Re-label one option in the stored menu_tree, matched on the\nsupplied DTMF value. The label is what the console displays in\nthe detail panel and what the worker reads back at navigate\ntime to surface the option semantically. Unknown DTMF values\nare a no-op (the response echoes the unchanged menu).\n","tags":["subpackage_tts.subpackage_tts/ivrMemory"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The refreshed menu shape.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:IVRMenu"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateIVRMenuLabelRequest"}}}}}},"/v1/agents/ivr-menus/{id}/invalidate":{"post":{"operationId":"invalidate","summary":"Invalidate IVR Menu","description":"Soft-invalidate the named menu. Future lookups skip it; the\nnext discovery for the same fingerprint replaces it (clearing\nthe invalidation, see ADR 0009 \u00a74). Idempotent: re-invalidating\nan already-invalidated row returns 404.\n\nReason is optional and is captured in structured logs for\noperator triage. A future audit table may persist it.\n","tags":["subpackage_tts.subpackage_tts/ivrMemory"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Menu invalidated.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:InvalidateIVRMenuRequest"}}}}}}},"servers":[{"url":"https://api.speechify.ai","description":"https://api.speechify.ai"}],"components":{"schemas":{"tts:GetSpeechRequestAudioFormat":{"type":"string","enum":["wav","mp3","ogg","aac","pcm"],"default":"wav","description":"The format for the output audio. Note, that the current default is \"wav\", but there's no guarantee it will not change in the future. We recommend always passing the specific param you expect.","title":"GetSpeechRequestAudioFormat"},"tts:GetSpeechRequestModel":{"type":"string","enum":["simba-english","simba-multilingual","simba-3.0"],"default":"simba-english","description":"Model used for audio synthesis. `simba-english` is optimized for English, `simba-multilingual` for non-English or mixed input. `simba-3.0` is the streaming-native model with lower TTFB and richer expressivity. Currently English only; multilingual coming soon. Non-English voices return 400 until multilingual support ships.","title":"GetSpeechRequestModel"},"tts:GetSpeechOptionsRequest":{"type":"object","properties":{"loudness_normalization":{"type":"boolean","default":false,"description":"Determines whether to normalize the audio loudness to a standard level.\nWhen enabled, loudness normalization aligns the audio output to the following standards:\nIntegrated loudness: -14 LUFS\nTrue peak: -2 dBTP\nLoudness range: 7 LU\nIf disabled, the audio loudness will match the original loudness of the selected voice, which may vary significantly and be either too quiet or too loud.\nEnabling loudness normalization can increase latency due to additional processing required for audio level adjustments."},"text_normalization":{"type":"boolean","default":true,"description":"Determines whether to normalize the text. If enabled, it will transform numbers, dates, etc. into words. For example, \"55\" is normalized into \"fifty five\".\nThis can increase latency due to additional processing required for text normalization."}},"description":"GetSpeechOptionsRequest is the wrapper for request parameters to the client","title":"GetSpeechOptionsRequest"},"tts:GetSpeechRequest":{"type":"object","properties":{"audio_format":{"$ref":"#/components/schemas/tts:GetSpeechRequestAudioFormat","default":"wav","description":"The format for the output audio. Note, that the current default is \"wav\", but there's no guarantee it will not change in the future. We recommend always passing the specific param you expect."},"input":{"type":"string","description":"Plain text or SSML to be synthesized to speech.\nRefer to https://docs.speechify.ai/docs/api-limits for the input size limits.\nEmotion, Pitch and Speed Rate are configured in the ssml input, please refer to the ssml documentation for more information: https://docs.speechify.ai/docs/ssml#prosody"},"language":{"type":"string","description":"Language of the input. Follow the format of an ISO 639-1 language code and an ISO 3166-1 region code, separated by a hyphen, e.g. en-US.\nPlease refer to the list of the supported languages and recommendations regarding this parameter: https://docs.speechify.ai/docs/language-support."},"model":{"$ref":"#/components/schemas/tts:GetSpeechRequestModel","default":"simba-english","description":"Model used for audio synthesis. `simba-english` is optimized for English, `simba-multilingual` for non-English or mixed input. `simba-3.0` is the streaming-native model with lower TTFB and richer expressivity. Currently English only; multilingual coming soon. Non-English voices return 400 until multilingual support ships."},"options":{"$ref":"#/components/schemas/tts:GetSpeechOptionsRequest"},"voice_id":{"type":"string","description":"Id of the voice to be used for synthesizing speech. Refer to /v1/voices endpoint for available voices"}},"required":["input","voice_id"],"description":"Request body for POST /v1/audio/speech.","title":"GetSpeechRequest"},"tts:GetSpeechResponseAudioFormat":{"type":"string","enum":["wav","mp3","ogg","aac","pcm"],"description":"The format of the audio data","title":"GetSpeechResponseAudioFormat"},"tts:NestedChunk":{"type":"object","properties":{"end":{"type":"integer","format":"int64"},"end_time":{"type":"number","format":"double"},"start":{"type":"integer","format":"int64"},"start_time":{"type":"number","format":"double"},"type":{"type":"string"},"value":{"type":"string"}},"description":"It details the type of segment, its start and end points in the text, and its start and end times in the synthesized speech audio.","title":"NestedChunk"},"tts:SpeechMarks":{"type":"object","properties":{"chunks":{"type":"array","items":{"$ref":"#/components/schemas/tts:NestedChunk"},"description":"Array of NestedChunk, each providing detailed segment information within the synthesized speech."},"end":{"type":"integer","format":"int64"},"end_time":{"type":"number","format":"double"},"start":{"type":"integer","format":"int64"},"start_time":{"type":"number","format":"double"},"type":{"type":"string"},"value":{"type":"string"}},"required":["chunks","end","end_time","start","start_time","type"],"description":"It is used to annotate the audio data with metadata about the synthesis process, like word timing or phoneme details.","title":"SpeechMarks"},"tts:GetSpeechResponse":{"type":"object","properties":{"audio_data":{"type":"string","format":"byte","description":"Synthesized speech audio, Base64-encoded"},"audio_format":{"$ref":"#/components/schemas/tts:GetSpeechResponseAudioFormat","description":"The format of the audio data"},"billable_characters_count":{"type":"integer","format":"int64","description":"The number of billable characters processed in the request."},"speech_marks":{"$ref":"#/components/schemas/tts:SpeechMarks"}},"required":["audio_data","audio_format","billable_characters_count","speech_marks"],"title":"GetSpeechResponse"},"tts:ErrorCode":{"type":"string","enum":["bad_request","validation_failed","unauthorized","payment_required","forbidden","not_found","method_not_allowed","conflict","payload_too_large","unsupported_media_type","rate_limited","internal_error","upstream_failure","service_unavailable","caller_not_found","credential_not_found","payment_method_required"],"description":"Stable machine-readable error code. Additive only: codes are\nnever renamed, only deprecated. SDKs may map each code to a\ntyped exception class. Status-code semantics:\n4xx codes describe caller-fixable issues; 5xx codes describe\nserver-side failures and are safe to retry with backoff for\nidempotent requests.\n","title":"ErrorCode"},"tts:ErrorDetail":{"type":"object","properties":{"code":{"$ref":"#/components/schemas/tts:ErrorCode"},"message":{"type":"string","description":"Human-readable explanation of this specific occurrence.\nSafe to surface in UI banners or pass to support. The\nwording can change between releases; clients should\nmatch on `code`, not on the message string.\n"},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Per-field validation errors as `path -> message`. Only\npresent on 400 responses caused by request validation\n(typically code=`validation_failed`). Keys are field\npaths in dotted/bracket notation; values are short\nhuman explanations safe to inline-surface next to the\noffending form field.\n"}},"required":["code","message"],"title":"ErrorDetail"},"tts:Error":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/tts:ErrorDetail"},"request_id":{"type":"string","description":"Server-side request identifier. Echoes the\n`X-Request-ID` response header. Stable across the\nrequest's lifetime, written to structured logs, and\nuseful when reporting issues.\n"}},"required":["error"],"description":"Standard error envelope returned on every non-2xx response.\nContent-Type is `application/json`. The shape mirrors OpenAI /\nAnthropic / Stripe style: a machine-readable `error.code` for\nSDK consumers to switch on, a human `error.message` for UI,\nand an optional `error.fields` map for per-field validation\nerrors. `request_id` matches the `X-Request-ID` response\nheader and is what customers quote when filing support\ntickets.\n","title":"Error"},"tts:V1AudioStreamPostParametersAccept":{"type":"string","enum":["audio/mpeg","audio/ogg","audio/aac","audio/pcm"],"title":"V1AudioStreamPostParametersAccept"},"tts:GetStreamRequestModel":{"type":"string","enum":["simba-english","simba-multilingual","simba-3.0"],"default":"simba-english","description":"Model used for audio synthesis. `simba-english` is optimized for English, `simba-multilingual` for non-English or mixed input. `simba-3.0` is the streaming-native model with lower TTFB and richer expressivity. Currently English only; multilingual coming soon. Non-English voices return 400 until multilingual support ships.","title":"GetStreamRequestModel"},"tts:GetStreamOptionsRequest":{"type":"object","properties":{"loudness_normalization":{"type":"boolean","default":false,"description":"Determines whether to normalize the audio loudness to a standard level.\nWhen enabled, loudness normalization aligns the audio output to the following standards:\nIntegrated loudness: -14 LUFS\nTrue peak: -2 dBTP\nLoudness range: 7 LU\nIf disabled, the audio loudness will match the original loudness of the selected voice, which may vary significantly and be either too quiet or too loud.\nEnabling loudness normalization can increase latency due to additional processing required for audio level adjustments."},"text_normalization":{"type":"boolean","default":false,"description":"Determines whether to normalize the text. If enabled, it will transform numbers, dates, etc. into words. For example, \"55\" is normalized into \"fifty five\".\nThis can increase latency due to additional processing required for text normalization."}},"description":"GetStreamOptionsRequest is the wrapper for request parameters to the client","title":"GetStreamOptionsRequest"},"tts:GetStreamRequest":{"type":"object","properties":{"input":{"type":"string","description":"Plain text or SSML to be synthesized to speech.\nRefer to https://docs.speechify.ai/docs/api-limits for the input size limits.\nEmotion, Pitch and Speed Rate are configured in the ssml input, please refer to the ssml documentation for more information: https://docs.speechify.ai/docs/ssml#prosody"},"language":{"type":"string","description":"Language of the input. Follow the format of an ISO 639-1 language code and an ISO 3166-1 region code, separated by a hyphen, e.g. en-US.\nPlease refer to the list of the supported languages and recommendations regarding this parameter: https://docs.speechify.ai/docs/language-support."},"model":{"$ref":"#/components/schemas/tts:GetStreamRequestModel","default":"simba-english","description":"Model used for audio synthesis. `simba-english` is optimized for English, `simba-multilingual` for non-English or mixed input. `simba-3.0` is the streaming-native model with lower TTFB and richer expressivity. Currently English only; multilingual coming soon. Non-English voices return 400 until multilingual support ships."},"options":{"$ref":"#/components/schemas/tts:GetStreamOptionsRequest"},"voice_id":{"type":"string","description":"Id of the voice to be used for synthesizing speech. Refer to /v1/voices endpoint for available voices"}},"required":["input","voice_id"],"description":"GetStreamRequest is the wrapper for request parameters to the client","title":"GetStreamRequest"},"tts:GetVoiceGender":{"type":"string","enum":["male","female","notSpecified"],"title":"GetVoiceGender"},"tts:GetVoiceLanguage":{"type":"object","properties":{"locale":{"type":"string"},"preview_audio":{"type":["string","null"]}},"required":["locale"],"title":"GetVoiceLanguage"},"tts:GetVoicesModelName":{"type":"string","enum":["simba-english","simba-multilingual","simba-3.0"],"title":"GetVoicesModelName"},"tts:GetVoicesModel":{"type":"object","properties":{"languages":{"type":"array","items":{"$ref":"#/components/schemas/tts:GetVoiceLanguage"}},"name":{"$ref":"#/components/schemas/tts:GetVoicesModelName"}},"required":["languages","name"],"title":"GetVoicesModel"},"tts:GetVoiceType":{"type":"string","enum":["shared","personal"],"title":"GetVoiceType"},"tts:GetVoice":{"type":"object","properties":{"avatar_image":{"type":["string","null"]},"display_name":{"type":"string"},"gender":{"$ref":"#/components/schemas/tts:GetVoiceGender"},"locale":{"type":"string"},"id":{"type":"string"},"models":{"type":"array","items":{"$ref":"#/components/schemas/tts:GetVoicesModel"}},"preview_audio":{"type":["string","null"]},"tags":{"type":["array","null"],"items":{"type":"string"}},"type":{"$ref":"#/components/schemas/tts:GetVoiceType"}},"required":["display_name","gender","locale","id","models","type"],"title":"GetVoice"},"tts:V1VoicesPostRequestBodyContentMultipartFormDataSchemaGender":{"type":"string","enum":["male","female","notSpecified"],"description":"Gender marker for the personal voice\nmale GenderMale\nfemale GenderFemale\nnotSpecified GenderNotSpecified","title":"V1VoicesPostRequestBodyContentMultipartFormDataSchemaGender"},"tts:CreatedVoiceGender":{"type":"string","enum":["male","female","notSpecified"],"title":"CreatedVoiceGender"},"tts:CreateVoiceLanguage":{"type":"object","properties":{"locale":{"type":"string"},"preview_audio":{"type":["string","null"]}},"title":"CreateVoiceLanguage"},"tts:CreateVoiceModelName":{"type":"string","enum":["simba-english","simba-multilingual","simba-3.0"],"title":"CreateVoiceModelName"},"tts:CreateVoiceModel":{"type":"object","properties":{"languages":{"type":"array","items":{"$ref":"#/components/schemas/tts:CreateVoiceLanguage"}},"name":{"$ref":"#/components/schemas/tts:CreateVoiceModelName"}},"title":"CreateVoiceModel"},"tts:CreatedVoiceType":{"type":"string","enum":["shared","personal"],"title":"CreatedVoiceType"},"tts:CreatedVoice":{"type":"object","properties":{"avatar_image":{"type":"string"},"display_name":{"type":"string"},"gender":{"$ref":"#/components/schemas/tts:CreatedVoiceGender"},"locale":{"type":"string"},"id":{"type":"string"},"models":{"type":"array","items":{"$ref":"#/components/schemas/tts:CreateVoiceModel"}},"type":{"$ref":"#/components/schemas/tts:CreatedVoiceType"}},"required":["display_name","gender","locale","id","models","type"],"title":"CreatedVoice"},"tts:CreateAgentRequestLlmProvider":{"type":"string","enum":["openai","speechify","custom",""],"description":"LLM backend. Leave empty (or omit both `llm_provider` and\n`llm_model`) to use the platform default (today: Speechify\nKimi K2.6, resolved server-side at dispatch). When set,\nmust be paired with a non-empty `llm_model`; mixing a\npopulated provider with an empty model is rejected as a\n400. `custom` additionally requires `llm_base_url`.\n","title":"CreateAgentRequestLlmProvider"},"tts:WidgetConfigStyle":{"type":"string","enum":["pill","fab"],"title":"WidgetConfigStyle"},"tts:WidgetConfigTheme":{"type":"string","enum":["dark","light","auto"],"title":"WidgetConfigTheme"},"tts:WidgetConfigAvatarType":{"type":"string","enum":["orb","image"],"title":"WidgetConfigAvatarType"},"tts:WidgetConfigAvatar":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/tts:WidgetConfigAvatarType"},"image_url":{"type":"string"},"orb_color_1":{"type":"string"},"orb_color_2":{"type":"string"}},"title":"WidgetConfigAvatar"},"tts:WidgetConfigText":{"type":"object","properties":{"start_call":{"type":"string"},"end_call":{"type":"string"},"listening":{"type":"string"},"thinking":{"type":"string"},"speaking":{"type":"string"}},"title":"WidgetConfigText"},"tts:WidgetConfigTerms":{"type":"object","properties":{"enabled":{"type":"boolean"},"content":{"type":"string"}},"title":"WidgetConfigTerms"},"tts:WidgetConfigTranscript":{"type":"object","properties":{"enabled":{"type":"boolean"}},"title":"WidgetConfigTranscript"},"tts:WidgetConfig":{"type":"object","properties":{"version":{"type":"integer"},"style":{"$ref":"#/components/schemas/tts:WidgetConfigStyle"},"theme":{"$ref":"#/components/schemas/tts:WidgetConfigTheme"},"avatar":{"$ref":"#/components/schemas/tts:WidgetConfigAvatar"},"text":{"$ref":"#/components/schemas/tts:WidgetConfigText"},"terms":{"$ref":"#/components/schemas/tts:WidgetConfigTerms"},"transcript":{"$ref":"#/components/schemas/tts:WidgetConfigTranscript"}},"description":"Customer-editable appearance + behaviour payload for the\nembedded `` pill: button text, avatar style,\norb colours, terms-and-conditions markdown, transcript display.\nEvery field is optional - empty fields fall back to the\nwidget's compile-time defaults.\n","title":"WidgetConfig"},"tts:AmdConfigOnVoicemailAction":{"type":"string","enum":["hangup","leave_message"],"title":"AmdConfigOnVoicemailAction"},"tts:AmdConfigOnVoicemail":{"type":"object","properties":{"action":{"$ref":"#/components/schemas/tts:AmdConfigOnVoicemailAction"},"message":{"type":"string","description":"Spoken before terminating when action=leave_message.\nSupports {{variable}} substitution. Required (non-empty)\nwhen action=leave_message; rejected by the validator\notherwise.\n"}},"required":["action"],"description":"Action when AMD returns category=machine-vm.","title":"AmdConfigOnVoicemail"},"tts:AmdConfigOnIvrAction":{"type":"string","enum":["proceed","hangup","navigate"],"description":"proceed: hand control to the agent's flow as if the\ncalled party were human. hangup: terminate immediately.\nnavigate: hand control to the IVR Navigator subagent\nwith menu-memoization-aware session config (cache hit\nseeds the agent context; cache miss triggers cold\ndiscovery and the post-call pipeline extracts the\nmenu for future calls).\n","title":"AmdConfigOnIvrAction"},"tts:AmdConfigOnIvr":{"type":"object","properties":{"action":{"$ref":"#/components/schemas/tts:AmdConfigOnIvrAction","description":"proceed: hand control to the agent's flow as if the\ncalled party were human. hangup: terminate immediately.\nnavigate: hand control to the IVR Navigator subagent\nwith menu-memoization-aware session config (cache hit\nseeds the agent context; cache miss triggers cold\ndiscovery and the post-call pipeline extracts the\nmenu for future calls).\n"}},"required":["action"],"description":"Action when AMD returns category=machine-ivr.","title":"AmdConfigOnIvr"},"tts:AmdConfigOnUnavailableAction":{"type":"string","enum":["hangup"],"title":"AmdConfigOnUnavailableAction"},"tts:AmdConfigOnUnavailable":{"type":"object","properties":{"action":{"$ref":"#/components/schemas/tts:AmdConfigOnUnavailableAction"}},"required":["action"],"description":"Action when AMD returns category=machine-unavailable (mailbox full or disconnected).","title":"AmdConfigOnUnavailable"},"tts:AmdConfigTuning":{"type":"object","properties":{"human_speech_threshold_seconds":{"type":"number","format":"double"},"no_speech_threshold_seconds":{"type":"number","format":"double"},"timeout_seconds":{"type":"number","format":"double"},"classification_prompt":{"type":"string"}},"description":"Optional overrides for LiveKit's detection thresholds and\ntimeouts. Cross-field rule (enforced at the application\nvalidator): `timeout_seconds` must be greater than or equal\nto `no_speech_threshold_seconds` when both are set.\n","title":"AmdConfigTuning"},"tts:AMDConfig":{"type":"object","properties":{"enabled":{"type":"boolean","description":"When false, the worker skips AMD entirely. When true, the\nworker runs AMD on the called party's greeting before\ndelivering the agent's first message and dispatches per\nresult.category. The per-route fields below are still\nrequired by the schema regardless of `enabled` state so a\ncustomer flipping `enabled: false \u2192 true` ships coherent\nroute configuration immediately.\n"},"on_voicemail":{"$ref":"#/components/schemas/tts:AmdConfigOnVoicemail","description":"Action when AMD returns category=machine-vm."},"on_ivr":{"$ref":"#/components/schemas/tts:AmdConfigOnIvr","description":"Action when AMD returns category=machine-ivr."},"on_unavailable":{"$ref":"#/components/schemas/tts:AmdConfigOnUnavailable","description":"Action when AMD returns category=machine-unavailable (mailbox full or disconnected)."},"tuning":{"$ref":"#/components/schemas/tts:AmdConfigTuning","description":"Optional overrides for LiveKit's detection thresholds and\ntimeouts. Cross-field rule (enforced at the application\nvalidator): `timeout_seconds` must be greater than or equal\nto `no_speech_threshold_seconds` when both are set.\n"}},"required":["enabled","on_voicemail","on_ivr","on_unavailable"],"description":"Answering Machine Detection routing config for outbound voice\nagents. AMD classifies the called party's first ~3-15 seconds of\naudio into one of LiveKit's categories (human, uncertain,\nmachine-vm, machine-ivr, machine-unavailable) and dispatches per\ncategory to the configured action. Stored on the agent row;\nflowed onto outbound dispatch metadata under the `amd` key.\nRationale: see ADR 0008 (docs/adrs/0008-amd-as-session-routing-primitive.md).\n","title":"AMDConfig"},"tts:CreateAgentRequestSttOverride":{"type":"string","enum":["flux","whisper-v3","gpt-realtime-whisper"],"description":"Optional non-default streaming-STT stack for this agent.\nOmit to use the worker's default stack (today: whisper-v3).\nSee the Agent schema for the full option semantics.\n","title":"CreateAgentRequestSttOverride"},"tts:CreateAgentRequest":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string","description":"Optional. Server derives slug from name with a random suffix when omitted; if you supply your own, a collision returns 400 'slug already taken'."},"prompt":{"type":"string"},"first_message":{"type":"string","description":"Greeting spoken verbatim at session start when included in the agent's flow graph."},"language":{"type":"string","description":"ISO 639-1 code. Defaults to 'en' when omitted."},"llm_provider":{"$ref":"#/components/schemas/tts:CreateAgentRequestLlmProvider","description":"LLM backend. Leave empty (or omit both `llm_provider` and\n`llm_model`) to use the platform default (today: Speechify\nKimi K2.6, resolved server-side at dispatch). When set,\nmust be paired with a non-empty `llm_model`; mixing a\npopulated provider with an empty model is rejected as a\n400. `custom` additionally requires `llm_base_url`.\n"},"llm_model":{"type":"string","description":"Chat model slug. Leave empty to use the platform default.\nFor `openai` / `speechify` the (provider, model) pair must\nbe in the allowed table; for `custom` it is free-form.\n"},"llm_base_url":{"type":"string","description":"Custom OpenAI/vLLM-compatible endpoint base URL. Required\nwhen `llm_provider` is `custom`, rejected otherwise.\n"},"llm_api_key":{"type":"string","description":"Bearer key for the custom endpoint. Write-only - stored\nencrypted, never returned (GET exposes `llm_api_key_set`).\nOptional even for `custom` (keyless endpoints); rejected\nfor any other provider.\n"},"llm_extra_body":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Optional JSON object forwarded verbatim to the custom\nendpoint as the chat.completions `extra_body` (reasoning /\nsampling knobs). Valid only when `llm_provider` is\n`custom`.\n"},"voice_id":{"type":"string","description":"Voice slug from the VMS catalog (see GET /v1/voices). Required \u2014 the server rejects writes with an unknown or empty slug."},"temperature":{"type":"number","format":"double","description":"0.0..1.0. Defaults to 0.7 when omitted."},"widget_config":{"$ref":"#/components/schemas/tts:WidgetConfig"},"is_public":{"type":"boolean","description":"Defaults to false when omitted."},"allowed_origins":{"type":"array","items":{"type":"string"}},"hostname_allowlist":{"type":"array","items":{"type":"string"},"description":"Optional per-agent hostname allowlist (see Agent schema)."},"memory_enabled":{"type":"boolean","description":"Defaults to false when omitted."},"memory_retention_days":{"type":"integer","description":"Defaults to 90 when omitted."},"webhook_url":{"type":"string","description":"Customer-facing post-call webhook URL."},"webhook_secret":{"type":"string","description":"HMAC-SHA256 secret seed. Write-only \u2014 never echoed back on\nreads; clients see `webhook_secret_set: true` instead.\n"},"amd":{"$ref":"#/components/schemas/tts:AMDConfig","description":"AMD routing config. Optional on create; omitted means AMD off. See AMDConfig schema."},"save_audio_recording":{"type":"boolean","description":"When set, opts the agent into per-conversation audio recording. Defaults to false when omitted."},"navigator_mode":{"type":"boolean","description":"When set, opts the agent into IVR-tuned turn handling. Defaults to false when omitted."},"ivr_memory_enabled":{"type":"boolean","description":"When omitted, defaults to true. Set to false to opt-out of the IVR-memory cache lookup for this agent."},"tts_speaking_rate":{"type":["number","null"],"format":"double"},"tts_playback_rate":{"type":["number","null"],"format":"double","description":"Post-process pitch-preserving time-stretch on the synthesized\naudio. See the field on Agent for semantics.\n"},"response_delay_seconds":{"type":["number","null"],"format":"double","description":"Per-agent override for the worker's endpointing min_delay on\nthe VAD path (seconds). See the field on Agent for semantics.\nRange 0.0..5.0; null means use the stack default.\n"},"inactivity_timeout_seconds":{"type":"integer","description":"Per-agent silence-tolerance override in seconds. Send `0`\nto clear the override and fall back to the platform\ndefault. Negative values are rejected.\n"},"background_noise_preset":{"type":"string","description":"Pre-mixed ambient bed slug. Send empty string (\"\") to\ndisable the bed, which also clears `background_noise_volume`.\n"},"background_noise_volume":{"type":"number","format":"double","description":"Volume of the background-noise bed (0..1). Ignored when\n`background_noise_preset` is empty.\n"},"stt_override":{"$ref":"#/components/schemas/tts:CreateAgentRequestSttOverride","description":"Optional non-default streaming-STT stack for this agent.\nOmit to use the worker's default stack (today: whisper-v3).\nSee the Agent schema for the full option semantics.\n"}},"required":["name","voice_id"],"title":"CreateAgentRequest"},"tts:AgentLlmProvider":{"type":"string","enum":["openai","speechify","custom"],"description":"LLM backend the worker constructs for this agent. Null\nmeans \"use the platform default\" (resolved server-side at\ndispatch; today: Speechify Kimi K2.6). `openai` and\n`speechify` pair with a model from the allowed (provider,\nmodel) table. `custom` points the worker at any OpenAI /\nvLLM-compatible endpoint - see `llm_base_url`,\n`llm_api_key`, `llm_extra_body`.\n","title":"AgentLlmProvider"},"tts:AgentSttOverride":{"type":"string","enum":["flux","whisper-v3","gpt-realtime-whisper"],"description":"Optional override for the streaming-STT stack this agent\ndispatches with. Null means use the worker's default\nstack (today: whisper-v3, Baseten Whisper Large V3). Pick\n`whisper-v3` to pin Whisper Large V3 explicitly, `flux` to\nopt into Deepgram Flux's semantic end-of-turn detection, or\n`gpt-realtime-whisper` for OpenAI's streaming Whisper-class\nSTT.\n","title":"AgentSttOverride"},"tts:Agent":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`).\nADR 0015 Cluster 1 hard-break: this is the sole customer-facing\nidentifier. URL paths accept only this prefixed form; legacy\nUUID path parameters are rejected with 404 as of Cluster 1.\n"},"name":{"type":"string"},"slug":{"type":"string"},"prompt":{"type":"string"},"first_message":{"type":"string","description":"Spoken verbatim at session start when present in the customer's flow graph."},"language":{"type":"string","description":"ISO 639-1 code, e.g. 'en'."},"llm_provider":{"$ref":"#/components/schemas/tts:AgentLlmProvider","description":"LLM backend the worker constructs for this agent. Null\nmeans \"use the platform default\" (resolved server-side at\ndispatch; today: Speechify Kimi K2.6). `openai` and\n`speechify` pair with a model from the allowed (provider,\nmodel) table. `custom` points the worker at any OpenAI /\nvLLM-compatible endpoint - see `llm_base_url`,\n`llm_api_key`, `llm_extra_body`.\n"},"llm_model":{"type":["string","null"],"description":"Chat model slug. Null means \"use the platform default\"\n(resolved server-side at dispatch; today: Speechify Kimi\nK2.6). For `openai` / `speechify` it must be a slug from\nthe allowed table; for `custom` it is free-form (the\ncustomer's endpoint owns the namespace).\n"},"llm_base_url":{"type":["string","null"],"description":"Custom OpenAI/vLLM-compatible endpoint base URL. Non-null\nonly when `llm_provider` is `custom`.\n"},"llm_api_key_set":{"type":"boolean","description":"Whether a bearer key is stored for the custom endpoint.\nThe key itself is write-only and never returned.\n"},"llm_extra_body":{"type":["object","null"],"additionalProperties":{"description":"Any type"},"description":"JSON object forwarded verbatim to the custom endpoint as\nthe chat.completions `extra_body` (reasoning / sampling\nknobs). Non-null only when `llm_provider` is `custom`.\n"},"voice_id":{"type":"string","description":"Speechify voice slug."},"temperature":{"type":"number","format":"double"},"widget_config":{"$ref":"#/components/schemas/tts:WidgetConfig"},"is_public":{"type":"boolean","description":"When true, the `` web component can start a\nsession against this agent without an API key, subject to\nthe `allowed_origins` allowlist. When false (default), only\nauthenticated callers can start sessions.\n"},"allowed_origins":{"type":"array","items":{"type":"string"},"description":"Exact `Origin` header values (e.g. `https://example.com`)\nthat are allowed to start public sessions. Empty array\nwith `is_public = true` means any origin is accepted \u2014\nintended for open demos. No subdomain wildcards.\n"},"hostname_allowlist":{"type":["array","null"],"items":{"type":"string"},"description":"Optional per-agent hostname allowlist enforced at\nsession-creation time. When set and non-empty, the\n`Origin` header's hostname must be an exact member.\nBare hostnames only \u2014 no scheme, port, or path. Up to\n10 entries. Omit (null) or leave empty for no\nenforcement (public agents accept any hostname).\n"},"memory_enabled":{"type":"boolean","description":"When true, the post-call extractor writes durable facts about\neach caller; at conversation-start the retriever injects the\ntop matches into the system prompt via the `{{memory}}`\ntemplate variable. Defaults to false.\n"},"memory_retention_days":{"type":"integer","description":"Maximum age (in days) of memories kept and surfaced to the\nretriever. 0 disables the cap. Defaults to 90.\n"},"webhook_url":{"type":"string","description":"Customer-facing post-call webhook target. When non-empty,\nthe control plane POSTs a signed payload (transcript +\nevals + extractors + recording URL) once the conversation\ncompletes. Empty disables the fire path.\n"},"webhook_secret_set":{"type":"boolean","description":"True when an HMAC-SHA256 webhook secret is configured. The\nsecret itself is write-only \u2014 supplied on PATCH and never\nechoed back on reads.\n"},"amd":{"$ref":"#/components/schemas/tts:AMDConfig"},"save_audio_recording":{"type":"boolean","description":"When true, every conversation produces a room-composite\nOGG egress uploaded to the recordings bucket. Defaults\nFALSE for new agents (privacy by default).\n"},"navigator_mode":{"type":"boolean","description":"Tunes worker turn handling for autonomous outbound IVR\nnavigation - longer endpointing and no barge-in. The goal\nitself lives in the agent's prompt; this flag is the\nbehaviour switch only. Defaults FALSE.\n"},"ivr_memory_enabled":{"type":"boolean","description":"Per-agent kill switch for the IVR-memory cache lookup\nperformed at AMD time. Defaults TRUE so existing navigator\nagents keep their always-on behaviour. Set to false to skip\nthe cache and force every outbound dial on this agent to\nstart cold (LLM-driven navigation only).\n"},"tts_speaking_rate":{"type":["number","null"],"format":"double","description":"Per-agent override for the voice's default speaking rate\n(0.5 = half speed, 2.0 = double, 1.0 = neutral). Null\nmeans \"use the voice's default rate\".\n"},"tts_playback_rate":{"type":["number","null"],"format":"double","description":"Per-agent post-process pitch-preserving time-stretch applied\nto the synthesized audio in the worker before publishing.\nDistinct from tts_speaking_rate: speaking_rate biases the\nmodel's generation prosody (clipped syllables, pauses\npreserved); playback_rate uniformly stretches the rendered\nwaveform (every sample, every pause, every breath). Range\n0.5..3.0; null means no post-process.\n"},"response_delay_seconds":{"type":["number","null"],"format":"double","description":"How long the agent waits after the caller stops talking\nbefore generating a reply (the worker's endpointing\nmin_delay on the VAD path). Range 0.0..5.0. Null means\n\"use the stack default\" \u2014 Deepgram VAD: 0.5s, or 0.75s\nwhen `navigator_mode=true`. Ignored on Flux + Whisper\nSTT, which use semantic turn detection instead.\n"},"inactivity_timeout_seconds":{"type":["integer","null"],"description":"Optional override for the per-agent silence-tolerance\nbefore the worker tears the call down. Null means use\nthe platform default.\n"},"background_noise_preset":{"type":["string","null"],"description":"Optional pre-mixed ambient bed (e.g. office, cafe). Null\ndisables background noise.\n"},"background_noise_volume":{"type":["number","null"],"format":"double","description":"Volume of the background-noise bed. Null disables."},"stt_override":{"$ref":"#/components/schemas/tts:AgentSttOverride","description":"Optional override for the streaming-STT stack this agent\ndispatches with. Null means use the worker's default\nstack (today: whisper-v3, Baseten Whisper Large V3). Pick\n`whisper-v3` to pin Whisper Large V3 explicitly, `flux` to\nopt into Deepgram Flux's semantic end-of-turn detection, or\n`gpt-realtime-whisper` for OpenAI's streaming Whisper-class\nSTT.\n"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","slug","prompt","first_message","language","llm_provider","llm_model","voice_id","temperature","is_public","allowed_origins","memory_enabled","memory_retention_days","amd","save_audio_recording","navigator_mode","ivr_memory_enabled","created_at","updated_at"],"title":"Agent"},"tts:ListAgentsResponse":{"type":"object","properties":{"agents":{"type":"array","items":{"$ref":"#/components/schemas/tts:Agent"}}},"required":["agents"],"title":"ListAgentsResponse"},"tts:UpdateAgentRequestLlmProvider":{"type":"string","enum":["openai","speechify","custom",""],"description":"LLM backend. Send an empty string together with\n`llm_model: \"\"` to clear the pair to the platform default\n(today: Speechify Kimi K2.6). Sending one populated and\none empty is rejected as a 400. Omit both to leave the\nstored pair unchanged. Switching to a non-`custom` provider\nclears any stored `llm_base_url` / `llm_api_key` /\n`llm_extra_body`.\n","title":"UpdateAgentRequestLlmProvider"},"tts:UpdateAgentRequestSttOverride":{"type":"string","enum":["flux","whisper-v3","gpt-realtime-whisper",""],"description":"Streaming-STT stack override. Send an empty string (\"\") to\nclear the override and fall back to the worker default\n(today: whisper-v3). Any non-empty value must be a known\nstack name.\n","title":"UpdateAgentRequestSttOverride"},"tts:UpdateAgentRequest":{"type":"object","properties":{"name":{"type":"string"},"prompt":{"type":"string"},"first_message":{"type":"string"},"language":{"type":"string"},"llm_provider":{"$ref":"#/components/schemas/tts:UpdateAgentRequestLlmProvider","description":"LLM backend. Send an empty string together with\n`llm_model: \"\"` to clear the pair to the platform default\n(today: Speechify Kimi K2.6). Sending one populated and\none empty is rejected as a 400. Omit both to leave the\nstored pair unchanged. Switching to a non-`custom` provider\nclears any stored `llm_base_url` / `llm_api_key` /\n`llm_extra_body`.\n"},"llm_model":{"type":"string","description":"Chat model slug. Empty string + empty `llm_provider`\nclears the pair to the platform default. For `openai` /\n`speechify` the (provider, model) pair must be in the\nallowed table; for `custom` it is free-form.\n"},"llm_base_url":{"type":"string","description":"Custom-endpoint base URL. Required when the resulting\nprovider is `custom`, rejected otherwise.\n"},"llm_api_key":{"type":"string","description":"Bearer key for the custom endpoint. Write-only. Omit to\nkeep the stored key, send \"\" to clear it, send a value to\nreplace it. Rejected for non-`custom` providers.\n"},"llm_extra_body":{"type":"object","additionalProperties":{"description":"Any type"},"description":"JSON object forwarded to the custom endpoint as\nchat.completions `extra_body`. Omit to leave unchanged;\na JSON object (including `{}`) replaces it. Valid only\nwhen the resulting provider is `custom`.\n"},"voice_id":{"type":"string"},"temperature":{"type":"number","format":"double"},"widget_config":{"$ref":"#/components/schemas/tts:WidgetConfig"},"is_public":{"type":"boolean"},"allowed_origins":{"type":"array","items":{"type":"string"}},"hostname_allowlist":{"type":"array","items":{"type":"string"},"description":"When supplied, replaces the stored list. Pass an empty\narray to clear enforcement (public agent is open again).\nOmit the field to leave the existing value unchanged.\n"},"memory_enabled":{"type":"boolean"},"memory_retention_days":{"type":"integer"},"webhook_url":{"type":"string"},"webhook_secret":{"type":"string","description":"Rotate the HMAC secret. Write-only."},"amd":{"$ref":"#/components/schemas/tts:AMDConfig","description":"AMD routing config (PATCH-replace, wholesale). Omit to leave the stored config unchanged."},"save_audio_recording":{"type":"boolean"},"navigator_mode":{"type":"boolean"},"ivr_memory_enabled":{"type":"boolean","description":"Per-agent kill switch for the IVR-memory cache lookup. nil/omit = unchanged."},"tts_speaking_rate":{"type":["number","null"],"format":"double"},"clear_tts_speaking_rate":{"type":"boolean","description":"Two-headed clear: PATCH cannot distinguish \"absent\" from\n\"explicit null\" reliably across stacks. Setting this to\n`true` resets `tts_speaking_rate` to the voice default.\nIf both are sent, `clear_tts_speaking_rate` wins.\n"},"tts_playback_rate":{"type":["number","null"],"format":"double"},"clear_tts_playback_rate":{"type":"boolean","description":"Two-headed clear, mirroring `clear_tts_speaking_rate`.\nSetting this to `true` resets `tts_playback_rate` to null\n(no post-process). If both fields are sent,\n`clear_tts_playback_rate` wins.\n"},"response_delay_seconds":{"type":["number","null"],"format":"double","description":"Per-agent silence-wait override (seconds). See the field\non Agent for semantics. Range 0.0..5.0; null is allowed\nbut `clear_response_delay_seconds=true` is the canonical\nway to revert to the stack default.\n"},"clear_response_delay_seconds":{"type":"boolean","description":"Two-headed clear, mirroring `clear_tts_playback_rate`.\nSetting this to `true` resets `response_delay_seconds` to\nnull (revert to the stack default). If both are sent,\n`clear_response_delay_seconds` wins.\n"},"inactivity_timeout_seconds":{"type":"integer","description":"Per-agent silence-tolerance override. Send `0` to clear\nthe override and fall back to the platform default.\nNegative values are rejected.\n"},"background_noise_preset":{"type":"string","description":"Pre-mixed ambient bed slug. Send empty string (\"\") to\ndisable the bed, which also clears `background_noise_volume`.\n"},"background_noise_volume":{"type":"number","format":"double","description":"Volume of the background-noise bed (0..1). Ignored when\nthe preset is empty; clearing the preset also clears\nthis field server-side.\n"},"stt_override":{"$ref":"#/components/schemas/tts:UpdateAgentRequestSttOverride","description":"Streaming-STT stack override. Send an empty string (\"\") to\nclear the override and fall back to the worker default\n(today: whisper-v3). Any non-empty value must be a known\nstack name.\n"}},"description":"Body for PATCH /v1/agents/{id}. Every field is optional;\nomitting a field leaves it unchanged. `slug` is intentionally\nnot patchable (changing it would break embed URLs).\n","title":"UpdateAgentRequest"},"tts:CreateConversationRequest":{"type":"object","properties":{"transport":{"type":["string","null"],"description":"Transport hint. Omit to use the agent's default."},"dynamic_variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-session variable overrides that merge on top of the agent's\nstored variable defaults for this one conversation. Keys in the\nreserved `system__` namespace are rejected. Values must match the\ndeclared type of the corresponding variable definition on the agent.\n"}},"description":"Optional body for `POST /v1/agents/{id}/conversations`.","title":"CreateConversationRequest"},"tts:ConversationStatus":{"type":"string","enum":["pending","active","completed","failed"],"title":"ConversationStatus"},"tts:ConversationTransport":{"type":"string","enum":["web","phone","whatsapp","sip_inbound","sip_outbound"],"description":"How the caller reached the agent. `web` is the browser /\nSDK realtime path; the `sip_*` and `phone` variants come\nfrom the telephony stack.\n","title":"ConversationTransport"},"tts:ConversationEndReason":{"type":"string","enum":["voicemail_message_left","voicemail_hangup","ivr_hangup","unavailable_hangup","agent_ended","caller_hangup","inactivity_timeout","loop_detected","max_duration_reached"],"description":"Coarse termination category. Worker-stamped reasons arrive\nbefore `terminate_call` fires; `caller_hangup` has two\nemit sites (worker-observed SIP disconnect, plus a\nserver-side post-call catch-all).\n* `voicemail_message_left` \u2014 AMD machine-vm + we spoke the configured drop-message.\n* `voicemail_hangup` \u2014 AMD machine-vm + we terminated silently (action=hangup or empty-message bypass).\n* `ivr_hangup` \u2014 AMD machine-ivr + action=hangup.\n* `unavailable_hangup` \u2014 AMD machine-unavailable (mailbox full / disconnected).\n* `agent_ended` \u2014 LLM-driven end_call builtin.\n* `inactivity_timeout` \u2014 worker's inactivity handler fired terminate after the configured silence window.\n* `loop_detected` \u2014 worker's runtime loop guard force-ended the call after N consecutive near-identical user turns (typically an IVR replaying its menu while the LLM kept reacting instead of calling end_call).\n* `max_duration_reached` - worker's max-call-duration watchdog force-ended the call at the platform ceiling (a safety bound on runaway calls).\n* `caller_hangup` \u2014 caller's leg went away. Precise when the worker observed the SIP `participant_disconnected` event (stamped immediately); otherwise stamped server-side ~10s after `room_finished` as a catch-all (web tab close, network blip, worker crash, etc.).\n* `null` \u2014 pre-rollout calls only (anything that landed after the rollout completes without a stamp gets `caller_hangup` from the post-call goroutine).\n","title":"ConversationEndReason"},"tts:AgentSnapshot":{"type":"object","properties":{"schema_version":{"type":"integer"},"captured_at":{"type":"string","format":"date-time"},"name":{"type":"string"},"prompt":{"type":"string"},"first_message":{"type":"string"},"language":{"type":"string"},"llm_model":{"type":"string"},"voice_id":{"type":"string"},"temperature":{"type":"number","format":"double"},"memory_enabled":{"type":"boolean"},"memory_retention_days":{"type":"integer"},"tts_speaking_rate":{"type":["number","null"],"format":"double"},"tts_playback_rate":{"type":["number","null"],"format":"double"},"response_delay_seconds":{"type":["number","null"],"format":"double"}},"description":"Frozen subset of the agent's configuration captured at\nconversation-create time (AIS-2778) so the detail view can\nrender historical calls accurately even after the live\nagent's prompt or voice has been edited. Carries its own\n`schema_version` because the snapshot shape evolves\nindependently of the live Agent shape.\n","title":"AgentSnapshot"},"tts:ConversationIvrSurrenderReason":{"type":"string","enum":["no_goal","no_cached_menu","below_threshold","fingerprint_mismatch","goal_ambiguous","child_cache_miss","dtmf_send_failure","matched_option_missing_dtmf","disabled","repeated_prompt_max_retries"],"description":"AIS-3322 canonical code the worker emits when the IVR\nnavigator gave up. NULL when the navigator completed\ncleanly OR never started a plan.\n* `no_goal` - the goal extractor returned empty.\n* `no_cached_menu` - AMD-time cache miss for the root fingerprint.\n* `below_threshold` - cached menu loaded but confidence < threshold.\n* `fingerprint_mismatch` - in-call prompt diverged from the cached menu fingerprint.\n* `goal_ambiguous` - cached options matched the goal more than once or not at all.\n* `child_cache_miss` - sub-menu fingerprint had no cached row.\n* `dtmf_send_failure` - DTMF press could not be delivered.\n* `matched_option_missing_dtmf` - defensive shape guard.\n* `disabled` - per-agent toggle off OR operator kill switch on.\n* `repeated_prompt_max_retries` - bounded press-retry on the same fingerprint hit its cap of 1.\n","title":"ConversationIvrSurrenderReason"},"tts:Conversation":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`conv_<26 char Crockford base32>`).\nADR 0015 Cluster 2 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 2.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nfor the agent that answers this conversation. ADR 0015\nFK consistency: customer-facing responses emit the prefixed\nform, never raw UUIDs.\n"},"room_name":{"type":"string","description":"LiveKit room name. Equals the conversation `id` for `web`\nand `sip_outbound` transports; `sip_inbound` rooms use a\n`sip__` name assigned by the SIP dispatch rule.\n"},"room_sid":{"type":"string"},"status":{"$ref":"#/components/schemas/tts:ConversationStatus"},"transport":{"$ref":"#/components/schemas/tts:ConversationTransport"},"created_at":{"type":"string","format":"date-time","description":"When the conversation row was created (the call was\ninitiated). Always present, including for conversations\nthat never started \u2014 unlike `started_at` \u2014 so it is the\ntimestamp to display and sort pending calls by.\n"},"started_at":{"type":["string","null"],"format":"date-time","description":"Set when the first user participant joins the realtime\nvoice session. Null between CreateConversation and the\nparticipant-joined event, and stays null if no user ever\njoins.\n"},"ended_at":{"type":["string","null"],"format":"date-time"},"duration_ms":{"type":["integer","null"]},"cost_cents":{"type":["integer","null"]},"recording_url":{"type":["string","null"]},"recording_started_at":{"type":["string","null"],"format":"date-time","description":"When the recording file actually began capturing audio\n(LiveKit egress file started_at). Anchor transcript message\noffsets on this \u2014 not `started_at` \u2014 when seeking the\nrecording: the file's first frame trails the participant\njoin by the egress recorder's spin-up (~1-2s). Null when\nthere is no recording or the row pre-dates the field.\n"},"end_reason":{"$ref":"#/components/schemas/tts:ConversationEndReason","description":"Coarse termination category. Worker-stamped reasons arrive\nbefore `terminate_call` fires; `caller_hangup` has two\nemit sites (worker-observed SIP disconnect, plus a\nserver-side post-call catch-all).\n* `voicemail_message_left` \u2014 AMD machine-vm + we spoke the configured drop-message.\n* `voicemail_hangup` \u2014 AMD machine-vm + we terminated silently (action=hangup or empty-message bypass).\n* `ivr_hangup` \u2014 AMD machine-ivr + action=hangup.\n* `unavailable_hangup` \u2014 AMD machine-unavailable (mailbox full / disconnected).\n* `agent_ended` \u2014 LLM-driven end_call builtin.\n* `inactivity_timeout` \u2014 worker's inactivity handler fired terminate after the configured silence window.\n* `loop_detected` \u2014 worker's runtime loop guard force-ended the call after N consecutive near-identical user turns (typically an IVR replaying its menu while the LLM kept reacting instead of calling end_call).\n* `max_duration_reached` - worker's max-call-duration watchdog force-ended the call at the platform ceiling (a safety bound on runaway calls).\n* `caller_hangup` \u2014 caller's leg went away. Precise when the worker observed the SIP `participant_disconnected` event (stamped immediately); otherwise stamped server-side ~10s after `room_finished` as a catch-all (web tab close, network blip, worker crash, etc.).\n* `null` \u2014 pre-rollout calls only (anything that landed after the rollout completes without a stamp gets `caller_hangup` from the post-call goroutine).\n"},"metadata":{"type":"object","additionalProperties":{"description":"Any type"}},"caller_identity":{"type":"string","description":"Stable caller key (LiveKit participant identity) persisted\nat session start so the post-call memory extractor can\npivot memories by `(agent_id, caller_identity)`. Empty\nstring for anonymous widget sessions.\n"},"agent_snapshot":{"$ref":"#/components/schemas/tts:AgentSnapshot","description":"Frozen snapshot of the agent's configuration at create\ntime. Populated only on detail responses; list responses\nintentionally skip the column to keep the row small.\n"},"dynamic_variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Customer-facing dynamic variables this call ran with: the\nagent's stored variable defaults overlaid with the\nper-session `dynamic_variables` overrides, resolved to\ntheir values. Reserved `system__*` keys are excluded \u2014\nthey are runtime-derived and not part of the audit\nsnapshot. Omitted for SIP inbound calls (which take no\nper-session variables) and for any pre-rollout\nconversation. Populated only on detail responses; the\nlist endpoint skips it, mirroring `agent_snapshot`.\n"},"message_count":{"type":"integer","description":"Populated only on the list endpoint via a correlated\nsubquery. Zero on single-row reads where the join cost\nisn't paid.\n"},"ivr_menu_id":{"type":["string","null"],"description":"AIS-3322 audit pointer at the cached IVR menu the\nnavigator consulted on this call. NULL when the navigator\nnever engaged OR after the referenced menu was\ninvalidated (FK is ON DELETE SET NULL).\n"},"ivr_path_taken":{"type":["array","null"],"items":{"type":"object","additionalProperties":{"description":"Any type"}},"description":"AIS-3322 ordered log of the navigator's per-call presses:\n`[{fingerprint, dtmf, label}, ...]`. Empty array means\n\"navigator engaged but pressed nothing\" (distinct from\nNULL = \"navigator never engaged\").\n"},"ivr_surrender_reason":{"$ref":"#/components/schemas/tts:ConversationIvrSurrenderReason","description":"AIS-3322 canonical code the worker emits when the IVR\nnavigator gave up. NULL when the navigator completed\ncleanly OR never started a plan.\n* `no_goal` - the goal extractor returned empty.\n* `no_cached_menu` - AMD-time cache miss for the root fingerprint.\n* `below_threshold` - cached menu loaded but confidence < threshold.\n* `fingerprint_mismatch` - in-call prompt diverged from the cached menu fingerprint.\n* `goal_ambiguous` - cached options matched the goal more than once or not at all.\n* `child_cache_miss` - sub-menu fingerprint had no cached row.\n* `dtmf_send_failure` - DTMF press could not be delivered.\n* `matched_option_missing_dtmf` - defensive shape guard.\n* `disabled` - per-agent toggle off OR operator kill switch on.\n* `repeated_prompt_max_retries` - bounded press-retry on the same fingerprint hit its cap of 1.\n"}},"required":["id","agent_id","room_name","status","transport","created_at","metadata","message_count"],"title":"Conversation"},"tts:CreateConversationResponse":{"type":"object","properties":{"conversation":{"$ref":"#/components/schemas/tts:Conversation"},"room":{"type":"string"},"token":{"type":"string","description":"Short-lived realtime session access token (JWT)."},"url":{"type":"string","description":"Realtime session wss:// URL to connect to."}},"required":["conversation","room","token","url"],"description":"Returned when a conversation is created. The `token` + `url`\nlet the caller connect its browser/SDK directly to the\nrealtime voice session \u2014 the agent that answers is dispatched\nserver-side.\n","title":"CreateConversationResponse"},"tts:CreateSessionRequest":{"type":"object","properties":{"user_identity":{"type":"string","description":"Opaque identifier for the end-user (e.g. your app's user ID). Stamped onto the conversation. Optional - defaults to an anonymous per-session ID."},"dynamic_variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-session variable overrides that merge on top of the agent's\nstored variable defaults for this one session. Keys in the\nreserved `system__` namespace are rejected at this boundary.\nValues must match the declared type of the corresponding variable\ndefinition on the agent (a `string` type expects a JSON string,\n`number` expects a JSON number, etc.).\n"}},"description":"Optional body for `POST /v1/agents/{id}/sessions`. Widget embeds usually pass nothing.","title":"CreateSessionRequest"},"tts:AgentVoiceType":{"type":"string","enum":["shared"],"description":"Voice provenance. Always `shared` on this endpoint \u2014 personal\n/ cloned voices are not exposed here; they stay on\n`GET /v1/voices`.\n","title":"AgentVoiceType"},"tts:AgentVoiceModelName":{"type":"string","enum":["simba-english","simba-multilingual"],"title":"AgentVoiceModelName"},"tts:AgentVoiceLanguage":{"type":"object","properties":{"locale":{"type":"string","description":"BCP-47-ish locale tag (e.g. `en-US`, `de-DE`)."},"preview_audio":{"type":["string","null"],"description":"URL to a short audio preview for this locale, or null if\nno preview is available.\n"}},"required":["locale","preview_audio"],"title":"AgentVoiceLanguage"},"tts:AgentVoiceModel":{"type":"object","properties":{"name":{"$ref":"#/components/schemas/tts:AgentVoiceModelName"},"languages":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentVoiceLanguage"}}},"required":["name","languages"],"description":"One TTS engine the voice can be synthesised through. Each\nagent voice exposes a multilingual model, plus an\nenglish-specific model for voices whose locale starts with\n`en`.\n","title":"AgentVoiceModel"},"tts:AgentVoiceGender":{"type":"string","enum":["male","female","notSpecified"],"description":"Speaker gender as classified by VMS. `notSpecified` is used\nwhen the source dataset didn't carry the metadata; the\nconsole treats it as a neutral display label rather than a\nfilter gap.\n","title":"AgentVoiceGender"},"tts:AgentVoice":{"type":"object","properties":{"id":{"type":"string","description":"Voice slug. Passed verbatim as `voice_id` on agent writes."},"type":{"$ref":"#/components/schemas/tts:AgentVoiceType"},"display_name":{"type":"string"},"models":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentVoiceModel"}},"gender":{"$ref":"#/components/schemas/tts:AgentVoiceGender"},"locale":{"type":"string","description":"Default locale for the voice (BCP-47-ish, e.g. `en-US`)."},"preview_audio":{"type":["string","null"],"description":"Preferred preview clip URL, locale-matched when possible."},"avatar_image":{"type":["string","null"],"description":"Avatar URL for the picker UI. Null when no avatar is\nconfigured; the wire is intentionally `null` rather than\n`\"\"` so the picker doesn't render a broken ` `.\n"},"tags":{"type":["array","null"],"items":{"type":"string"},"description":"VMS-defined tags (e.g. `narrator`, `young`)."}},"required":["id","type","display_name","models","gender","locale","preview_audio","avatar_image"],"description":"One row in the curated voice catalogue returned by\n`GET /v1/agents/voices`. Matches the slug set accepted by\nagent create/update.\n","title":"AgentVoice"},"tts:SystemBuiltin":{"type":"string","description":"Identifier of a worker-resident system builtin. New entries are\nadded together on the server (a new `tool_builtin_.go`\nfile) and worker (`tools/builtins/.py`) - the 2-file rule\nAIS-3053 pins. Customers read the catalogue from\n`GET /v1/agents/tools/system-builtins` rather than depending on this\nstring set staying stable across releases.\n","title":"SystemBuiltin"},"tts:CreateAgentBuiltinRequest":{"type":"object","properties":{"builtin":{"$ref":"#/components/schemas/tts:SystemBuiltin"},"name":{"type":"string","description":"LLM-facing tool name. Must match the tool-name regex and be unique within the agent's builtin set."},"description":{"type":"string"},"config":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-instance configuration matching the per-builtin schema."},"params":{"type":"array","items":{"type":"object","additionalProperties":{"description":"Any type"}},"description":"Per-call parameter descriptors."},"enabled":{"type":"boolean","description":"Defaults to true on the server when omitted."}},"required":["builtin","name"],"title":"CreateAgentBuiltinRequest"},"tts:AgentBuiltin":{"type":"object","properties":{"id":{"type":"string","description":"Opaque builtin instance ID."},"tenant_id":{"type":"string","description":"The workspace owning this instance."},"agent_id":{"type":"string","description":"The agent this instance is bound to."},"builtin":{"$ref":"#/components/schemas/tts:SystemBuiltin"},"name":{"type":"string","description":"LLM-facing tool name. Unique within the agent's builtin set."},"description":{"type":"string","description":"LLM-facing one-line description of when to call the tool."},"config":{"type":["object","null"],"additionalProperties":{"description":"Any type"},"description":"Per-instance configuration shape. The schema depends on\n`builtin` \u2014 see the per-builtin contracts under\n`/contracts/tools/system_*.schema.json`. Null when the\nbuiltin takes no instance-level config.\n"},"params":{"type":["array","null"],"items":{"type":"object","additionalProperties":{"description":"Any type"}},"description":"Per-call parameter schema fragment merged into the model's\ntool spec. Each entry is one parameter descriptor (the\nper-builtin contract pins the exact shape). Null when the\nbuiltin takes no caller arguments.\n"},"enabled":{"type":"boolean","description":"When false, the instance is persisted but skipped at dispatch."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","tenant_id","agent_id","builtin","name","description","enabled","created_at","updated_at"],"description":"One instance of a system builtin bound to a specific agent.\nStorage lives in the `agent_builtins` table (migration 00061);\nwire format intentionally matches the legacy `kind=\"system\"`\nTool shape so the worker is untouched by the AIS-3116 split.\n","title":"AgentBuiltin"},"tts:ListAgentBuiltinsResponse":{"type":"object","properties":{"builtins":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentBuiltin"}}},"required":["builtins"],"title":"ListAgentBuiltinsResponse"},"tts:UpdateAgentBuiltinRequest":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"config":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-instance configuration matching the per-builtin schema."},"params":{"type":"array","items":{"type":"object","additionalProperties":{"description":"Any type"}},"description":"Per-call parameter descriptors."},"enabled":{"type":"boolean"}},"description":"PATCH body. All fields optional; omitting a field leaves it\nunchanged. The underlying `builtin` is NOT patchable \u2014 delete\nand recreate to change which capability an instance maps to.\n","title":"UpdateAgentBuiltinRequest"},"tts:DynamicVariableType":{"type":"string","enum":["string","number","boolean","json"],"description":"Declared type of a customer-scope variable. Enforced at save time\nand again at session-start when an override value is supplied.\n- `string` - plain text value; interpolated verbatim with `{{name}}`\n- `number` - numeric value; rendered as its decimal representation\n- `boolean` - `true` or `false`\n- `json` - any valid JSON value; use `{{name|json}}` to inject\n safely inside JSON tool bodies\n","title":"DynamicVariableType"},"tts:DynamicVariable":{"type":"object","properties":{"key":{"type":"string","description":"Variable name. Must match `[a-zA-Z0-9_]+`. The `system__` prefix\nis reserved for platform-populated variables and will be rejected.\n"},"type":{"$ref":"#/components/schemas/tts:DynamicVariableType"},"default":{"description":"Optional default value used when no per-session override is\nsupplied. Must conform to the declared `type`.\n"},"description":{"type":"string","description":"Human-readable note shown in the console variable editor."}},"required":["key","type"],"description":"One customer-scope variable definition on an agent. Referenced in\nprompts, first messages, and webhook tool configs via `{{key}}` or\n`{{key|json}}`. Missing variables render as empty string at dispatch\ntime - a typo never breaks a session.\n","title":"DynamicVariable"},"tts:SystemVariableDoc":{"type":"object","properties":{"key":{"type":"string","description":"The reserved variable key (always starts with `system__`)."},"description":{"type":"string","description":"What the variable contains and when it is populated."}},"required":["key","description"],"description":"Documents one reserved `system__*` variable that the platform\nauto-populates at session start. Customers cannot define or\noverride these keys.\n","title":"SystemVariableDoc"},"tts:ListDynamicVariablesResponse":{"type":"object","properties":{"variables":{"type":"array","items":{"$ref":"#/components/schemas/tts:DynamicVariable"},"description":"Customer-defined variables for this agent."},"system_variables":{"type":"array","items":{"$ref":"#/components/schemas/tts:SystemVariableDoc"},"description":"Platform-populated `system__*` variables, provided for\nreference. This list is the same for every agent.\n"}},"required":["variables","system_variables"],"description":"Response for `GET /v1/agents/{id}/variables`. Returns both the\ncustomer-scope variable catalogue and the read-only `system__*`\ncatalogue so the editor UI has a single source of truth.\n","title":"ListDynamicVariablesResponse"},"tts:UpdateDynamicVariablesRequest":{"type":"object","properties":{"variables":{"type":"array","items":{"$ref":"#/components/schemas/tts:DynamicVariable"},"description":"The new variable list. Replaces the existing list entirely."}},"required":["variables"],"description":"PATCH body for `PATCH /v1/agents/{id}/variables`. Replaces the\nstored variable list wholesale. Pass an empty array to clear all\nvariables. Up to 20 variables per agent.\n","title":"UpdateDynamicVariablesRequest"},"tts:EvaluationCriterion":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"}},"required":["id","name","description"],"description":"One LLM-scored assertion about the call (\"Did the agent confirm the customer's name?\").","title":"EvaluationCriterion"},"tts:DataCollectionFieldType":{"type":"string","enum":["string","int","number","boolean"],"title":"DataCollectionFieldType"},"tts:DataCollectionField":{"type":"object","properties":{"key":{"type":"string"},"description":{"type":"string"},"type":{"$ref":"#/components/schemas/tts:DataCollectionFieldType"}},"required":["key","description","type"],"description":"A structured value the post-call evaluator should extract from the\ntranscript. `int` is distinct from `number` so downstream consumers\nreceive whole integers without a synthetic decimal.\n","title":"DataCollectionField"},"tts:EvaluationConfig":{"type":"object","properties":{"criteria":{"type":"array","items":{"$ref":"#/components/schemas/tts:EvaluationCriterion"}},"data_collection":{"type":"array","items":{"$ref":"#/components/schemas/tts:DataCollectionField"}}},"required":["criteria","data_collection"],"title":"EvaluationConfig"},"tts:UpdateEvaluationConfigRequest":{"type":"object","properties":{"criteria":{"type":"array","items":{"$ref":"#/components/schemas/tts:EvaluationCriterion"}},"data_collection":{"type":"array","items":{"$ref":"#/components/schemas/tts:DataCollectionField"}}},"required":["criteria","data_collection"],"title":"UpdateEvaluationConfigRequest"},"tts:KnowledgeBase":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`kb_<26 char Crockford base32>`).\nADR 0015 Cluster 1 hard-break.\n"},"name":{"type":"string","description":"Human-readable label, shown in the console."},"description":{"type":"string","description":"Optional description."},"document_count":{"type":"integer","description":"Number of ingested documents."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","description","document_count","created_at","updated_at"],"description":"A bundle of documents that can be attached to one or more voice\nagents. Chunks across every document in the knowledge base are\nembedded and searched together.","title":"KnowledgeBase"},"tts:AttachedKnowledgeBasesResponse":{"type":"object","properties":{"knowledge_bases":{"type":"array","items":{"$ref":"#/components/schemas/tts:KnowledgeBase"}}},"required":["knowledge_bases"],"description":"Bare list of the knowledge bases attached to an agent. Not\npaginated \u2014 an agent's KB attachment count is naturally\nbounded (configuration, not data scale). See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the \"pagination only where needed\" rule.\n","title":"AttachedKnowledgeBasesResponse"},"tts:Memory":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`memory_<26 char Crockford base32>`).\nADR 0015 Cluster 2 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 2.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the owning agent. ADR 0015 FK consistency.\n"},"caller_identity":{"type":"string","description":"Stable caller key (LiveKit participant identity) the memory is scoped to."},"fact":{"type":"string","description":"Short third-person statement about the caller."},"source_conversation_id":{"type":["string","null"],"description":"When set, the prefixed wire identifier\n(`conv_<26 char Crockford base32>`) of the conversation this\nmemory was extracted from. May be null if the source was\ndeleted. ADR 0015 FK consistency.\n"},"confidence":{"type":"number","format":"double","description":"LLM self-reported 0-1 confidence in the fact's durability and relevance."},"score":{"type":"number","format":"double","description":"Populated only on retrieval hits \u2014 recency-weighted cosine similarity."},"created_at":{"type":"string","format":"date-time"}},"required":["id","agent_id","caller_identity","fact","confidence","created_at"],"description":"One salient fact extracted post-call about a specific caller on\na specific agent. Retrieved at the next conversation-start for\nthe same caller and injected into the agent's system prompt via\nthe `{{memory}}` template variable.","title":"Memory"},"tts:ListMemoriesResponse":{"type":"object","properties":{"memories":{"type":"array","items":{"$ref":"#/components/schemas/tts:Memory"}}},"required":["memories"],"title":"ListMemoriesResponse"},"tts:DeleteMemoriesByCallerRequest":{"type":"object","properties":{"agent_id":{"type":"string"},"caller_identity":{"type":"string"}},"required":["agent_id","caller_identity"],"title":"DeleteMemoriesByCallerRequest"},"tts:DeleteMemoriesByCallerResponse":{"type":"object","properties":{"deleted":{"type":"integer","description":"Number of memories soft-deleted."}},"required":["deleted"],"title":"DeleteMemoriesByCallerResponse"},"tts:TestType":{"type":"string","enum":["reply","tool","simulation"],"description":"Discriminates the shape of `AgentTest.config`.\n- `reply` - send one message to the agent and judge the response with an LLM.\n- `tool` - assert that the agent calls a specific tool given a context.\n- `simulation` - run a multi-turn conversation between the agent and an AI caller.\n","title":"TestType"},"tts:SimulationMessageRole":{"type":"string","enum":["user","assistant"],"title":"SimulationMessageRole"},"tts:SimulationMessage":{"type":"object","properties":{"role":{"$ref":"#/components/schemas/tts:SimulationMessageRole"},"content":{"type":"string"}},"required":["role","content"],"description":"One turn in a simulation conversation. `role` is `user` (the AI caller) or `assistant` (the agent).","title":"SimulationMessage"},"tts:ReplyConfig":{"type":"object","properties":{"context":{"type":"string","description":"User message sent to the agent to trigger the behaviour under test. Optional when `initial_chat_history` already ends with a user message."},"success_criteria":{"type":"string","description":"Natural-language description of what a passing agent response looks like."},"success_examples":{"type":"array","items":{"type":"string"},"description":"Concrete examples of passing responses (few-shot for the judge)."},"failure_examples":{"type":"array","items":{"type":"string"},"description":"Concrete examples of failing responses (few-shot for the judge)."},"initial_chat_history":{"type":"array","items":{"$ref":"#/components/schemas/tts:SimulationMessage"},"description":"Optional seed conversation prepended before `context`. Lets you test the agent's reply mid-conversation rather than on a cold single-turn prompt."},"system_prompt_override":{"type":"string","description":"Deprecated (AIS-3443). Prefer the run-level `config_override`\non `POST /v1/agents/{id}/tests/runs`, which applies a proposed\nprompt to every test in the run without editing each one.\nStill honoured; the run-level override wins when both are set.\nReplaces the agent's system prompt for this run only."},"first_message_override":{"type":"string","description":"Replaces the agent's first message for this run only."},"model_override":{"type":"string","description":"Deprecated (AIS-3443). Prefer the run-level `config_override`\non `POST /v1/agents/{id}/tests/runs`. Still honoured; the\nrun-level override wins when both are set. Overrides the LLM\nmodel used by the agent for this run only."}},"required":["success_criteria"],"description":"Configuration for a `reply` test. The runner sends `context` as\na user message and asks an LLM judge to evaluate the agent response\nagainst `success_criteria`. Optional few-shot examples sharpen the\njudge's calibration. Use `initial_chat_history` to prepend prior\nturns before `context`; when the history already ends with a user\nmessage, `context` may be omitted and the agent is evaluated on\nits reply to that last history turn.","title":"ReplyConfig"},"tts:ParameterCheckMode":{"type":"string","enum":["exact","regex","llm"],"description":"How a `ParameterCheck` validates a tool argument.\n- `exact` - JSON equality.\n- `regex` - the argument stringified is matched against the pattern.\n- `llm` - an LLM judge decides whether the value semantically satisfies\n the criteria (e.g. \"is a plausible email address\").\n","title":"ParameterCheckMode"},"tts:ParameterCheck":{"type":"object","properties":{"path":{"type":"string","description":"Dotted JSON path to the argument being checked. Empty means the whole args object."},"mode":{"$ref":"#/components/schemas/tts:ParameterCheckMode"},"expected":{"type":"string","description":"Expected value string for `exact` and `regex` modes."},"criteria":{"type":"string","description":"Natural-language criteria for `llm` mode (e.g. \"is a valid email address\")."}},"required":["path","mode"],"description":"Validates one argument of an expected tool call. `path` is a\ndotted JSON path (e.g. `customer.email`); use zero-indexed\nnotation for arrays (`items.0.sku`). An empty path checks the\nwhole args object.","title":"ParameterCheck"},"tts:ToolCallConfig":{"type":"object","properties":{"context":{"type":"string","description":"User message that should cause the agent to invoke the expected tool. Optional when `initial_chat_history` already ends with a user message."},"expected_tool":{"type":"string","description":"Name of the tool the agent is expected to call. Leave empty to\ninvert the assertion: the test passes only when the agent calls\nno tool at all."},"parameter_checks":{"type":"array","items":{"$ref":"#/components/schemas/tts:ParameterCheck"},"description":"Assertions on specific arguments of the tool call."},"initial_chat_history":{"type":"array","items":{"$ref":"#/components/schemas/tts:SimulationMessage"},"description":"Optional seed conversation prepended before `context`."},"system_prompt_override":{"type":"string","description":"Deprecated (AIS-3443). Prefer the run-level `config_override`\non `POST /v1/agents/{id}/tests/runs`. Still honoured; the\nrun-level override wins when both are set. Replaces the\nagent's system prompt for this run only."},"model_override":{"type":"string","description":"Deprecated (AIS-3443). Prefer the run-level `config_override`\non `POST /v1/agents/{id}/tests/runs`. Still honoured; the\nrun-level override wins when both are set. Overrides the LLM\nmodel used by the agent for this run only."}},"required":["expected_tool"],"description":"Configuration for a `tool` test. The runner sends `context` as a\nuser message and asserts that the agent calls `expected_tool` with\narguments matching all `parameter_checks`. Use\n`initial_chat_history` to test tool invocations that only make\nsense mid-conversation.","title":"ToolCallConfig"},"tts:DataAssertionMode":{"type":"string","enum":["exact","regex","llm"],"description":"How the assertion validates the extracted value.","title":"DataAssertionMode"},"tts:DataAssertion":{"type":"object","properties":{"key":{"type":"string","description":"Name of the data-collection field on the agent's evaluation config. The assertion fails when this key is missing from the extracted data."},"mode":{"$ref":"#/components/schemas/tts:DataAssertionMode","description":"How the assertion validates the extracted value."},"expected":{"type":"string","description":"Expected value string for `exact` and `regex` modes."},"criteria":{"type":"string","description":"Natural-language criteria for `llm` mode."}},"required":["key","mode"],"description":"Asserts on one entry in the LLM-extracted data-collection map\nproduced by the unified evaluator. `key` matches a\ndata-collection field configured on the agent; the assertion\nruns against the value the judge wrote under that key. Same\nexact / regex / llm modes as `ParameterCheck` so the tool-call\nand data-collection assertion surfaces are uniform.","title":"DataAssertion"},"tts:SimulationConfig":{"type":"object","properties":{"scenario":{"type":"string","description":"Instructions for the AI caller describing who they are and what they want."},"max_turns":{"type":"integer","default":5,"description":"Maximum agent turns before the simulation is cut off and judged."},"initial_chat_history":{"type":"array","items":{"$ref":"#/components/schemas/tts:SimulationMessage"},"description":"Optional seed conversation that precedes the AI caller's first generated message."},"data_assertions":{"type":"array","items":{"$ref":"#/components/schemas/tts:DataAssertion"},"description":"Optional assertions on the LLM-extracted data-collection\nmap. Each entry references a key from the agent's\ndata_collection config and validates the extracted value.\nThe test fails if any assertion fails."},"system_prompt_override":{"type":"string","description":"Deprecated (AIS-3443). Prefer the run-level `config_override`\non `POST /v1/agents/{id}/tests/runs`. Still honoured; the\nrun-level override wins when both are set. Replaces the\nagent's system prompt for this run only."},"model_override":{"type":"string","description":"Deprecated (AIS-3443). Prefer the run-level `config_override`\non `POST /v1/agents/{id}/tests/runs`. Still honoured; the\nrun-level override wins when both are set. Overrides the LLM\nmodel used by the agent for this run only."}},"required":["scenario"],"description":"Configuration for a `simulation` test. An AI caller drives a\nmulti-turn conversation with the agent according to `scenario`.\nAfter `max_turns` exchanges (or when the agent ends the call),\nthe unified post-call evaluator scores the synthetic transcript\nagainst the agent's configured evaluation criteria + data\ncollection fields. A test passes when no configured criterion\nfails and every `data_assertions` entry passes.","title":"SimulationConfig"},"tts:AgentTestConfig":{"oneOf":[{"$ref":"#/components/schemas/tts:ReplyConfig"},{"$ref":"#/components/schemas/tts:ToolCallConfig"},{"$ref":"#/components/schemas/tts:SimulationConfig"}],"description":"Type-specific configuration document.","title":"AgentTestConfig"},"tts:MockingStrategy":{"type":"string","enum":["none","all","selected"],"description":"Controls which tool calls the runner intercepts during a run.\nSystem tools (`end_call`, `transfer_to_number`, etc.) are never\nmocked regardless of strategy.\n- `none` - no interception; all tools are called normally.\n- `all` - every non-system tool call is intercepted and matched\n against the `mocks` list.\n- `selected` - only tools explicitly listed in `mocks` are\n intercepted; others are called normally.\n","title":"MockingStrategy"},"tts:ToolMock":{"type":"object","properties":{"tool_name":{"type":"string","description":"Name of the tool to intercept."},"args_match":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Optional structured argument matcher. When set, the mock fires\nonly if the tool call's arguments deep-contain every key/value\nin this object: nested objects match recursively as subsets,\narrays and scalar leaves match by deep equality. An empty\nobject matches unconditionally. When absent the mock matches\nunconditionally for this tool."},"response":{"description":"JSON value returned to the agent as the tool result."}},"required":["tool_name","response"],"description":"A canned response returned when the agent calls `tool_name`. If\n`args_match` is set the mock only triggers when the call arguments\ndeep-contain it (a structured subset match). A mock without\n`args_match` always matches for its tool.","title":"ToolMock"},"tts:NoMatchBehavior":{"type":"string","enum":["call_real_tool","finish_with_error","skip"],"description":"Fallback when a mockable tool is called but no configured mock\nmatches the call arguments.\n- `call_real_tool` - pass-through: actually invoke the underlying\n tool (a webhook tool POSTs to the customer endpoint). Use only\n when the real call is safe to make from a test.\n- `finish_with_error` - fail: the run finishes as a `failed`\n verdict. Useful when a test wants to assert that a specific\n mocked response path is taken - any unmocked tool call fails the\n test.\n- `skip` - return an empty stub (`{\"skipped\":true}`) to the agent so\n the simulation proceeds without treating the call as a failure.\n Useful when a tool's output is irrelevant to the behaviour under\n test but the model may still decide to call it. This is the\n default for a test with no mock configuration.\n","title":"NoMatchBehavior"},"tts:ToolMockConfig":{"type":"object","properties":{"strategy":{"$ref":"#/components/schemas/tts:MockingStrategy"},"mocks":{"type":"array","items":{"$ref":"#/components/schemas/tts:ToolMock"},"description":"Canned responses for specific tools (order matters - first match wins)."},"no_match_behavior":{"$ref":"#/components/schemas/tts:NoMatchBehavior"}},"required":["strategy","no_match_behavior"],"description":"Controls tool-call interception during a test run.","title":"ToolMockConfig"},"tts:TestRunStatus":{"type":"string","enum":["queued","running","passed","failed","error"],"description":"Lifecycle of a test run: `queued` - `running` - terminal.\n\nTerminal states:\n- `passed` - the agent behaviour met the success criteria.\n- `failed` - the agent behaviour did not meet the success criteria.\n- `error` - the runner itself could not complete (LLM outage, network error, etc.),\n distinct from `failed` which means the agent behaviour was judged and found lacking.\n","title":"TestRunStatus"},"tts:ReplyResult":{"type":"object","properties":{"agent_response":{"type":"string","description":"The raw text response the agent produced."},"passed":{"type":"boolean"},"rationale":{"type":"string","description":"LLM judge's explanation of the verdict."},"score":{"type":"number","format":"double","description":"0-1 judge confidence score."},"duration_ms":{"type":"integer","format":"int64","description":"Wall-clock time for the run in milliseconds."}},"required":["agent_response","passed","rationale","score","duration_ms"],"description":"Result details for a `reply` test run.","title":"ReplyResult"},"tts:ParameterCheckResult":{"type":"object","properties":{"path":{"type":"string"},"mode":{"$ref":"#/components/schemas/tts:ParameterCheckMode"},"actual_json":{"type":"string","description":"JSON-serialised actual value at `path`."},"passed":{"type":"boolean"},"rationale":{"type":"string","description":"LLM rationale (populated for `llm` mode checks)."}},"required":["path","mode","actual_json","passed"],"description":"Result of one `ParameterCheck` within a tool-call test run.","title":"ParameterCheckResult"},"tts:ToolCallResult":{"type":"object","properties":{"tool_called":{"type":"string","description":"Name of the tool the agent actually called (may differ from `expected_tool`)."},"tool_args":{"description":"Arguments the agent passed to the tool, as a JSON object."},"expected_tool":{"type":"string","description":"Name of the tool the test expected the agent to call."},"tool_matched":{"type":"boolean","description":"True when `tool_called` equals `expected_tool`."},"parameter_results":{"type":"array","items":{"$ref":"#/components/schemas/tts:ParameterCheckResult"}},"passed":{"type":"boolean"},"rationale":{"type":"string","description":"Explanation of the overall verdict."},"duration_ms":{"type":"integer","format":"int64"}},"required":["tool_called","expected_tool","tool_matched","parameter_results","passed","rationale","duration_ms"],"description":"Result details for a `tool` test run.","title":"ToolCallResult"},"tts:SimulationToolCall":{"type":"object","properties":{"turn_index":{"type":"integer","description":"Zero-based index of the conversation turn in which this call occurred."},"tool_name":{"type":"string"},"args":{"description":"Arguments passed to the tool, as a JSON object."},"response":{"description":"Response returned to the agent (absent for system tools that end the call)."},"mocked":{"type":"boolean"}},"required":["turn_index","tool_name","args","mocked"],"description":"One tool invocation that occurred during a simulation run.\n`mocked` is true when the call was intercepted by the run's\nmock config; false when the real tool was called or when the\ntool is a system tool.","title":"SimulationToolCall"},"tts:SimulationResultSentiment":{"type":"string","enum":["positive","neutral","negative"],"description":"Overall sentiment classification.","title":"SimulationResultSentiment"},"tts:SimulationCriterionResultStatus":{"type":"string","enum":["success","failure","unknown"],"description":"Three-state outcome. `unknown` means the criterion did not\napply on this run (the topic never came up); `failure`\nmeans it did apply and the agent did not satisfy it.","title":"SimulationCriterionResultStatus"},"tts:SimulationCriterionResult":{"type":"object","properties":{"criterion_id":{"type":"string"},"name":{"type":"string"},"status":{"$ref":"#/components/schemas/tts:SimulationCriterionResultStatus","description":"Three-state outcome. `unknown` means the criterion did not\napply on this run (the topic never came up); `failure`\nmeans it did apply and the agent did not satisfy it."},"score":{"type":"number","format":"double","description":"0.0..1.0 continuous estimate of how well the criterion was met."},"rationale":{"type":"string"}},"required":["criterion_id","name","status","rationale"],"description":"One scored entry of an agent's configured evaluation criterion\nagainst a simulation transcript. Mirrors the per-criterion row\nthe post-call evaluator persists, so test runs and live\nconversations carry identical per-criterion shapes.","title":"SimulationCriterionResult"},"tts:DataAssertionResultMode":{"type":"string","enum":["exact","regex","llm"],"title":"DataAssertionResultMode"},"tts:DataAssertionResult":{"type":"object","properties":{"key":{"type":"string"},"mode":{"$ref":"#/components/schemas/tts:DataAssertionResultMode"},"actual_json":{"type":"string","description":"The extracted value rendered as JSON (`null` when the key was missing from the data map)."},"passed":{"type":"boolean"},"rationale":{"type":"string","description":"Empty on pass; reason for failure otherwise."}},"required":["key","mode","actual_json","passed"],"description":"Outcome of one `data_assertions` entry: did the value the\nevaluator extracted under `key` pass the configured exact /\nregex / llm check.","title":"DataAssertionResult"},"tts:SimulationResult":{"type":"object","properties":{"transcript":{"type":"array","items":{"$ref":"#/components/schemas/tts:SimulationMessage"},"description":"Full synthetic conversation in order."},"tool_calls":{"type":"array","items":{"$ref":"#/components/schemas/tts:SimulationToolCall"},"description":"Every tool invocation across all turns."},"turns_used":{"type":"integer","description":"Number of agent turns that ran before the simulation ended."},"passed":{"type":"boolean"},"rationale":{"type":"string","description":"Top-level verdict explanation (run summary on pass; first failing criterion or assertion on fail)."},"duration_ms":{"type":"integer","format":"int64"},"summary":{"type":"string","description":"One-sentence narrative summary of what happened in the conversation."},"sentiment":{"$ref":"#/components/schemas/tts:SimulationResultSentiment","description":"Overall sentiment classification."},"criteria":{"type":"array","items":{"$ref":"#/components/schemas/tts:SimulationCriterionResult"},"description":"One result row per configured EvaluationCriterion on the\nagent. Same shape as the per-criterion rows persisted on\nthe post-call evaluations table."},"data":{"type":"object","additionalProperties":{"description":"Any type"},"description":"LLM-extracted values for the agent's configured\ndata-collection fields. Keys mirror the agent's\ndata_collection field keys; values are typed per the\ndeclared field type."},"data_assertions":{"type":"array","items":{"$ref":"#/components/schemas/tts:DataAssertionResult"},"description":"One result row per `data_assertions` entry on the simulation config."}},"required":["transcript","turns_used","passed","rationale","duration_ms"],"description":"Result details for a `simulation` test run. AIS-3446 unifies\nscoring with the post-call evaluator: the synthetic transcript\nis scored against the agent's configured evaluation criteria\nand data-collection fields, then per-test `data_assertions`\ncheck the extracted values. The top-level `passed` is derived\n\u2014 every criterion must resolve to `success` or `unknown` and\nevery assertion must pass.","title":"SimulationResult"},"tts:TestRunResult":{"type":"object","properties":{"test_type":{"$ref":"#/components/schemas/tts:TestType"},"passed":{"type":"boolean"},"rationale":{"type":"string","description":"Top-level verdict explanation duplicated from the inner result for quick rendering."},"duration_ms":{"type":"integer","format":"int64"},"reply":{"oneOf":[{"$ref":"#/components/schemas/tts:ReplyResult"},{"type":"null"}]},"tool_call":{"oneOf":[{"$ref":"#/components/schemas/tts:ToolCallResult"},{"type":"null"}]},"simulation":{"oneOf":[{"$ref":"#/components/schemas/tts:SimulationResult"},{"type":"null"}]}},"required":["test_type","passed","rationale","duration_ms"],"description":"Union-like result of a completed test run. Exactly one of\n`reply`, `tool_call`, or `simulation` is populated, matching\nthe `test_type`.","title":"TestRunResult"},"tts:AgentTestRun":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`run_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"test_id":{"type":"string","description":"Prefixed wire identifier (`test_<26 char Crockford base32>`)\nof the parent test. ADR 0015 FK consistency.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the agent this run executed against. ADR 0015 FK\nconsistency.\n"},"status":{"$ref":"#/components/schemas/tts:TestRunStatus"},"started_at":{"type":["string","null"],"format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"},"result":{"oneOf":[{"$ref":"#/components/schemas/tts:TestRunResult"},{"type":"null"}],"description":"Populated on terminal status only."},"error":{"type":"string","description":"Human-readable error message when status is `error`."},"created_at":{"type":"string","format":"date-time"}},"required":["id","test_id","agent_id","status","created_at"],"description":"One execution of a test. `result` is populated when `status`\nreaches a terminal state (`passed`, `failed`, or `error`).\nSee `TestRunResult` for the shape.","title":"AgentTestRun"},"tts:AgentTestWithLastRun":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`test_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the owning agent. ADR 0015 FK consistency.\n"},"name":{"type":"string"},"description":{"type":"string"},"type":{"$ref":"#/components/schemas/tts:TestType"},"config":{"$ref":"#/components/schemas/tts:AgentTestConfig","description":"Type-specific configuration document."},"tool_mock_config":{"$ref":"#/components/schemas/tts:ToolMockConfig","description":"Optional tool-mocking config applied during runs of this test."},"variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-test dynamic-variable overrides. Keys substitute `{{key}}`\nplaceholders inside the test config at run-start. Unknown keys\nrender as empty string, matching session dispatch behaviour.\n"},"folder_id":{"type":["string","null"],"description":"When set, prefixed wire identifier\n(`folder_<26 char Crockford base32>`) of the containing folder.\nNull means root (unfiled). ADR 0015 FK consistency.\n"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"last_run":{"oneOf":[{"$ref":"#/components/schemas/tts:AgentTestRun"},{"type":"null"}],"description":"The most recent run, or null if the test has never been run."},"attached_agent_ids":{"type":"array","items":{"type":"string"},"description":"Every agent this test runs against. Always includes the owner agent."}},"required":["id","agent_id","name","description","type","config","created_at","updated_at"],"description":"List-view projection of a test that includes the most recent run\nso the console can display pass/fail badges without an extra\nround-trip. On the global `/v1/agents/tests` surface, also carries\n`attached_agent_ids` so the row can render agent chips without a\nfollow-up request.","title":"AgentTestWithLastRun"},"tts:ListAgentTestsResponse":{"type":"object","properties":{"tests":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestWithLastRun"}}},"required":["tests"],"title":"ListAgentTestsResponse"},"tts:CreateAgentTestRequestConfig":{"oneOf":[{"$ref":"#/components/schemas/tts:ReplyConfig"},{"$ref":"#/components/schemas/tts:ToolCallConfig"},{"$ref":"#/components/schemas/tts:SimulationConfig"}],"description":"Type-specific configuration. Must match the shape for the given `type`.","title":"CreateAgentTestRequestConfig"},"tts:CreateAgentTestRequest":{"type":"object","properties":{"name":{"type":"string","description":"Short human-readable label for the test."},"description":{"type":"string","description":"Optional longer description of what this test verifies."},"type":{"$ref":"#/components/schemas/tts:TestType"},"config":{"$ref":"#/components/schemas/tts:CreateAgentTestRequestConfig","description":"Type-specific configuration. Must match the shape for the given `type`."},"tool_mock_config":{"$ref":"#/components/schemas/tts:ToolMockConfig","description":"Optional tool-mocking config applied during every run of this test."},"variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-test variable values substituted into string fields of the\nconfig at run-start. Keys use the same rules as agent-level\n`DynamicVariable` keys.\n"},"folder_id":{"type":["string","null"],"description":"Prefixed wire identifier (`folder_<26 char Crockford base32>`)\nof the folder to place the test in. Omit / null for root.\n"},"attached_agent_ids":{"type":"array","items":{"type":"string"},"description":"Optional list of additional agents this test should also run\nagainst. The owner agent (path param) is always attached\nimplicitly.\n"}},"required":["name","type","config"],"description":"Payload for `POST /v1/agents/{id}/tests`.","title":"CreateAgentTestRequest"},"tts:AgentTest":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`test_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the owning agent. ADR 0015 FK consistency.\n"},"name":{"type":"string"},"description":{"type":"string"},"type":{"$ref":"#/components/schemas/tts:TestType"},"config":{"$ref":"#/components/schemas/tts:AgentTestConfig","description":"Type-specific configuration document."},"tool_mock_config":{"$ref":"#/components/schemas/tts:ToolMockConfig","description":"Optional tool-mocking config applied during runs of this test."},"variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-test dynamic-variable overrides. Keys substitute `{{key}}`\nplaceholders inside the test config at run-start. Unknown keys\nrender as empty string, matching session dispatch behaviour.\n"},"folder_id":{"type":["string","null"],"description":"When set, prefixed wire identifier\n(`folder_<26 char Crockford base32>`) of the containing folder.\nNull means root (unfiled). ADR 0015 FK consistency.\n"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","agent_id","name","description","type","config","created_at","updated_at"],"description":"A configured test against a voice agent. `config` is a\ntype-specific document - see `ReplyConfig`, `ToolCallConfig`,\nand `SimulationConfig` for the per-type shapes (discriminated by `type`).","title":"AgentTest"},"tts:TestRunConfigOverride":{"type":"object","properties":{"prompt":{"type":"string","description":"Replaces the agent's system prompt for every test in the run."},"model":{"type":"string","description":"Overrides the LLM model for every test in the run. The model\nid rides on the agent's configured provider \u2014 a\ncross-provider switch is not supported."},"tool_ids":{"type":"array","items":{"type":"string"},"description":"Replaces the agent's attached external tools for the run with\nexactly this set. Each entry is a prefixed `tool_`\nid; `builtin_` ids are rejected. An empty array runs with no\ntools; omit the field to keep the agent's attachments."}},"description":"A run-level config override applied to every test in a Run All.\nLayered on top of the agent's stored config for the duration of\nthe suite run, so the whole suite can be validated against a\nproposed prompt / model / toolbelt without editing any test. An\nabsent field leaves the agent's value untouched; a run-level\noverride wins over a deprecated per-test `system_prompt_override`\n/ `model_override`.","title":"TestRunConfigOverride"},"tts:RunAllTestsRequest":{"type":"object","properties":{"config_override":{"$ref":"#/components/schemas/tts:TestRunConfigOverride"},"flow_version_id":{"type":"string","description":"Targets a specific flow version (an `agent_versions` row)\ninstead of the agent's active flow \u2014 version-targeted\nregression. Must be a flow version of the agent under test.\nRaw UUID; flow versions carry no prefixed wire id."}},"description":"Optional body of `POST /v1/agents/{id}/tests/runs`. Omit it\nentirely to run every test against the agent's live config and\nactive flow.","title":"RunAllTestsRequest"},"tts:SuiteRunTrigger":{"type":"string","enum":["run_all","batch","resubmit"],"description":"Which entry point created a suite run.\n- `run_all` - POST /v1/agents/{id}/tests/runs.\n- `batch` - POST /v1/agents/tests/runs/batch.\n- `resubmit` - POST /v1/agents/tests/suite-runs/{id}/resubmit.\n","title":"SuiteRunTrigger"},"tts:AgentTestSuiteRun":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`srun_<26 char Crockford base32>`)."},"agent_id":{"type":["string","null"],"description":"Prefixed `agent_` id of the agent whose suite\nwas run. Set for the `run_all` trigger; null for `batch`,\nwhich can span many agents.\n"},"trigger":{"$ref":"#/components/schemas/tts:SuiteRunTrigger"},"parent_suite_run_id":{"type":["string","null"],"description":"Set on a `resubmit`: the prefixed `srun_` id of\nthe suite run whose failed/errored tests this one re-ran.\nNull for `run_all` and `batch`.\n"},"status":{"$ref":"#/components/schemas/tts:TestRunStatus"},"total_runs":{"type":"integer","description":"Number of child runs in the suite."},"passed_count":{"type":"integer"},"failed_count":{"type":"integer"},"errored_count":{"type":"integer"},"pending_count":{"type":"integer","description":"Child runs still queued or running."},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time","description":"Newest child-run completion; null until every child run is terminal."},"config_override":{"oneOf":[{"$ref":"#/components/schemas/tts:TestRunConfigOverride"},{"type":"null"}],"description":"The run-level config override (AIS-3443) this suite was run\nwith, or null for an ordinary Run All / batch."},"flow_version_id":{"type":["string","null"],"description":"The flow version (`agent_versions` row) this suite targeted,\nor null for the agent's active / synthesized flow."},"flow_version_number":{"type":["integer","null"],"description":"Human-facing version number of `flow_version_id`; null when no version was targeted."}},"required":["id","trigger","status","total_runs","passed_count","failed_count","errored_count","pending_count","created_at"],"description":"A suite run (test invocation): the grouping object over every\ntest run dispatched by one Run All, batch, or resubmit call.\n`status` and the count fields are derived from the child runs.\n`status` is `running` while any child run is still queued or\nrunning, then `passed` (all passed), `failed` (at least one\nfailed), or `error` (at least one errored, none failed).","title":"AgentTestSuiteRun"},"tts:RunAgentTestsResponse":{"type":"object","properties":{"runs":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestRun"}},"suite_run":{"oneOf":[{"$ref":"#/components/schemas/tts:AgentTestSuiteRun"},{"type":"null"}],"description":"The suite run grouping the queued runs."}},"required":["runs"],"description":"Response from `POST /v1/agents/{id}/tests/runs` and the suite-run\nresubmit endpoint. Contains every newly-queued run so the client\ncan poll each for completion, plus the `suite_run` that groups\nthem. `suite_run` is null only when a Run All found no tests.","title":"RunAgentTestsResponse"},"tts:ToolKind":{"type":"string","enum":["system","webhook","client","mcp"],"description":"Where the tool executes.\n- `system`: worker-resident built-in (e.g. end_call, play_audio)\n- `webhook`: worker signs a payload and POSTs it to your URL\n- `client`: worker dispatches to the caller's browser/SDK via data channel\n- `mcp`: worker connects to a customer-hosted MCP server and proxies tool calls (AIS-3056)\n","title":"ToolKind"},"tts:ToolParamType":{"type":"string","enum":["string","number","integer","boolean"],"description":"Permitted JSON-Schema primitive types for tool params.","title":"ToolParamType"},"tts:ToolParam":{"type":"object","properties":{"name":{"type":"string"},"type":{"$ref":"#/components/schemas/tts:ToolParamType"},"description":{"type":"string"},"required":{"type":"boolean"},"enum":{"type":"array","items":{"type":"string"}}},"required":["name","type","description","required"],"description":"One argument the LLM can pass when calling the tool. Mirrors the JSON-Schema subset standard function-calling schemas support.","title":"ToolParam"},"tts:SystemToolConfig":{"type":"object","properties":{"builtin":{"$ref":"#/components/schemas/tts:SystemBuiltin"},"params":{"type":"array","items":{"$ref":"#/components/schemas/tts:ToolParam"}},"builtin_config":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-builtin extras (e.g. allowed_numbers for transfer_to_number)."}},"required":["builtin"],"description":"Config shape for `kind=system`. The `builtin` value names the\nworker-resident capability; the catalogue served by\n`GET /v1/agents/tools/system-builtins` is the runtime source of truth\nfor valid names plus their console-facing labels.\n","title":"SystemToolConfig"},"tts:WebhookToolConfigMethod":{"type":"string","enum":["POST","GET"],"title":"WebhookToolConfigMethod"},"tts:WebhookToolConfig":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"method":{"$ref":"#/components/schemas/tts:WebhookToolConfigMethod"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Static headers sent with every call. `Authorization` and `X-Speechify-Signature` are reserved."},"timeout_ms":{"type":"integer","description":"Per-call timeout in milliseconds. Defaults to 10000 server-side when omitted."},"params":{"type":"array","items":{"$ref":"#/components/schemas/tts:ToolParam"}},"fire_and_forget":{"type":"boolean","description":"When true the worker dispatches the HTTP request and returns\nimmediately to the LLM with a synthetic \"queued\" result\ninstead of waiting for the response body. The customer's\nendpoint is expected to enqueue the work and return any\nnon-error status quickly; errors raised after dispatch are\nlogged but never surfaced to the LLM. Use for long-running\ncustomer-side work (job triggers, async ticket creation,\netc.) where blocking the call on the response would hurt\nthe conversation. Defaults to false.\n"}},"required":["url"],"description":"Config shape for `kind=webhook`.","title":"WebhookToolConfig"},"tts:ClientToolConfig":{"type":"object","properties":{"params":{"type":"array","items":{"$ref":"#/components/schemas/tts:ToolParam"}},"timeout_ms":{"type":"integer","description":"Per-call timeout in milliseconds. Defaults to 10000 server-side when omitted."}},"description":"Config shape for `kind=client`. Execution happens in the caller's browser / SDK.","title":"ClientToolConfig"},"tts:MCPTransport":{"type":"string","enum":["http_streamable","sse"],"description":"MCP transport. `http_streamable` is the default; `sse` is the\nlegacy fallback for servers that haven't migrated yet.\n","title":"MCPTransport"},"tts:MCPAuth":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["none"],"description":"Discriminator value: none"}},"required":["type"],"description":"none variant"},{"type":"object","properties":{"type":{"type":"string","enum":["bearer"],"description":"Discriminator value: bearer"},"token":{"type":"string","description":"Bearer token. Write-only \u2014 never echoed back on reads."},"token_set":{"type":"boolean","description":"True when a bearer token is configured. Read-only."}},"required":["type"],"description":"bearer variant"},{"type":"object","properties":{"type":{"type":"string","enum":["oauth2_client_credentials"],"description":"Discriminator value: oauth2_client_credentials"},"token_url":{"type":"string","format":"uri"},"client_id":{"type":"string"},"client_secret":{"type":"string","description":"OAuth2 client_secret. Write-only \u2014 never echoed back on reads."},"client_secret_set":{"type":"boolean","description":"True when a client_secret is configured. Read-only."},"scope":{"type":"string","description":"Optional scope claim sent on the token request."}},"required":["type","token_url","client_id"],"description":"oauth2_client_credentials variant"}],"discriminator":{"propertyName":"type"},"description":"Discriminated union over `type`.","title":"MCPAuth"},"tts:MCPToolConfig":{"type":"object","properties":{"endpoint":{"type":"string","format":"uri"},"transport":{"$ref":"#/components/schemas/tts:MCPTransport"},"auth":{"$ref":"#/components/schemas/tts:MCPAuth"}},"required":["endpoint","auth"],"description":"Config shape for `kind=mcp` (AIS-3056). The worker opens the\nconfigured transport at session start, runs `initialize` +\n`list_tools`, and registers each discovered remote tool as a\nlivekit-agents function_tool proxying through the long-lived\nClientSession.\n","title":"MCPToolConfig"},"tts:ToolConfig":{"oneOf":[{"$ref":"#/components/schemas/tts:SystemToolConfig"},{"$ref":"#/components/schemas/tts:WebhookToolConfig"},{"$ref":"#/components/schemas/tts:ClientToolConfig"},{"$ref":"#/components/schemas/tts:MCPToolConfig"}],"description":"One of `SystemToolConfig`, `WebhookToolConfig`, `ClientToolConfig`, or `MCPToolConfig` depending on `kind`.","title":"ToolConfig"},"tts:Tool":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`tool_<26 char Crockford base32>`).\nADR 0015 Cluster 1 hard-break.\n"},"name":{"type":"string"},"description":{"type":"string"},"kind":{"$ref":"#/components/schemas/tts:ToolKind"},"config":{"$ref":"#/components/schemas/tts:ToolConfig","description":"One of `SystemToolConfig`, `WebhookToolConfig`, `ClientToolConfig`, or `MCPToolConfig` depending on `kind`."},"webhook_secret":{"type":"string","description":"HMAC signing secret for `kind=webhook`. Returned in full **only** on the create\nresponse; all subsequent reads return a masked placeholder. Store it on first\ncreate \u2014 there is no way to retrieve it later.\n"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","description","kind","config","created_at","updated_at"],"title":"Tool"},"tts:AttachedToolsResponse":{"type":"object","properties":{"tools":{"type":"array","items":{"$ref":"#/components/schemas/tts:Tool"}}},"required":["tools"],"description":"Bare list of the tools attached to an agent. Not paginated \u2014\nan agent's tool attachment count is bounded by configuration,\nnot by data scale. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the \"pagination only where needed\" rule.\n","title":"AttachedToolsResponse"},"tts:ListConversationsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"conversations":{"type":"array","items":{"$ref":"#/components/schemas/tts:Conversation"}}},"required":["next_cursor","has_more","conversations"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListConversationsResponse"},"tts:MessageRole":{"type":"string","enum":["user","assistant","system","tool"],"title":"MessageRole"},"tts:Message":{"type":"object","properties":{"id":{"type":"string"},"conversation_id":{"type":"string","description":"Prefixed wire identifier (`conv_<26 char Crockford base32>`)\nof the parent conversation. ADR 0015 FK consistency.\n"},"role":{"$ref":"#/components/schemas/tts:MessageRole"},"content":{"type":"string"},"tool_name":{"type":["string","null"]},"tool_args":{"type":["object","null"],"additionalProperties":{"description":"Any type"}},"tool_result":{"description":"Arbitrary JSON value returned by the tool (object, array, string, or primitive)."},"started_at":{"type":"string","format":"date-time"},"ended_at":{"type":["string","null"],"format":"date-time"}},"required":["id","conversation_id","role","content","started_at"],"title":"Message"},"tts:ListMessagesResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"messages":{"type":"array","items":{"$ref":"#/components/schemas/tts:Message"}}},"required":["next_cursor","has_more","messages"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListMessagesResponse"},"tts:EvaluationKind":{"type":"string","enum":["criterion","summary","data"],"title":"EvaluationKind"},"tts:EvaluationStatus":{"type":"string","enum":["success","failure","unknown"],"description":"Three-state criterion result. `unknown` means the criterion did not apply to this call.","title":"EvaluationStatus"},"tts:Evaluation":{"type":"object","properties":{"id":{"type":"string"},"conversation_id":{"type":"string","description":"Prefixed wire identifier (`conv_<26 char Crockford base32>`)\nof the conversation this evaluation is attached to. ADR 0015\nFK consistency.\n"},"kind":{"$ref":"#/components/schemas/tts:EvaluationKind"},"criterion_id":{"type":["string","null"]},"name":{"type":"string"},"status":{"oneOf":[{"$ref":"#/components/schemas/tts:EvaluationStatus"},{"type":"null"}],"description":"Three-state criterion result. `unknown` means the criterion did not apply to this call."},"passed":{"type":["boolean","null"]},"score":{"type":["number","null"],"format":"double"},"rationale":{"type":"string"},"data":{"description":"Structured data-collection payload (present only on `kind=data` rows)."},"created_at":{"type":"string","format":"date-time"}},"required":["id","conversation_id","kind","name","rationale","created_at"],"description":"Three flavours coexist, discriminated by `kind`:\n- `criterion` rows carry `status` + `passed` + `score` + `rationale` for one criterion\n- `summary` row carries overall sentiment + rationale in `rationale`\n- `data` row carries the structured data-collection payload in `data`\n\n`status` is the canonical three-state result. `passed` is a\nderived boolean kept for backwards compatibility with earlier\nwebhook consumers: success\u2192true, failure\u2192false, unknown\u2192null.\n","title":"Evaluation"},"tts:ListEvaluationsResponse":{"type":"object","properties":{"evaluations":{"type":"array","items":{"$ref":"#/components/schemas/tts:Evaluation"}}},"required":["evaluations"],"title":"ListEvaluationsResponse"},"tts:ConversationStats":{"type":"object","properties":{"total":{"type":"integer","format":"int64"},"completed":{"type":"integer","format":"int64"},"failed":{"type":"integer","format":"int64"},"active":{"type":"integer","format":"int64"},"pending":{"type":"integer","format":"int64"},"avg_duration_ms":{"type":["number","null"],"format":"double"},"avg_cost_cents":{"type":["number","null"],"format":"double"}},"required":["total","completed","failed","active","pending","avg_duration_ms","avg_cost_cents"],"description":"Counts + averages over the caller's conversations matching the supplied filters. AVG fields are null when no rows match the FILTER predicate.","title":"ConversationStats"},"tts:RecentCallee":{"type":"object","properties":{"phone":{"type":"string","description":"E.164 phone number that was dialled."},"last_called_at":{"type":"string","format":"date-time","description":"Timestamp of the most recent outbound call to this number."}},"required":["phone","last_called_at"],"description":"One distinct phone number this workspace has dialled, with the timestamp of the most recent outbound call to it.","title":"RecentCallee"},"tts:ListRecentCalleesResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"callees":{"type":"array","items":{"$ref":"#/components/schemas/tts:RecentCallee"}}},"required":["next_cursor","has_more","callees"],"description":"Payload for GET /v1/agents/conversations/recent-callees.","title":"ListRecentCalleesResponse"},"tts:WebhookDeliveryStatus":{"type":"string","enum":["pending","delivered","failed"],"description":"Lifecycle of a post-call webhook delivery row. The sender\nupdates the same row across retries so the UI always sees the\nlatest outcome.\n","title":"WebhookDeliveryStatus"},"tts:WebhookDelivery":{"type":"object","properties":{"id":{"type":"string"},"conversation_id":{"type":"string","description":"Prefixed wire identifier (`conv_<26 char Crockford base32>`)\nof the conversation that triggered this delivery. ADR 0015\nFK consistency.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the agent. ADR 0015 FK consistency.\n"},"url":{"type":"string"},"event":{"type":"string"},"status":{"$ref":"#/components/schemas/tts:WebhookDeliveryStatus"},"attempt_count":{"type":"integer"},"last_attempt_at":{"type":"string","format":"date-time"},"last_status_code":{"type":"integer"},"last_error":{"type":"string"},"created_at":{"type":"string","format":"date-time"}},"required":["id","conversation_id","agent_id","url","event","status","attempt_count","created_at"],"description":"Post-call webhook delivery log row. One row per\n`(conversation, webhook-url)`; updated in place across retry\nattempts.\n","title":"WebhookDelivery"},"tts:ListWebhookDeliveriesResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/tts:WebhookDelivery"}}},"required":["next_cursor","has_more","deliveries"],"description":"Payload for `GET /v1/agents/conversations/{id}/webhook-deliveries`.","title":"ListWebhookDeliveriesResponse"},"tts:RetrievalLogResult":{"type":"object","properties":{"chunk_id":{"type":"string"},"document_id":{"type":"string"},"kb_id":{"type":"string","description":"Prefixed wire identifier (`kb_<26 char Crockford base32>`)\nof the knowledge base the matched chunk lives in. ADR 0015\nFK consistency.\n"},"filename":{"type":"string"},"chunk_index":{"type":"integer"},"content":{"type":"string"},"score":{"type":"number","format":"double"}},"required":["chunk_id","document_id","kb_id","filename","chunk_index","content","score"],"description":"One ranked chunk inside a retrieval log row. Mirrors\n`RetrievalLogResult` in apps/server/internal/kb/types.go \u2014\ndenormalised so deleting a chunk or document after the call\ndoesn't render historical logs unreadable.\n","title":"RetrievalLogResult"},"tts:RetrievalLogEntry":{"type":"object","properties":{"id":{"type":"string"},"conversation_id":{"type":"string","description":"Prefixed wire identifier (`conv_<26 char Crockford base32>`)\nof the conversation. ADR 0015 FK consistency.\n"},"query":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/tts:RetrievalLogResult"}},"top_k":{"type":"integer"},"hit_count":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}},"required":["id","conversation_id","query","results","top_k","hit_count","created_at"],"description":"One `search_knowledge` invocation recorded against a\nconversation. Powers the Retrieval panel on the conversation\ndetail view.\n","title":"RetrievalLogEntry"},"tts:ListRetrievalLogsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"entries":{"type":"array","items":{"$ref":"#/components/schemas/tts:RetrievalLogEntry"}}},"required":["next_cursor","has_more","entries"],"description":"Payload for `GET /v1/agents/conversations/{id}/retrieval-log`.","title":"ListRetrievalLogsResponse"},"tts:CreateKnowledgeBaseRequest":{"type":"object","properties":{"name":{"type":"string","description":"Human-readable label."},"description":{"type":"string","description":"Optional description."}},"required":["name"],"title":"CreateKnowledgeBaseRequest"},"tts:ListKnowledgeBasesResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"knowledge_bases":{"type":"array","items":{"$ref":"#/components/schemas/tts:KnowledgeBase"}}},"required":["next_cursor","has_more","knowledge_bases"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListKnowledgeBasesResponse"},"tts:UpdateKnowledgeBaseRequest":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"}},"title":"UpdateKnowledgeBaseRequest"},"tts:KnowledgeBaseDocumentSourceKind":{"type":"string","enum":["file","url","text"],"description":"How the document entered the KB. `file` is the upload path,\n`text` is inline pasted content, `url` is fetched via\nFirecrawl. Sitemap and crawl imports also produce `url` rows.\n","title":"KnowledgeBaseDocumentSourceKind"},"tts:KnowledgeBaseDocumentStatus":{"type":"string","enum":["fetching","embedding","ready","failed"],"description":"Document lifecycle. `fetching` is the pre-scrape state used\nonly by url-sourced rows; file and text docs skip straight\nto `embedding` because their content is available\nsynchronously. Terminal states are `ready` and `failed`.\n","title":"KnowledgeBaseDocumentStatus"},"tts:KnowledgeBaseDocument":{"type":"object","properties":{"id":{"type":"string"},"kb_id":{"type":"string","description":"Prefixed wire identifier (`kb_<26 char Crockford base32>`) of\nthe knowledge base the document belongs to. ADR 0015 FK\nconsistency.\n"},"source_kind":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocumentSourceKind"},"source_url":{"type":"string","description":"Source URL for url-sourced documents (and the sitemap /\ncrawl imports that produce them). Empty string for file\nand text rows.\n"},"folder_id":{"type":["string","null"],"description":"Folder this document lives in. Null for root-level\n(unfiled) documents. Mutated via the move endpoint.\n"},"filename":{"type":"string"},"content_type":{"type":"string"},"byte_size":{"type":"integer","format":"int64"},"char_count":{"type":"integer"},"chunk_count":{"type":"integer"},"status":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocumentStatus"},"error":{"type":"string","description":"Populated when status is failed."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","kb_id","source_kind","folder_id","filename","content_type","byte_size","char_count","chunk_count","status","created_at","updated_at"],"title":"KnowledgeBaseDocument"},"tts:ListKnowledgeBaseDocumentsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"documents":{"type":"array","items":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocument"}}},"required":["next_cursor","has_more","documents"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListKnowledgeBaseDocumentsResponse"},"tts:DependentAgent":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"description":"Minimal agent pointer (id + name) used by the document\ndetail view to render a clickable link to each agent that\nhas the document's KB attached.\n","title":"DependentAgent"},"tts:RefreshConfig":{"type":"object","properties":{"enabled":{"type":"boolean"},"interval_days":{"type":"integer"},"auto_remove_enabled":{"type":"boolean"},"last_refreshed_at":{"type":["string","null"],"format":"date-time"},"consecutive_fetch_failures":{"type":"integer"}},"required":["enabled","interval_days","auto_remove_enabled","last_refreshed_at","consecutive_fetch_failures"],"description":"Per-document auto-refresh state (AIS-2656). Only populated\nfor url-sourced documents; file and text rows omit this and\nthe console's auto-refresh panel hides accordingly.\n","title":"RefreshConfig"},"tts:KnowledgeBaseDocumentDetail":{"type":"object","properties":{"id":{"type":"string"},"kb_id":{"type":"string","description":"Prefixed wire identifier (`kb_<26 char Crockford base32>`) of\nthe knowledge base the document belongs to. ADR 0015 FK\nconsistency.\n"},"source_kind":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocumentSourceKind"},"source_url":{"type":"string","description":"Source URL for url-sourced documents (and the sitemap /\ncrawl imports that produce them). Empty string for file\nand text rows.\n"},"folder_id":{"type":["string","null"],"description":"Folder this document lives in. Null for root-level\n(unfiled) documents. Mutated via the move endpoint.\n"},"filename":{"type":"string"},"content_type":{"type":"string"},"byte_size":{"type":"integer","format":"int64"},"char_count":{"type":"integer"},"chunk_count":{"type":"integer"},"status":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocumentStatus"},"error":{"type":"string","description":"Populated when status is failed."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"content_preview":{"type":"string"},"preview_truncated":{"type":"boolean"},"dependent_agents":{"type":"array","items":{"$ref":"#/components/schemas/tts:DependentAgent"}},"refresh":{"$ref":"#/components/schemas/tts:RefreshConfig"}},"required":["id","kb_id","source_kind","folder_id","filename","content_type","byte_size","char_count","chunk_count","status","created_at","updated_at","content_preview","preview_truncated","dependent_agents"],"description":"Payload of GET /v1/knowledge-bases/documents/{docId}. Extends\nthe list-view document with a bounded content preview, the\nlist of dependent agents, and (for url-sourced docs) the\nauto-refresh state.\n","title":"KnowledgeBaseDocumentDetail"},"tts:KnowledgeBaseChunk":{"type":"object","properties":{"id":{"type":"string"},"document_id":{"type":"string"},"kb_id":{"type":"string","description":"Prefixed wire identifier (`kb_<26 char Crockford base32>`) of\nthe knowledge base the chunk belongs to. ADR 0015 FK\nconsistency.\n"},"chunk_index":{"type":"integer"},"content":{"type":"string"}},"required":["id","document_id","kb_id","chunk_index","content"],"title":"KnowledgeBaseChunk"},"tts:ListKnowledgeBaseChunksResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"chunks":{"type":"array","items":{"$ref":"#/components/schemas/tts:KnowledgeBaseChunk"}}},"required":["next_cursor","has_more","chunks"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListKnowledgeBaseChunksResponse"},"tts:SearchKnowledgeBasesRequest":{"type":"object","properties":{"query":{"type":"string","description":"Natural-language search query."},"kb_ids":{"type":"array","items":{"type":"string"},"description":"Knowledge bases to search across. Results scoped to caller-owned entries; unknown IDs are silently ignored."},"top_k":{"type":"integer","default":5,"description":"Max hits to return (default 5, capped at 50)."}},"required":["query","kb_ids"],"title":"SearchKnowledgeBasesRequest"},"tts:KnowledgeBaseSearchHit":{"type":"object","properties":{"chunk_id":{"type":"string"},"document_id":{"type":"string"},"kb_id":{"type":"string"},"filename":{"type":"string"},"chunk_index":{"type":"integer"},"content":{"type":"string"},"score":{"type":"number","format":"double","description":"Cosine similarity (higher = more relevant)."}},"required":["chunk_id","document_id","kb_id","filename","chunk_index","content","score"],"title":"KnowledgeBaseSearchHit"},"tts:SearchKnowledgeBasesResponse":{"type":"object","properties":{"hits":{"type":"array","items":{"$ref":"#/components/schemas/tts:KnowledgeBaseSearchHit"}}},"required":["hits"],"title":"SearchKnowledgeBasesResponse"},"tts:CreateTextDocumentRequest":{"type":"object","properties":{"name":{"type":"string"},"content":{"type":"string"},"folder_id":{"type":["string","null"],"description":"Folder to drop the document into. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null/omitted = root.\n"}},"required":["name","content"],"description":"Body for POST /v1/knowledge-bases/{id}/documents/text.","title":"CreateTextDocumentRequest"},"tts:CreateURLDocumentRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"folder_id":{"type":["string","null"],"description":"Folder to drop the document into. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null/omitted = root.\n"}},"required":["url"],"description":"Body for POST /v1/knowledge-bases/{id}/documents/url.","title":"CreateURLDocumentRequest"},"tts:CreateSitemapImportRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"folder_id":{"type":["string","null"],"description":"Folder to import the documents into. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null/omitted = root.\n"}},"required":["url"],"title":"CreateSitemapImportRequest"},"tts:ImportJobKind":{"type":"string","enum":["sitemap","crawl","refresh","urls"],"title":"ImportJobKind"},"tts:ImportJobStatus":{"type":"string","enum":["pending","running","completed","failed","cancelled"],"description":"`pending` is the brief window between insert and the worker\npicking up; `running` is the bulk of the job's life;\n`completed` / `failed` / `cancelled` are terminal.\n","title":"ImportJobStatus"},"tts:ImportJob":{"type":"object","properties":{"id":{"type":"string"},"kb_id":{"type":"string"},"kind":{"$ref":"#/components/schemas/tts:ImportJobKind"},"status":{"$ref":"#/components/schemas/tts:ImportJobStatus"},"requested_count":{"type":"integer"},"completed_count":{"type":"integer"},"failed_count":{"type":"integer"},"params":{"type":"object","additionalProperties":{"description":"Any type"},"description":"JSON blob whose shape depends on `kind` \u2014 typically `url`,\n`max_pages`, `max_depth`. The console reads it for display\nonly.\n"},"error":{"type":"string"},"upstream_job_id":{"type":"string"},"created_by_uid":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"started_at":{"type":["string","null"],"format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"}},"required":["id","kb_id","kind","status","requested_count","completed_count","failed_count","params","created_by_uid","created_at","updated_at","started_at","finished_at"],"description":"Async URL import job (AIS-2655 sitemap, AIS-2657 crawl, plus\nthe auto-refresh path). The console polls\n`GET /v1/agents/knowledge-bases/{id}/imports` while the job is\nnon-terminal.\n","title":"ImportJob"},"tts:ImportJobResponse":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/tts:ImportJob"}},"required":["job"],"description":"Wrapper returned by the async import endpoints (sitemap, crawl, multi-URL).","title":"ImportJobResponse"},"tts:CreateCrawlImportRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"max_pages":{"type":"integer"},"max_depth":{"type":"integer"},"folder_id":{"type":["string","null"],"description":"Folder to import the documents into. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null/omitted = root.\n"}},"required":["url"],"title":"CreateCrawlImportRequest"},"tts:CreateURLBatchImportRequest":{"type":"object","properties":{"urls":{"type":"array","items":{"type":"string","format":"uri"}},"folder_id":{"type":["string","null"],"description":"Folder to import the documents into. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null/omitted = root.\n"}},"required":["urls"],"description":"Body for POST /v1/knowledge-bases/{id}/documents/urls. Submit\n1..N URLs in a single async import. The server dedupes and\nvalidates each entry before queueing. The per-import cap is\noperator-tunable (default 250) via kbUrlBatchMaxUrls; the\nserver returns 400 when the resolved list exceeds the cap, so\nno maxItems is encoded in the schema to avoid SDK-side false\nrejections when an operator raises the limit.\n","title":"CreateURLBatchImportRequest"},"tts:ListImportJobsResponse":{"type":"object","properties":{"jobs":{"type":"array","items":{"$ref":"#/components/schemas/tts:ImportJob"}}},"required":["jobs"],"title":"ListImportJobsResponse"},"tts:BatchDeleteDocumentsRequest":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"}}},"required":["ids"],"description":"Body for DELETE /v1/knowledge-bases/{id}/documents/batch. All\nids must belong to the supplied KB; capped at 200 ids per\ncall.\n","title":"BatchDeleteDocumentsRequest"},"tts:BatchMoveDocumentsRequest":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"}},"folder_id":{"type":["string","null"],"description":"Destination folder. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null moves every\ndocument to the knowledge base root.\n"}},"required":["ids","folder_id"],"description":"Body for PATCH /v1/knowledge-bases/{id}/documents/batch/move.\nCapped at 200 ids per call. Pass `folder_id: null` to move to\nroot.\n","title":"BatchMoveDocumentsRequest"},"tts:UpdateRefreshConfigRequest":{"type":"object","properties":{"enabled":{"type":"boolean"},"interval_days":{"type":"integer"},"auto_remove_enabled":{"type":"boolean"}},"description":"PATCH body \u2014 every field optional.","title":"UpdateRefreshConfigRequest"},"tts:RefreshHistoryEntryStatus":{"type":"string","enum":["running","changed","unchanged","failed","removed"],"title":"RefreshHistoryEntryStatus"},"tts:RefreshHistoryEntry":{"type":"object","properties":{"id":{"type":"string"},"document_id":{"type":"string"},"started_at":{"type":"string","format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"},"status":{"$ref":"#/components/schemas/tts:RefreshHistoryEntryStatus"},"error":{"type":"string"},"previous_hash":{"type":"string"},"new_hash":{"type":"string"}},"required":["id","document_id","started_at","finished_at","status"],"description":"One auto-refresh attempt. `running` only appears mid-tick;\nterminal values are the ones the drawer renders.\n","title":"RefreshHistoryEntry"},"tts:ListRefreshHistoryResponse":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/tts:RefreshHistoryEntry"}}},"required":["entries"],"title":"ListRefreshHistoryResponse"},"tts:KnowledgeBaseFolder":{"type":"object","properties":{"id":{"type":"string"},"kb_id":{"type":"string","description":"Prefixed wire identifier (`kb_<26 char Crockford base32>`) of\nthe owning knowledge base. ADR 0015 FK consistency.\n"},"parent_folder_id":{"type":["string","null"]},"name":{"type":"string"},"document_count":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","kb_id","parent_folder_id","name","document_count","created_at","updated_at"],"description":"Folder inside a knowledge base. Root-level folders have\n`parent_folder_id: null`. `document_count` is populated only\non the list endpoint.\n","title":"KnowledgeBaseFolder"},"tts:ListKnowledgeBaseFoldersResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"folders":{"type":"array","items":{"$ref":"#/components/schemas/tts:KnowledgeBaseFolder"}}},"required":["next_cursor","has_more","folders"],"description":"Flat list of folders for a knowledge base. The console builds\nthe folder tree from `parent_folder_id` references, so callers\nshould walk every page before rendering.\n","title":"ListKnowledgeBaseFoldersResponse"},"tts:CreateFolderRequest":{"type":"object","properties":{"name":{"type":"string"},"parent_folder_id":{"type":["string","null"],"description":"Parent folder. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null/omitted creates a\nroot-level folder.\n"}},"required":["name"],"title":"CreateFolderRequest"},"tts:UpdateFolderRequest":{"type":"object","properties":{"name":{"type":"string"},"parent_folder_id":{"type":"string","description":"Folder to reparent under. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`).\n"},"clear_parent_folder_id":{"type":"boolean","description":"When `true`, moves the folder to root (clears\n`parent_folder_id`). Wins over `parent_folder_id` when both\nare sent."}},"description":"PATCH body. All fields optional; omit to leave unchanged. Set\n`parent_folder_id` to reparent into that folder; send\n`clear_parent_folder_id: true` to move the folder to root. The\nclear flag is the explicit signal because JSON `null` is\nindistinguishable from absent for pointer fields in Go's\nencoding/json.\n","title":"UpdateFolderRequest"},"tts:ListTestsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"tests":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestWithLastRun"}}},"required":["next_cursor","has_more","tests"],"description":"Workspace-wide paginated list of tests. Walk pages while\n`has_more` is true; pass `next_cursor` back as the request\n`cursor` parameter.","title":"ListTestsResponse"},"tts:TestStatsBucket":{"type":"object","properties":{"day":{"type":"string","description":"ISO date (YYYY-MM-DD)."},"passed":{"type":"integer"},"failed":{"type":"integer"},"errored":{"type":"integer"}},"required":["day","passed","failed","errored"],"description":"One daily point on the aggregate pass-rate chart.","title":"TestStatsBucket"},"tts:TestStats":{"type":"object","properties":{"window_days":{"type":"integer"},"buckets":{"type":"array","items":{"$ref":"#/components/schemas/tts:TestStatsBucket"}},"total_runs":{"type":"integer"},"passed_runs":{"type":"integer"},"failed_runs":{"type":"integer"},"errored_runs":{"type":"integer"},"avg_duration_ms":{"type":"integer"},"by_type":{"type":"object","additionalProperties":{"type":"integer"}}},"required":["window_days","buckets","total_runs","passed_runs","failed_runs","errored_runs","avg_duration_ms"],"description":"Aggregate run metrics over the requested window. `buckets` is\ndense - one entry per day in the window, zero-filled, so a chart\nnever has gaps. `by_type` counts runs per test type across the\nwhole window.","title":"TestStats"},"tts:UpdateAgentTestRequestConfig":{"oneOf":[{"$ref":"#/components/schemas/tts:ReplyConfig"},{"$ref":"#/components/schemas/tts:ToolCallConfig"},{"$ref":"#/components/schemas/tts:SimulationConfig"}],"description":"Replaces the test config when present.","title":"UpdateAgentTestRequestConfig"},"tts:UpdateAgentTestRequest":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"config":{"$ref":"#/components/schemas/tts:UpdateAgentTestRequestConfig","description":"Replaces the test config when present."},"tool_mock_config":{"$ref":"#/components/schemas/tts:ToolMockConfig","description":"Replaces the tool-mock config when present."},"folder_id":{"type":"string","description":"Prefixed wire identifier (`folder_<26 char Crockford base32>`)\nof the folder to move the test into.\n"},"clear_folder_id":{"type":"boolean","description":"When `true`, moves the test back to root (clears\n`folder_id`). Wins over `folder_id` when both are sent."}},"description":"Payload for `PATCH /v1/agents/tests/{id}`. All fields are optional;\nomitting a field leaves it unchanged. Set `folder_id` to a target\nfolder id to move the test into that folder; send\n`clear_folder_id: true` (folder_id omitted or ignored) to move\nthe test back to root. The clear flag is the explicit signal\nbecause JSON `null` is indistinguishable from absent for\npointer fields in Go's encoding/json.","title":"UpdateAgentTestRequest"},"tts:AgentTestAttachment":{"type":"object","properties":{"test_id":{"type":"string","description":"Prefixed wire identifier (`test_<26 char Crockford base32>`)\nof the attached test. ADR 0015 FK consistency.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the attached agent. ADR 0015 FK consistency.\n"},"created_at":{"type":"string","format":"date-time"}},"required":["test_id","agent_id","created_at"],"description":"One (test, agent) pair. Poll the `attached_agent_ids` field on `AgentTestWithLastRun` or hit `/v1/agents/tests/{id}/attachments` for the authoritative set.","title":"AgentTestAttachment"},"tts:ListAgentTestAttachmentsResponse":{"type":"object","properties":{"attachments":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestAttachment"}}},"required":["attachments"],"title":"ListAgentTestAttachmentsResponse"},"tts:AgentTestFolder":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`folder_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"parent_folder_id":{"type":["string","null"],"description":"When set, prefixed wire identifier\n(`folder_<26 char Crockford base32>`) of the parent folder.\nNull means root. ADR 0015 FK consistency.\n"},"name":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","created_at","updated_at"],"description":"One organisational node in the per-owner tests tree.","title":"AgentTestFolder"},"tts:ListAgentTestFoldersResponse":{"type":"object","properties":{"folders":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestFolder"}}},"required":["folders"],"title":"ListAgentTestFoldersResponse"},"tts:CreateAgentTestFolderRequest":{"type":"object","properties":{"name":{"type":"string"},"parent_folder_id":{"type":["string","null"],"description":"Prefixed wire identifier (`folder_<26 char Crockford base32>`)\nof the parent folder. Omit / null for a root-level folder.\n"}},"required":["name"],"title":"CreateAgentTestFolderRequest"},"tts:UpdateAgentTestFolderRequest":{"type":"object","properties":{"name":{"type":"string"},"parent_folder_id":{"type":"string","description":"Prefixed wire identifier (`folder_<26 char Crockford base32>`)\nof the folder to reparent this folder under.\n"},"clear_parent_folder_id":{"type":"boolean","description":"When `true`, reparents this folder to root (clears\n`parent_folder_id`). Wins over `parent_folder_id` when\nboth are sent."}},"description":"PATCH body. All fields optional; omit to leave unchanged. Set\n`parent_folder_id` to a target folder id to reparent into that\nfolder; send `clear_parent_folder_id: true` to reparent to\nroot. The clear flag is the explicit signal because JSON `null`\nis indistinguishable from absent for pointer fields in Go's\nencoding/json.","title":"UpdateAgentTestFolderRequest"},"tts:ListAgentTestRunsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"runs":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestRun"}}},"required":["next_cursor","has_more","runs"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListAgentTestRunsResponse"},"tts:BatchRunEntry":{"type":"object","properties":{"test_id":{"type":"string","description":"Prefixed wire identifier (`test_<26 char Crockford base32>`)\nof the test to run.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the agent to run the test against. Omit to fan out to\nevery agent the test is attached to.\n"}},"required":["test_id"],"description":"One entry in a batch-run request. Omit `agent_id` to fan out to\nevery agent the test is attached to.","title":"BatchRunEntry"},"tts:RunBatchRequest":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/tts:BatchRunEntry"}}},"required":["entries"],"description":"Batch-run payload. Total expanded runs across all entries are\ncapped at 100 per call.","title":"RunBatchRequest"},"tts:RunBatchResponse":{"type":"object","properties":{"runs":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestRun"}},"suite_run":{"oneOf":[{"$ref":"#/components/schemas/tts:AgentTestSuiteRun"},{"type":"null"}],"description":"The suite run grouping the queued runs."}},"required":["runs"],"title":"RunBatchResponse"},"tts:ListSuiteRunsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"suite_runs":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestSuiteRun"}}},"required":["next_cursor","has_more","suite_runs"],"description":"One page of suite runs, newest first. Walk pages while\n`has_more` is true; pass `next_cursor` back as the request\n`cursor` parameter.","title":"ListSuiteRunsResponse"},"tts:SuiteChildRun":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`run_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"test_id":{"type":"string","description":"Prefixed wire identifier (`test_<26 char Crockford base32>`)\nof the parent test. ADR 0015 FK consistency.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the agent this run executed against. ADR 0015 FK\nconsistency.\n"},"status":{"$ref":"#/components/schemas/tts:TestRunStatus"},"started_at":{"type":["string","null"],"format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"},"result":{"oneOf":[{"$ref":"#/components/schemas/tts:TestRunResult"},{"type":"null"}],"description":"Populated on terminal status only."},"error":{"type":"string","description":"Human-readable error message when status is `error`."},"created_at":{"type":"string","format":"date-time"},"test_name":{"type":"string","description":"Name of the test this run executed."}},"required":["id","test_id","agent_id","status","created_at","test_name"],"description":"One child run inside a suite run, carrying the parent test's\nname so the grouped result view can label each row.","title":"SuiteChildRun"},"tts:AgentTestSuiteRunWithRuns":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`srun_<26 char Crockford base32>`)."},"agent_id":{"type":["string","null"],"description":"Prefixed `agent_` id of the agent whose suite\nwas run. Set for the `run_all` trigger; null for `batch`,\nwhich can span many agents.\n"},"trigger":{"$ref":"#/components/schemas/tts:SuiteRunTrigger"},"parent_suite_run_id":{"type":["string","null"],"description":"Set on a `resubmit`: the prefixed `srun_` id of\nthe suite run whose failed/errored tests this one re-ran.\nNull for `run_all` and `batch`.\n"},"status":{"$ref":"#/components/schemas/tts:TestRunStatus"},"total_runs":{"type":"integer","description":"Number of child runs in the suite."},"passed_count":{"type":"integer"},"failed_count":{"type":"integer"},"errored_count":{"type":"integer"},"pending_count":{"type":"integer","description":"Child runs still queued or running."},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time","description":"Newest child-run completion; null until every child run is terminal."},"config_override":{"oneOf":[{"$ref":"#/components/schemas/tts:TestRunConfigOverride"},{"type":"null"}],"description":"The run-level config override (AIS-3443) this suite was run\nwith, or null for an ordinary Run All / batch."},"flow_version_id":{"type":["string","null"],"description":"The flow version (`agent_versions` row) this suite targeted,\nor null for the agent's active / synthesized flow."},"flow_version_number":{"type":["integer","null"],"description":"Human-facing version number of `flow_version_id`; null when no version was targeted."},"runs":{"type":"array","items":{"$ref":"#/components/schemas/tts:SuiteChildRun"}}},"required":["id","trigger","status","total_runs","passed_count","failed_count","errored_count","pending_count","created_at","runs"],"description":"A suite run plus every child run, for the grouped detail view.","title":"AgentTestSuiteRunWithRuns"},"tts:CreateToolRequestConfig":{"oneOf":[{"$ref":"#/components/schemas/tts:SystemToolConfig"},{"$ref":"#/components/schemas/tts:WebhookToolConfig"},{"$ref":"#/components/schemas/tts:ClientToolConfig"},{"$ref":"#/components/schemas/tts:MCPToolConfig"}],"title":"CreateToolRequestConfig"},"tts:CreateToolRequest":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"kind":{"$ref":"#/components/schemas/tts:ToolKind"},"config":{"$ref":"#/components/schemas/tts:CreateToolRequestConfig"}},"required":["name","description","kind","config"],"title":"CreateToolRequest"},"tts:ListToolsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"tools":{"type":"array","items":{"$ref":"#/components/schemas/tts:Tool"}}},"required":["next_cursor","has_more","tools"],"description":"Payload for `GET /v1/agents/tools` \u2014 the workspace-level tool\ncatalog. Cursor-paginated; the per-agent attached-tools endpoint\nuses a different (bare) shape \u2014 see AttachedToolsResponse.\n","title":"ListToolsResponse"},"tts:UpdateToolRequestConfig":{"oneOf":[{"$ref":"#/components/schemas/tts:SystemToolConfig"},{"$ref":"#/components/schemas/tts:WebhookToolConfig"},{"$ref":"#/components/schemas/tts:ClientToolConfig"},{"$ref":"#/components/schemas/tts:MCPToolConfig"}],"title":"UpdateToolRequestConfig"},"tts:UpdateToolRequest":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"config":{"$ref":"#/components/schemas/tts:UpdateToolRequestConfig"}},"description":"All fields optional. `kind` is immutable \u2014 create a new tool to change it.","title":"UpdateToolRequest"},"tts:SystemBuiltinInfo":{"type":"object","properties":{"name":{"$ref":"#/components/schemas/tts:SystemBuiltin"},"label":{"type":"string","description":"Console-facing display label for the builtin."},"description":{"type":"string","description":"Console-facing one-line summary of what the builtin does."}},"required":["name","label","description"],"description":"One entry in the system-builtin catalogue.","title":"SystemBuiltinInfo"},"tts:ListSystemBuiltinsResponse":{"type":"object","properties":{"builtins":{"type":"array","items":{"$ref":"#/components/schemas/tts:SystemBuiltinInfo"}}},"required":["builtins"],"title":"ListSystemBuiltinsResponse"},"tts:ToolAttachedAgent":{"type":"object","properties":{"id":{"type":"string","description":"Opaque agent ID."},"name":{"type":"string","description":"Human-readable agent name."}},"required":["id","name"],"description":"Minimal agent identity returned alongside a tool so the console\ncan render \"this tool is attached to: X, Y\" copy before a\ndestructive action runs (AIS-3347).\n","title":"ToolAttachedAgent"},"tts:ListToolAttachedAgentsResponse":{"type":"object","properties":{"agents":{"type":"array","items":{"$ref":"#/components/schemas/tts:ToolAttachedAgent"}}},"required":["agents"],"description":"Response shape for GET /v1/agents/tools/{id}/attached-agents.\nAgents are tenant-scoped and ordered by name ASC.\n","title":"ListToolAttachedAgentsResponse"},"tts:TestMCPConnectionRequest":{"type":"object","properties":{"config":{"$ref":"#/components/schemas/tts:MCPToolConfig"},"tool_id":{"type":"string","description":"Optional `tool_` id of the existing tool to hydrate\nstored secrets from. Raw UUIDs and other-resource prefixes are\nrejected.\n"}},"required":["config"],"description":"Body for `POST /v1/agents/tools/test-mcp-connection`. `config` is the\nsame MCPToolConfig shape `POST /v1/agents/tools` would persist; nothing\nis persisted by the probe itself. `tool_id` is only meaningful\nin the edit-form flow \u2014 when set, the server hydrates stored\nbearer / oauth2 secrets from the encrypted column before\nprobing, so customers can hit \"Test Connection\" on an existing\ntool without re-typing the secret.\n","title":"TestMCPConnectionRequest"},"tts:MCPProbeTool":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"}},"required":["name"],"description":"One discovered tool in a probe result.","title":"MCPProbeTool"},"tts:McpProbeErrorDetailsStage":{"type":"string","enum":["validation","oauth2_token","mcp_connect","mcp_initialize","mcp_notify","mcp_list_tools"],"title":"McpProbeErrorDetailsStage"},"tts:MCPProbeErrorDetails":{"type":"object","properties":{"stage":{"$ref":"#/components/schemas/tts:McpProbeErrorDetailsStage"},"http_status":{"type":"integer"},"oauth2_error":{"type":"string"},"oauth2_error_description":{"type":"string"},"upstream_body":{"type":"string"},"field_hint":{"type":"string"}},"description":"Structured upstream signal for an MCP probe failure. All fields\nare optional; the console renders what's present. `stage` names\nthe phase the probe was in (`validation`, `oauth2_token`,\n`mcp_connect`, `mcp_initialize`, `mcp_notify`, `mcp_list_tools`).\n`oauth2_error` / `oauth2_error_description` mirror RFC 6749 \u00a75.2\nwhen the customer's auth server returned the standard error\nshape. `http_status` is the upstream status code for transport\nfailures. `upstream_body` is a truncated prefix (max ~1 KiB) of\nthe upstream response body when the failure isn't structured.\n`field_hint` names a form field (`endpoint`, `transport`,\n`token`, `token_url`, `client_id`, `client_secret`, `scope`)\nthe console should highlight so the customer knows what to fix.\n","title":"MCPProbeErrorDetails"},"tts:MCPProbeResult":{"type":"object","properties":{"tools":{"type":["array","null"],"items":{"$ref":"#/components/schemas/tts:MCPProbeTool"}},"error":{"type":"string"},"details":{"$ref":"#/components/schemas/tts:MCPProbeErrorDetails"}},"required":["tools"],"description":"Result of an MCP probe. On success, `tools` is the discovered\ncatalogue and `error` is absent. On failure, `tools` is `null`\nand `error` carries a human-readable reason the console renders\ninline next to the form. `details` is optional structured\nsignal from the upstream (OAuth2 RFC 6749 fields, HTTP status,\ntruncated upstream body, form field hint) the console uses to\nexpand the inline banner and highlight the offending input.\nOlder consoles ignore `details` and fall back to `error`. Both\nvalidation and network failures land in `error` rather than\nnon-2xx responses, so consumers must check `error` before\nreading `tools`.\n","title":"MCPProbeResult"},"tts:TestWebhookConnectionRequest":{"type":"object","properties":{"config":{"$ref":"#/components/schemas/tts:WebhookToolConfig"},"tool_id":{"type":"string","description":"Optional `tool_` id of the existing tool to sign\nthe probe with. Raw UUIDs and other-resource prefixes are\nrejected.\n"}},"required":["config"],"description":"Body for `POST /v1/agents/tools/test-webhook-connection`.\n`config` is the same WebhookToolConfig shape `POST /v1/agents/tools`\nwould persist; nothing is persisted by the probe. `tool_id` is\nonly meaningful in the edit-form flow \u2014 when set, the server\nsigns the probe request with the tool's stored HMAC secret so\nthe test exercises the real signature path.\n","title":"TestWebhookConnectionRequest"},"tts:WebhookProbeResult":{"type":"object","properties":{"ok":{"type":"boolean"},"status_code":{"type":"integer","description":"HTTP status the endpoint returned. Absent on a transport failure."},"latency_ms":{"type":"integer","format":"int64","description":"Wall-clock round-trip time in milliseconds."},"response_body":{"type":"string","description":"Truncated prefix (max ~2 KiB) of the endpoint's response body."},"signed":{"type":"boolean","description":"Whether the probe request carried an HMAC signature header."},"error":{"type":"string","description":"Human-readable transport-level failure reason. Absent when any response was received."}},"required":["ok","signed"],"description":"Result of a webhook probe. `ok` is true only when the endpoint\nreturned a 2xx. A non-2xx response still populates `status_code`\nand `response_body` with `ok=false` \u2014 the request reached the\nendpoint, the endpoint just declined it. `error` is set only for\ntransport-level failures (DNS, connect, TLS, timeout, blocked\naddress range) where no response was received; `status_code` is\nabsent in that case. `signed` reports whether the probe carried\nan `X-Speechify-Signature` header \u2014 false on the create-form\nflow, which has no stored secret yet. Both success and failure\nuse the 200 envelope so the console renders them inline.\n","title":"WebhookProbeResult"},"tts:Caller":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`caller_<26 char Crockford base32>`).\nADR 0015 Cluster 2 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 2.\n"},"tenant_id":{"type":"string","description":"Prefixed wire identifier (`ws_<26 char Crockford base32>`) of\nthe owning workspace. ADR 0015 FK consistency.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the agent the caller is scoped under. ADR 0015 FK\nconsistency.\n"},"identity":{"type":"string","description":"The raw identifier the caller arrived with (E.164 phone for SIP, LiveKit\nparticipant id for web). Stable for the life of the caller row.\n"},"display_name":{"type":["string","null"],"description":"Operator-editable display name, nullable."},"external_ref":{"type":["string","null"],"description":"Optional handle into the customer's own CRM, nullable."},"metadata":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Customer-supplied JSON metadata blob."},"first_seen_at":{"type":"string","format":"date-time","description":"Timestamp of the earliest observed conversation / memory for this caller."},"last_seen_at":{"type":"string","format":"date-time","description":"Timestamp of the most recent observation. Drives the default list ordering."},"conversation_count":{"type":"integer","description":"Number of conversation rows currently pointing at this caller."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","tenant_id","agent_id","identity","metadata","first_seen_at","last_seen_at","conversation_count","created_at","updated_at"],"description":"First-class Caller entity (Phase 2 of ADR 0011). Identified by\nthe (tenant, agent, identity) triple. Memories and conversations\nFK at it via `caller_id`.\n","title":"Caller"},"tts:ListCallersResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"callers":{"type":"array","items":{"$ref":"#/components/schemas/tts:Caller"}}},"required":["next_cursor","has_more","callers"],"description":"Payload for GET /v1/agents/callers.","title":"ListCallersResponse"},"tts:GetCallerResponse":{"type":"object","properties":{"caller":{"$ref":"#/components/schemas/tts:Caller"}},"required":["caller"],"description":"Single-resource envelope used by GET / PATCH /v1/agents/callers/{id}.","title":"GetCallerResponse"},"tts:DeleteCallerResponse":{"type":"object","properties":{"caller_purged":{"type":"integer","description":"1 on the first delete; 0 on idempotent re-delete."},"memories_purged":{"type":"integer","description":"Number of user_memories rows cascade-soft-deleted under this caller."}},"required":["caller_purged","memories_purged"],"description":"Audit envelope returned by DELETE /v1/agents/callers/{id}. Surfaces\nthe cascade row counts so a privacy operator has direct evidence\nof the purge without re-querying.\n","title":"DeleteCallerResponse"},"tts:UpdateCallerRequest":{"type":"object","properties":{"display_name":{"type":["string","null"],"description":"Operator-editable display name. Empty string clears the column."},"external_ref":{"type":["string","null"],"description":"Optional handle into the customer's own CRM. Empty string clears the column."},"metadata":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Replacement metadata JSONB. Must not be `null`."}},"description":"PATCH payload. Omitted fields are unchanged; present fields\noverwrite. Empty string clears nullable text columns; `metadata`\nreplaces the JSONB blob in full when supplied.\n","title":"UpdateCallerRequest"},"tts:CallerMemoryItem":{"type":"object","properties":{"id":{"type":"string"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the owning agent. ADR 0015 FK consistency.\n"},"caller_identity":{"type":"string"},"fact":{"type":"string"},"source_conversation_id":{"type":["string","null"],"description":"When set, the prefixed wire identifier\n(`conv_<26 char Crockford base32>`) of the conversation this\nmemory was extracted from. ADR 0015 FK consistency.\n"},"confidence":{"type":"number","format":"double"},"created_at":{"type":"string","format":"date-time"}},"required":["id","agent_id","caller_identity","fact","confidence","created_at"],"description":"Memory projection returned by the per-caller memories list. Mirrors\nthe legacy `/v1/agents/{id}/memories` shape so console code can\nre-use existing renderers.\n","title":"CallerMemoryItem"},"tts:ListCallerMemoriesResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"memories":{"type":"array","items":{"$ref":"#/components/schemas/tts:CallerMemoryItem"}}},"required":["next_cursor","has_more","memories"],"description":"Payload for GET /v1/agents/callers/{id}/memories.","title":"ListCallerMemoriesResponse"},"tts:ListCallerConversationsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"conversations":{"type":"array","items":{"$ref":"#/components/schemas/tts:Conversation"}}},"required":["next_cursor","has_more","conversations"],"description":"Payload for GET /v1/agents/callers/{id}/conversations.","title":"ListCallerConversationsResponse"},"tts:AudioAsset":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`audio_<26 char Crockford base32>`).\nADR 0015 Cluster 2 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 2.\n"},"original_filename":{"type":"string","description":"The filename supplied at upload time, kept for display."},"content_type":{"type":"string","description":"Always `audio/wav`. Pinned server-side after WAV validation\nrather than trusting the upload's multipart Content-Type\nheader.\n"},"size_bytes":{"type":"integer","description":"Stored byte length. Capped at 4 MiB at upload time."},"duration_ms":{"type":"integer","description":"Clip duration in milliseconds. Capped at 30000 (30s) at upload time."},"sample_rate_hz":{"type":"integer","description":"WAV sample rate. Always 48000 (matches the LiveKit room rate)."},"channels":{"type":"integer","description":"Channel count. Always 1 (mono)."},"bit_depth":{"type":"integer","description":"PCM sample bit depth. Always 16."},"created_at":{"type":"string","format":"date-time"}},"required":["id","original_filename","content_type","size_bytes","duration_ms","sample_rate_hz","channels","bit_depth","created_at"],"description":"Metadata for a pre-recorded WAV clip stored in the workspace's\naudio-asset bucket. Bytes are immutable once uploaded \u2014 to\nreplace a clip, upload a new asset and update any references.\n","title":"AudioAsset"},"tts:ListAudioAssetsResponse":{"type":"object","properties":{"assets":{"type":"array","items":{"$ref":"#/components/schemas/tts:AudioAsset"}}},"required":["assets"],"title":"ListAudioAssetsResponse"},"tts:UploadAudioAssetResponse":{"type":"object","properties":{"asset":{"$ref":"#/components/schemas/tts:AudioAsset"}},"required":["asset"],"title":"UploadAudioAssetResponse"},"tts:FlowVersion":{"type":"object","properties":{"id":{"type":"string","description":"Flow version id. A raw UUID, not a prefixed external id."},"agent_id":{"type":"string"},"version":{"type":"integer","description":"Monotonic revision number within the agent."},"parent_version_id":{"type":["string","null"]},"is_active":{"type":"boolean"},"is_draft":{"type":"boolean"},"name":{"type":"string"},"notes":{"type":"string"},"published_by":{"type":"string"},"published_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","agent_id","version","is_active","is_draft"],"description":"One published or draft revision of an agent's flow graph.","title":"FlowVersion"},"tts:FlowGraphNodesItems":{"type":"object","properties":{},"title":"FlowGraphNodesItems"},"tts:FlowGraphEdgesItems":{"type":"object","properties":{},"title":"FlowGraphEdgesItems"},"tts:FlowGraphVariablesItems":{"type":"object","properties":{},"title":"FlowGraphVariablesItems"},"tts:FlowGraph":{"type":"object","properties":{"version":{"$ref":"#/components/schemas/tts:FlowVersion"},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowGraphNodesItems"}},"edges":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowGraphEdgesItems"}},"variables":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowGraphVariablesItems"}}},"required":["version","nodes","edges"],"description":"A flow graph: an ordered set of typed nodes connected by edges,\nplus flow variables. The node, edge, and variable shapes are\ngoverned by the live JSON Schema at GET /v1/agents/flow/schema\nand are intentionally opaque here so this spec cannot drift\nfrom that authoritative definition.\n","title":"FlowGraph"},"tts:GetFlowResponse":{"type":"object","properties":{"draft":{"$ref":"#/components/schemas/tts:FlowGraph"},"active":{"$ref":"#/components/schemas/tts:FlowGraph"},"history":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowVersion"}}},"required":["history"],"description":"Response for GET /v1/agents/{id}/flow.","title":"GetFlowResponse"},"tts:PutFlowRequestNodesItems":{"type":"object","properties":{},"title":"PutFlowRequestNodesItems"},"tts:PutFlowRequestEdgesItems":{"type":"object","properties":{},"title":"PutFlowRequestEdgesItems"},"tts:PutFlowRequestVariablesItems":{"type":"object","properties":{},"title":"PutFlowRequestVariablesItems"},"tts:PutFlowRequest":{"type":"object","properties":{"name":{"type":"string"},"notes":{"type":"string"},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/tts:PutFlowRequestNodesItems"}},"edges":{"type":"array","items":{"$ref":"#/components/schemas/tts:PutFlowRequestEdgesItems"}},"variables":{"type":"array","items":{"$ref":"#/components/schemas/tts:PutFlowRequestVariablesItems"}}},"required":["nodes","edges"],"description":"Request body for PUT /v1/agents/{id}/flow. Replaces the draft graph.","title":"PutFlowRequest"},"tts:PublishFlowRequest":{"type":"object","properties":{"notes":{"type":"string","description":"Optional changelog note recorded on the published version."}},"description":"Optional body for POST /v1/agents/{id}/flow/publish.","title":"PublishFlowRequest"},"tts:RollbackFlowRequest":{"type":"object","properties":{"version_id":{"type":"string","description":"The flow version to roll back to."}},"required":["version_id"],"title":"RollbackFlowRequest"},"tts:ListFlowVersionsResponse":{"type":"object","properties":{"versions":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowVersion"}}},"required":["versions"],"title":"ListFlowVersionsResponse"},"tts:GetFlowVersionResponse":{"type":"object","properties":{"graph":{"$ref":"#/components/schemas/tts:FlowGraph"}},"required":["graph"],"title":"GetFlowVersionResponse"},"tts:flow_getSchema_Response_200":{"type":"object","properties":{},"title":"flow_getSchema_Response_200"},"tts:FlowTemplate":{"type":"object","properties":{"id":{"type":"string","description":"Flow template id. A raw UUID, not a prefixed external id."},"key":{"type":"string","description":"Stable unique key for the template."},"name":{"type":"string"},"description":{"type":"string"},"category":{"type":"string"},"graph":{"$ref":"#/components/schemas/tts:FlowGraph"},"is_seed":{"type":"boolean","description":"True for platform-provided templates."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","key","name","category","graph","is_seed","created_at","updated_at"],"description":"A reusable flow graph that can be cloned onto an agent as a new draft.","title":"FlowTemplate"},"tts:ListFlowTemplatesResponse":{"type":"object","properties":{"templates":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowTemplate"}}},"required":["templates"],"title":"ListFlowTemplatesResponse"},"tts:FlowGraphInputNodesItems":{"type":"object","properties":{},"title":"FlowGraphInputNodesItems"},"tts:FlowGraphInputEdgesItems":{"type":"object","properties":{},"title":"FlowGraphInputEdgesItems"},"tts:FlowGraphInputVariablesItems":{"type":"object","properties":{},"title":"FlowGraphInputVariablesItems"},"tts:FlowGraphInput":{"type":"object","properties":{"nodes":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowGraphInputNodesItems"}},"edges":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowGraphInputEdgesItems"}},"variables":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowGraphInputVariablesItems"}}},"required":["nodes","edges"],"description":"Request-side flow graph: nodes, edges, and variables only.\nUnlike the response-side FlowGraph it carries no `version`\nblock - the server owns version metadata.\n","title":"FlowGraphInput"},"tts:CreateFlowTemplateRequest":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","description":"Defaults to \"custom\" when omitted."},"graph":{"$ref":"#/components/schemas/tts:FlowGraphInput"}},"required":["key","name","graph"],"description":"Request body for creating (POST) or replacing (PATCH) a flow\ntemplate. PATCH replaces the whole template, it is not a\nfield-by-field patch.\n","title":"CreateFlowTemplateRequest"},"tts:CloneFlowTemplateRequest":{"type":"object","properties":{"agent_id":{"type":"string","description":"The agent that receives the cloned graph as a new draft."}},"required":["agent_id"],"title":"CloneFlowTemplateRequest"},"tts:ShadowConversationResponse":{"type":"object","properties":{"conversation_id":{"type":"string"},"room_name":{"type":"string"},"livekit_url":{"type":"string","description":"wss://\u2026 signaling URL for the LiveKit project hosting the room."},"token":{"type":"string","description":"Short-lived LiveKit access token. Grant has CanPublish=false,\nCanPublishData=false, CanSubscribe=true, Hidden=true so the\nobserver can listen but cannot speak and is invisible to the\ncaller and the agent.\n"},"identity":{"type":"string","description":"Opaque participant identity tag (e.g. shadow_). Visible only to admin tooling."},"expires_at":{"type":"string","format":"date-time","description":"When the token stops being accepted by LiveKit. The console should re-mint past this point."}},"required":["conversation_id","room_name","livekit_url","token","identity","expires_at"],"description":"Connection details for an authorized observer (workspace owner or\nadmin) joining an active conversation as a hidden, listen-only\nparticipant. The livekit-client SDK consumes `livekit_url` +\n`token` to attach to the live room and play the agent + caller\naudio tracks.\n","title":"ShadowConversationResponse"},"tts:BatchRecipientRequest":{"type":"object","properties":{"phone":{"type":"string","description":"Recipient phone number in E.164 format."},"dynamic_vars":{"type":"object","additionalProperties":{"type":"string"},"description":"Per-recipient variable overrides injected into the agent prompt."}},"required":["phone"],"description":"One entry in a batch-call request.","title":"BatchRecipientRequest"},"tts:CreateBatchCallRequest":{"type":"object","properties":{"name":{"type":"string","description":"Human-readable batch name."},"agent_id":{"type":"string","description":"Agent that handles each call."},"phone_number_id":{"type":"string","description":"Caller-ID override. Falls back to the agent's bound number."},"scheduled_at":{"type":"string","format":"date-time","description":"Schedule the batch for a future time (RFC 3339). Omit to start immediately."},"ringing_timeout_ms":{"type":"integer","description":"Ringing timeout in milliseconds applied to every call in the\nbatch (how long each recipient rings before the dial gives\nup). Range 1000-80000 (1-80s). Omit to use the 30s default.\nThe console collects this in seconds and converts to\nmilliseconds.\n"},"recipients":{"type":"array","items":{"$ref":"#/components/schemas/tts:BatchRecipientRequest"}}},"required":["name","agent_id","recipients"],"description":"Body for `POST /v1/agents/batch-calls`. Also accepts `multipart/form-data`\nwith a CSV file upload (`csv_file` field) where the `phone` column is\nrequired and remaining columns become per-recipient `dynamic_vars`.\n","title":"CreateBatchCallRequest"},"tts:BatchCallStatus":{"type":"string","enum":["pending","scheduled","running","completed","failed","cancelled"],"title":"BatchCallStatus"},"tts:BatchCall":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`batch_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the agent that will run the batch. ADR 0015 FK consistency.\n"},"phone_number_id":{"type":["string","null"],"description":"Caller-ID override. When set, prefixed wire identifier\n(`phone_<26 char Crockford base32>`) of the phone number to\nuse; falls back to the agent's bound number when null. ADR\n0015 FK consistency.\n"},"name":{"type":"string","description":"Human-readable batch name."},"status":{"$ref":"#/components/schemas/tts:BatchCallStatus"},"total":{"type":"integer","description":"Total number of recipients."},"completed":{"type":"integer","description":"Recipients successfully dialed."},"failed":{"type":"integer","description":"Recipients that failed."},"error":{"type":"string","description":"Populated when the batch itself fails."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"started_at":{"type":["string","null"],"format":"date-time","description":"When the dispatcher started dialing."},"finished_at":{"type":["string","null"],"format":"date-time","description":"When the last recipient was resolved."},"scheduled_at":{"type":["string","null"],"format":"date-time","description":"If set, the batch waits until this time before dialing."},"ringing_timeout_ms":{"type":["integer","null"],"description":"Per-call ringing timeout in milliseconds applied to every\nrecipient in the batch. Null when the batch uses the 30s\ndefault.\n"}},"required":["id","agent_id","name","status","total","completed","failed","created_at","updated_at"],"description":"A batch of outbound calls dispatched to a list of recipients.","title":"BatchCall"},"tts:CreateBatchCallResponse":{"type":"object","properties":{"batch":{"$ref":"#/components/schemas/tts:BatchCall"}},"required":["batch"],"title":"CreateBatchCallResponse"},"tts:ListBatchCallsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"batches":{"type":"array","items":{"$ref":"#/components/schemas/tts:BatchCall"}}},"required":["next_cursor","has_more","batches"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListBatchCallsResponse"},"tts:BatchRecipientStatus":{"type":"string","enum":["pending","dialing","completed","failed"],"title":"BatchRecipientStatus"},"tts:BatchRecipient":{"type":"object","properties":{"id":{"type":"string"},"batch_id":{"type":"string","description":"Prefixed wire identifier (`batch_<26 char Crockford base32>`)\nof the parent batch. ADR 0015 FK consistency.\n"},"phone":{"type":"string","description":"Recipient phone number in E.164 format."},"dynamic_vars":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-recipient variable overrides injected into the agent prompt."},"status":{"$ref":"#/components/schemas/tts:BatchRecipientStatus"},"conversation_id":{"type":["string","null"],"description":"Set once the call is placed. Prefixed wire identifier\n(`conv_<26 char Crockford base32>`). ADR 0015 FK consistency.\n"},"error":{"type":"string","description":"Populated when this recipient fails."},"attempted_at":{"type":["string","null"],"format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"}},"required":["id","batch_id","phone","status"],"description":"One recipient row in a batch call.","title":"BatchRecipient"},"tts:GetBatchCallResponse":{"type":"object","properties":{"batch":{"$ref":"#/components/schemas/tts:BatchCall"},"recipients":{"type":"array","items":{"$ref":"#/components/schemas/tts:BatchRecipient"}}},"required":["batch","recipients"],"description":"Batch row plus all recipients for the detail view.","title":"GetBatchCallResponse"},"tts:CreateOutboundCallRequest":{"type":"object","properties":{"agent_id":{"type":"string","description":"ID of the agent that handles the answered call."},"to":{"type":"string","description":"Destination phone number in E.164 format (e.g. `+12025559876`)."},"caller_id_number":{"type":"string","description":"The number shown to the callee as caller ID, in E.164 format.\nDefaults to the first outbound-capable number in the workspace.\nUseful for multi-number campaigns where you want to rotate\ncaller IDs.\n"},"dtmf_prefix":{"type":"string","description":"DTMF digits dialed automatically after the call is answered,\nbefore the agent begins speaking. Use this for IVR navigation\n(e.g. `1ww2` presses 1, waits two seconds, presses 2). `w`\nis a half-second pause; `W` is a one-second pause.\n"},"dynamic_variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-call variable overrides merged on top of the agent's stored\ndefaults. Keys must not use the reserved `system__` prefix.\nUseful for injecting per-call context (customer name, order ID)\ninto the agent prompt.\n"},"ringing_timeout_ms":{"type":"integer","description":"How long to wait for the callee to answer before abandoning,\nin milliseconds. Defaults to 30000 (30s). Capped at 80000 (80s).\n"},"amd":{"$ref":"#/components/schemas/tts:AMDConfig","description":"Optional per-call override for the AMD routing config. When\nset, wholesale-replaces the agent's stored AMD shape for\nthis single call (PATCH-replace, not merge). Unlocks the\nbatch-campaign pattern: one agent dialling many recipients\nwith per-row tailored voicemail messages via the existing\ndynamic_variables substitution. Validation rules match\nthe agent-update boundary.\n"}},"required":["agent_id","to"],"description":"Body for `POST /v1/agents/outbound-calls`. Requires a Twilio or BYOC\ntrunk; LiveKit-native numbers do not support outbound today.\n","title":"CreateOutboundCallRequest"},"tts:CreateOutboundCallResponse":{"type":"object","properties":{"conversation_id":{"type":"string","description":"ID of the conversation created for this call. Use to poll status."},"room":{"type":"string","description":"LiveKit room name the answered call joins."},"sip_participant_id":{"type":"string","description":"LiveKit participant ID for the outbound SIP call leg."}},"required":["conversation_id","room","sip_participant_id"],"description":"Returned synchronously when LiveKit accepts the SIP INVITE. Poll\n`GET /v1/agents/conversations/{conversation_id}` for status transitions:\n`pending` (ringing) \u2192 `active` (answered) \u2192 `completed`.\n","title":"CreateOutboundCallResponse"},"tts:PhoneNumberSource":{"type":"string","enum":["livekit","twilio","byoc","twilio_purchased","verified_caller_id"],"description":"Where the number came from. Determines the provisioning and\nportability path.\n\n- `livekit` - LiveKit owns the carrier relationship; US inbound only.\n- `twilio` - Customer's own Twilio number bridged via Elastic SIP Trunk.\n- `byoc` - Any SIP provider using a customer-supplied trunk.\n- `twilio_purchased` - Bought through `POST /v1/agents/phone-numbers/purchase` on Speechify's master Twilio account; billed to Speechify.\n- `verified_caller_id` - Customer-verified outbound caller ID on\n their own Twilio account (Twilio's OutgoingCallerIds resource).\n Server-determined at import time: when an `e164` submitted with\n `source=twilio` is not a full DID on the customer's account but\n IS a verified caller ID, the resulting row gets this source.\n Outbound-only, never agent-bindable, rides the customer's\n existing shared Twilio trunk for outbound routing. Requires a\n prior `twilio` full-DID import from the same account; without\n it the import returns 400.\n","title":"PhoneNumberSource"},"tts:TwilioImportSpec":{"type":"object","properties":{"account_sid":{"type":"string","description":"Twilio Account SID (starts with `AC`)."},"auth_token":{"type":"string","description":"Twilio Auth Token. Write-only - never echoed back."}},"required":["account_sid","auth_token"],"description":"Twilio credentials for the one-click import flow. Used only when\n`source=twilio`. The Account SID and Auth Token are used to\nprovision an Elastic SIP Trunk on the customer's Twilio account\npointing at LiveKit's SIP endpoint, then stored for future trunk\nmanagement operations.\n","title":"TwilioImportSpec"},"tts:ImportPhoneNumberRequest":{"type":"object","properties":{"e164":{"type":"string","description":"The phone number in E.164 format. For `source=livekit` this\nis the number you want LiveKit to purchase. For `source=twilio`\nand `source=byoc` it is the number you already own.\n"},"source":{"$ref":"#/components/schemas/tts:PhoneNumberSource"},"label":{"type":"string","description":"Optional human-readable label."},"trunk_id":{"type":"string","description":"For `source=byoc`: the SIP trunk to bind this number to.\nPrefixed wire identifier (`trunk_<26 char Crockford base32>`).\nNot required for `source=livekit` or `source=twilio`.\n"},"agent_id":{"type":"string","description":"Optional agent to bind on import. Prefixed wire identifier\n(`agent_<26 char Crockford base32>`).\n"},"twilio":{"$ref":"#/components/schemas/tts:TwilioImportSpec"}},"required":["e164","source"],"description":"Body for `POST /v1/agents/phone-numbers`. The required fields vary by\n`source` - see the individual source descriptions.\n","title":"ImportPhoneNumberRequest"},"tts:PhoneNumberCapability":{"type":"string","enum":["inbound","outbound"],"description":"What the number can do. LiveKit-native numbers are `inbound` only;\nverified caller IDs are `outbound` only; Twilio and BYOC full-DID\nnumbers (and Speechify-purchased numbers) support both directions.\n","title":"PhoneNumberCapability"},"tts:PhoneNumber":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`phone_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"e164":{"type":"string","description":"The phone number in E.164 format (e.g. `+12025551234`)."},"source":{"$ref":"#/components/schemas/tts:PhoneNumberSource"},"label":{"type":"string","description":"Optional human-readable label set by the customer."},"trunk_id":{"type":"string","description":"ID of the SIP trunk backing this number, if applicable."},"agent_id":{"type":"string","description":"ID of the agent that answers calls to this number. Null when unbound."},"capabilities":{"type":"array","items":{"$ref":"#/components/schemas/tts:PhoneNumberCapability"},"description":"What this number can do."},"livekit_phone_number_id":{"type":"string","description":"LiveKit's own phone number ID (populated for `source=livekit` only)."},"created_at":{"type":"string","format":"date-time","description":"When the number was imported."},"updated_at":{"type":"string","format":"date-time","description":"When the number was last modified."}},"required":["id","e164","source","capabilities","created_at","updated_at"],"description":"A phone number in the workspace inventory. Bound to an agent via\n`agent_id`; unbound numbers are valid but non-functional until\nassigned.\n","title":"PhoneNumber"},"tts:ListPhoneNumbersResponse":{"type":"object","properties":{"numbers":{"type":"array","items":{"$ref":"#/components/schemas/tts:PhoneNumber"},"description":"Phone numbers in the workspace (up to 100)."}},"required":["numbers"],"description":"Response for `GET /v1/agents/phone-numbers`.","title":"ListPhoneNumbersResponse"},"tts:UpdatePhoneNumberRequest":{"type":"object","properties":{"label":{"type":"string","description":"New label. Pass an empty string to clear."},"agent_id":{"type":"string","description":"Agent to bind the number to. Prefixed wire identifier\n(`agent_<26 char Crockford base32>`).\n"},"clear_agent_id":{"type":"boolean","description":"When `true`, unbinds the current agent (clears `agent_id`).\nWins over `agent_id` when both are sent."}},"description":"PATCH body for `PATCH /v1/agents/phone-numbers/{id}`. Only `label`,\n`agent_id`, and `clear_agent_id` are mutable; `source` and `e164`\nare immutable after import. Set `agent_id` to bind a new agent;\nsend `clear_agent_id: true` to unbind. The clear flag is the\nexplicit signal because JSON `null` is indistinguishable from\nabsent for pointer fields in Go's encoding/json.\n","title":"UpdatePhoneNumberRequest"},"tts:AvailablePhoneNumber":{"type":"object","properties":{"e164":{"type":"string","description":"The phone number in E.164 format."},"friendly_name":{"type":"string","description":"Carrier-formatted display variant, e.g. \"(415) 555-2671\"."},"locality":{"type":"string","description":"City the number is associated with, when known."},"region":{"type":"string","description":"Two-letter state code for US numbers."},"iso_country":{"type":"string","description":"ISO-3166 alpha-2 country code."}},"required":["e164","iso_country"],"description":"One hit from `GET /v1/agents/phone-numbers/available`. The number is\nnot held: a concurrent buy by another customer may take it\nbetween this response and a subsequent purchase request.\n","title":"AvailablePhoneNumber"},"tts:SearchAvailablePhoneNumbersResponse":{"type":"object","properties":{"numbers":{"type":"array","items":{"$ref":"#/components/schemas/tts:AvailablePhoneNumber"},"description":"Available numbers (may be empty if no inventory matches)."}},"required":["numbers"],"description":"Response for `GET /v1/agents/phone-numbers/available`.","title":"SearchAvailablePhoneNumbersResponse"},"tts:PurchasePhoneNumberRequest":{"type":"object","properties":{"e164":{"type":"string","description":"The E.164 number to buy. Must currently be in carrier inventory."},"label":{"type":"string","description":"Optional human-readable label."},"agent_id":{"type":"string","description":"Optional agent to bind the number to at purchase time.\nPrefixed wire identifier (`agent_<26 char Crockford base32>`).\n"}},"required":["e164"],"description":"Body for `POST /v1/agents/phone-numbers/purchase`. The `e164` must come\nfrom a recent `SearchAvailablePhoneNumbers` response.\n","title":"PurchasePhoneNumberRequest"},"tts:SIPTrunkKind":{"type":"string","enum":["livekit","twilio","byoc"],"description":"Where the trunk came from. Informs the provisioning path and\nportability story.\n\n- `livekit` - Provisioned by LiveKit's native phone-number API.\n- `twilio` - Backed by a Twilio Elastic SIP Trunk on the customer's account.\n- `byoc` - Any SIP provider with a customer-managed trunk.\n","title":"SIPTrunkKind"},"tts:SIPTrunkDirection":{"type":"string","enum":["inbound","outbound","both"],"description":"Whether the trunk handles inbound calls, outbound calls, or both.\nA `both` trunk has distinct LiveKit inbound and outbound trunk IDs.\n","title":"SIPTrunkDirection"},"tts:SIPTransport":{"type":"string","enum":["auto","udp","tcp","tls"],"description":"SIP transport protocol. `auto` lets LiveKit negotiate. Use `tls`\nfor production where available - note that TLS is incompatible\nwith SIP REFER (cold transfer). Trunks that need `transfer_to_number`\nshould use `udp` or `tcp`.\n","title":"SIPTransport"},"tts:SIPMediaEncryption":{"type":"string","enum":["disable","allow","require"],"description":"SRTP media encryption policy.\n\n- `disable` - Unencrypted media only.\n- `allow` - Negotiate SRTP; fall back to unencrypted. Recommended default.\n- `require` - Reject calls that do not support SRTP.\n","title":"SIPMediaEncryption"},"tts:CreateSipTrunkRequestCredentials":{"type":"object","properties":{},"description":"Provider-specific credential blob (for future extensibility).","title":"CreateSipTrunkRequestCredentials"},"tts:CreateSIPTrunkRequest":{"type":"object","properties":{"name":{"type":"string","description":"Human-readable name for the trunk."},"kind":{"$ref":"#/components/schemas/tts:SIPTrunkKind"},"direction":{"$ref":"#/components/schemas/tts:SIPTrunkDirection"},"sip_address":{"type":"string","description":"SIP endpoint hostname. Required for `kind=byoc`."},"auth_username":{"type":"string","description":"SIP digest auth username."},"auth_password":{"type":"string","description":"SIP digest auth password. Write-only."},"allowed_addresses":{"type":"array","items":{"type":"string"},"description":"IP / CIDR allowlist for inbound connections. Empty means any source is accepted."},"destination_country":{"type":"string","description":"ISO 3166-1 alpha-2 country for the outbound dial plan."},"transport":{"$ref":"#/components/schemas/tts:SIPTransport"},"media_encryption":{"$ref":"#/components/schemas/tts:SIPMediaEncryption"},"credentials":{"$ref":"#/components/schemas/tts:CreateSipTrunkRequestCredentials","description":"Provider-specific credential blob (for future extensibility)."}},"required":["name","kind","direction"],"description":"Body for `POST /v1/agents/sip-trunks`.","title":"CreateSIPTrunkRequest"},"tts:SIPTrunk":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`trunk_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"name":{"type":"string","description":"Human-readable name."},"kind":{"$ref":"#/components/schemas/tts:SIPTrunkKind"},"direction":{"$ref":"#/components/schemas/tts:SIPTrunkDirection"},"livekit_inbound_trunk_id":{"type":"string","description":"LiveKit's inbound trunk ID (present when direction is `inbound` or `both`)."},"livekit_outbound_trunk_id":{"type":"string","description":"LiveKit's outbound trunk ID (present when direction is `outbound` or `both`)."},"livekit_dispatch_rule_id":{"type":"string","description":"LiveKit dispatch rule ID that routes inbound calls into rooms."},"sip_address":{"type":"string","description":"SIP endpoint hostname (e.g. `sip.telnyx.com`). Required for `kind=byoc`."},"auth_username":{"type":"string","description":"SIP digest auth username."},"auth_password_set":{"type":"boolean","description":"Whether a SIP digest auth password is configured. The value is never returned."},"allowed_addresses":{"type":"array","items":{"type":"string"},"description":"IP address / CIDR allowlist for inbound SIP connections."},"destination_country":{"type":"string","description":"ISO 3166-1 alpha-2 country code for the outbound dial plan\n(e.g. `US`, `DE`). Required for international outbound on\nsome carriers.\n"},"transport":{"$ref":"#/components/schemas/tts:SIPTransport"},"media_encryption":{"$ref":"#/components/schemas/tts:SIPMediaEncryption"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","kind","direction","allowed_addresses","transport","media_encryption","created_at","updated_at"],"description":"A SIP trunk in the workspace. Trunks back one or more phone numbers\nand hold the carrier credentials LiveKit uses to route calls.\n`auth_password` is never echoed - `auth_password_set` indicates\nwhether one is configured.\n","title":"SIPTrunk"},"tts:ListSIPTrunksResponse":{"type":"object","properties":{"trunks":{"type":"array","items":{"$ref":"#/components/schemas/tts:SIPTrunk"},"description":"SIP trunks in the workspace (up to 20)."}},"required":["trunks"],"description":"Response for `GET /v1/agents/sip-trunks`.","title":"ListSIPTrunksResponse"},"tts:IvrMenuListEntryMenuTree":{"type":"object","properties":{},"title":"IvrMenuListEntryMenuTree"},"tts:IVRMenuListEntry":{"type":"object","properties":{"menu_id":{"type":"string","description":"Prefixed wire identifier (`menu_<26 char Crockford base32>`)."},"fingerprint_id":{"type":"string"},"fingerprint_hash":{"type":"string"},"transcript_sample":{"type":"string"},"schema_version":{"type":"integer"},"menu_tree":{"$ref":"#/components/schemas/tts:IvrMenuListEntryMenuTree"},"confidence_score":{"type":"number","format":"double"},"succeeded_traversals":{"type":"integer"},"total_traversals":{"type":"integer"},"last_validated_at":{"type":"string","format":"date-time"},"last_observed_at":{"type":"string","format":"date-time"},"occurrence_count":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}},"required":["menu_id","fingerprint_id","fingerprint_hash","transcript_sample","schema_version","menu_tree","confidence_score","succeeded_traversals","total_traversals","last_validated_at","last_observed_at","occurrence_count","created_at"],"description":"One row in the list-IVR-menus response. Carries the fingerprint\nhash + sample transcript so the console can render the IVR\nidentity without a second round-trip. `last_observed_at` and\n`occurrence_count` are projected from `ivr_fingerprints` for\nthe \"when did we last see this IVR\" signal.\n","title":"IVRMenuListEntry"},"tts:ListIVRMenusResponse":{"type":"object","properties":{"menus":{"type":"array","items":{"$ref":"#/components/schemas/tts:IVRMenuListEntry"}}},"required":["menus"],"title":"ListIVRMenusResponse"},"tts:IvrMenuMenuTree":{"type":"object","properties":{},"description":"Validated menu_tree per contracts/agents/ivr_menu.schema.json. Opaque to consumers other than the worker.","title":"IvrMenuMenuTree"},"tts:IVRMenu":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`menu_<26 char Crockford base32>`).\nADR 0015 Cluster 2 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 2.\n"},"fingerprint_id":{"type":"string"},"tenant_id":{"type":["string","null"],"description":"Null on the cross-tenant promoted slot."},"schema_version":{"type":"integer"},"menu_tree":{"$ref":"#/components/schemas/tts:IvrMenuMenuTree","description":"Validated menu_tree per contracts/agents/ivr_menu.schema.json. Opaque to consumers other than the worker."},"confidence_score":{"type":"number","format":"double"},"succeeded_traversals":{"type":"integer"},"total_traversals":{"type":"integer"},"last_validated_at":{"type":"string","format":"date-time"},"invalidated_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","fingerprint_id","schema_version","menu_tree","confidence_score","succeeded_traversals","total_traversals","last_validated_at","created_at","updated_at"],"description":"One memorized IVR menu level (AIS-3267). Identified by the\nSHA-256 fingerprint of the normalized greeting transcript;\nscoped to the caller's workspace (foreign-tenant menus are\nnever returned).\n\n`menu_tree` is the validated JSONB blob the worker consumes:\nprompt text plus the options offered (label + DTMF). Sub-menus\nreached by pressing an option are their own rows, looked up at\ndescent time by a fresh fingerprint - the tree structure is the\nimplicit graph of fingerprint -> fingerprint transitions.\n\n`confidence_score` is `succeeded_traversals / total_traversals`\n(ADR 0009 \u00a73). The worker's plan-then-execute fast path only\nactivates at or above 0.5.\n\n`invalidated_at` is non-null on a soft-deleted row; the API\nfilters these out of list / lookup / get responses so this field\nis informational only.\n","title":"IVRMenu"},"tts:UpdateIVRMenuLabelRequest":{"type":"object","properties":{"dtmf":{"type":"string","description":"DTMF value of the option to relabel (e.g. \"1\", \"*\", \"#\")."},"label":{"type":"string","description":"New label. Capped at 256 chars server-side."}},"required":["dtmf","label"],"description":"Re-label one option in the stored menu_tree. The option is\nmatched by its DTMF value; the label is the human-readable text\nrendered in the console + surfaced to the LLM at navigate time.\n","title":"UpdateIVRMenuLabelRequest"},"tts:InvalidateIVRMenuRequest":{"type":"object","properties":{"reason":{"type":"string","description":"Operator-debug cause string. Bounded to 256 chars."}},"description":"Optional reason captured in structured logs. The column today\nis the timestamp, not the cause; a future audit table may\npersist the reason if customer demand justifies it.\n","title":"InvalidateIVRMenuRequest"}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'."}}}}
+{"openapi":"3.1.0","info":{"title":"API Reference","version":"1.0.0"},"paths":{"/v1/audio/speech":{"post":{"operationId":"speech","summary":"Create Speech","description":"Synthesize speech audio from text or SSML. Returns the complete audio\nfile plus billing and speech-mark metadata in a single response. For\nlow-latency playback or long-form text, use POST /v1/audio/stream.","tags":["subpackage_tts.subpackage_tts/audio"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Synthesized speech audio for the requested input.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetSpeechResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"402":{"description":"The workspace has insufficient credits, or the request needs a\nplan tier the workspace is not on (e.g. voice cloning). Distinct\nfrom `Forbidden` so SDK consumers can drive upgrade UX.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"403":{"description":"The credential authenticated, but is not authorised for this\nresource - typically a workspace-role gate (owner / admin\nrequired) or a cross-tenant access attempt.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetSpeechRequest"}}}}}},"/v1/audio/stream":{"post":{"operationId":"stream","summary":"Stream Speech","description":"Synthesize speech and stream the audio back as it is generated, for\nlow-latency playback. The Accept header selects the audio container.\nFor short text where receiving the whole file at once is fine, use\nPOST /v1/audio/speech.","tags":["subpackage_tts.subpackage_tts/audio"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}},{"name":"Accept","in":"header","required":true,"schema":{"$ref":"#/components/schemas/tts:V1AudioStreamPostParametersAccept"}}],"responses":{"200":{"description":"Chunked audio stream for the requested input.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"402":{"description":"The workspace has insufficient credits, or the request needs a\nplan tier the workspace is not on (e.g. voice cloning). Distinct\nfrom `Forbidden` so SDK consumers can drive upgrade UX.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"403":{"description":"The credential authenticated, but is not authorised for this\nresource - typically a workspace-role gate (owner / admin\nrequired) or a cross-tenant access attempt.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetStreamRequest"}}}}}},"/v1/voices":{"get":{"operationId":"list","summary":"List Voices","description":"Gets the list of voices available for the user","tags":["subpackage_tts.subpackage_tts/voices"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of voices","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/tts:GetVoice"}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"post":{"operationId":"create","summary":"Create Voice","description":"Create a personal (cloned) voice for the user","tags":["subpackage_tts.subpackage_tts/voices"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A created voice","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreatedVoice"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"402":{"description":"The workspace has insufficient credits, or the request needs a\nplan tier the workspace is not on (e.g. voice cloning). Distinct\nfrom `Forbidden` so SDK consumers can drive upgrade UX.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Name of the personal voice"},"locale":{"type":"string","default":"en-US","description":"Native language (locale) of the personal voice (e.g. en-US, es-ES, etc.)"},"gender":{"$ref":"#/components/schemas/tts:V1VoicesPostRequestBodyContentMultipartFormDataSchemaGender","description":"Gender marker for the personal voice\nmale GenderMale\nfemale GenderFemale\nnotSpecified GenderNotSpecified"},"sample":{"type":"string","format":"binary","description":"Audio sample file"},"avatar":{"type":"string","format":"binary","description":"Avatar image file"},"consent":{"type":"string","description":"A **string** representing the user consent information in JSON format\nThis should include the fullName and email of the consenting individual.\nFor example, `{\"fullName\": \"John Doe\", \"email\": \"john@example.com\"}`"}},"required":["name","gender","sample","consent"]}}}}}},"/v1/voices/{id}":{"delete":{"operationId":"delete","summary":"Delete Voice","description":"Delete a personal (cloned) voice","tags":["subpackage_tts.subpackage_tts/voices"],"parameters":[{"name":"id","in":"path","description":"The ID of the voice to delete","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Voice deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/voices/{id}/sample":{"get":{"operationId":"download-sample","summary":"Download Voice Sample","description":"Download a personal (cloned) voice sample","tags":["subpackage_tts.subpackage_tts/voices"],"parameters":[{"name":"id","in":"path","description":"The ID of the voice to download sample for","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Voice sample audio file","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents":{"post":{"operationId":"create","summary":"Create Agent","description":"Create a voice agent.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Agent"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateAgentRequest"}}}}},"get":{"operationId":"list","summary":"List Agents","description":"List voice agents owned by the caller.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of voice agents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAgentsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}":{"get":{"operationId":"get","summary":"Get Agent","description":"Retrieve a voice agent by ID.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Agent"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update","summary":"Update Agent","description":"Update a voice agent. Only fields present on the request body are changed.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Agent"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateAgentRequest"}}}}},"delete":{"operationId":"delete","summary":"Delete Agent","description":"Delete a voice agent. Conversations and attached tools remain.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Agent deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/conversations":{"post":{"operationId":"create-conversation","summary":"Create Conversation","description":"Start a new voice conversation with the agent. Returns a realtime\nvoice session + short-lived client token so the caller can\nconnect the audio pipeline directly. The agent is dispatched\nserver-side; no additional client action required.\n\nPass `dynamic_variables` to supply per-session values that override\nthe agent's stored variable defaults for this one conversation.\nKeys in the `system__` namespace are rejected at this boundary.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created conversation with its realtime session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateConversationResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateConversationRequest"}}}}}},"/v1/agents/{id}/sessions":{"post":{"operationId":"create-session","summary":"Create Session","description":"Mint a realtime voice session for the given agent. Widget-friendly\ncounterpart to `createConversation` \u2014 same response shape, dual\nauthentication:\n\n* **Authenticated (Bearer)**: works for any agent the caller\n owns. Typical server-to-server flow where the embedding\n site's backend mints a token and hands it to the browser so\n the API key never reaches the client.\n* **Unauthenticated**: works only when `agent.is_public = true`\n AND the request's `Origin` header matches `agent.allowed_origins`\n (or that list is empty). When `agent.hostname_allowlist` is\n non-empty, the `Origin` hostname must additionally be a\n member of that list. Used directly by the\n `` web component.\n\nResponds with the same `CreateConversationResponse` as\n`createConversation`.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The created session with its realtime token + URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateConversationResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"403":{"description":"The credential authenticated, but is not authorised for this\nresource - typically a workspace-role gate (owner / admin\nrequired) or a cross-tenant access attempt.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateSessionRequest"}}}}}},"/v1/agents/voices":{"get":{"operationId":"list-agent-voices","summary":"List Agent Voices","description":"List the curated voice catalogue available for voice agents.\nMatches the `ai-api-agents` VMS scope one-for-one, so the same\nslug set is accepted by POST/PATCH /v1/agents. Personal\n(cloned) voices are NOT included \u2014 they stay on\n`GET /v1/voices`. The JSON layout intentionally mirrors the\nTTS `/v1/voices` shape so the console feeds both endpoints\ninto the same voice-picker component.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The curated agent voice catalogue.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentVoice"}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/builtins":{"post":{"operationId":"create-builtin","summary":"Create Agent Builtin","description":"Create a new builtin instance on this agent. `builtin` must\nresolve to one of the names returned by\n`GET /v1/agents/tools/system-builtins`; unknown values are rejected.\n`name` is the LLM-facing identifier the model uses to call the\ntool; it must match the tool-name regex and be unique within\nthe agent's builtin set.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created builtin instance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentBuiltin"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateAgentBuiltinRequest"}}}}},"get":{"operationId":"list-builtins","summary":"List Agent Builtins","description":"List every builtin instance configured on this agent. Each row\nis one instance of a worker-resident capability (`end_call`,\n`play_audio`, etc.) bound to this specific agent with its own\nLLM-facing name, description, and per-call config. Same builtin\nmay appear N times on one agent \u2014 typically two `play_audio`\nrows bound to different audio assets.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The agent's builtin instances.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAgentBuiltinsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/builtins/{builtinId}":{"get":{"operationId":"get-builtin","summary":"Get Agent Builtin","description":"Fetch one builtin instance by ID.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"builtinId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The builtin instance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentBuiltin"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-builtin","summary":"Update Agent Builtin","description":"Update a builtin instance. All fields optional; omitting a\nfield leaves it unchanged. The underlying `builtin` (which\ncapability the instance maps to) is intentionally NOT\npatchable \u2014 change of identity would surprise the worker, so\nthe customer should delete and recreate instead.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"builtinId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated builtin instance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentBuiltin"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateAgentBuiltinRequest"}}}}},"delete":{"operationId":"delete-builtin","summary":"Delete Agent Builtin","description":"Delete a builtin instance from this agent. Idempotent on\nalready-deleted ids (404). Does NOT detach references from\nflow nodes that name the instance; the worker logs and skips\non missing-row at session start (fail-soft).\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"builtinId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Builtin instance deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/variables":{"get":{"operationId":"get-dynamic-variables","summary":"Get Dynamic Variables","description":"Retrieve the agent's customer-scope dynamic variables and the read-only\ncatalogue of reserved `system__*` keys. The system variables list is\nprovided so editor UIs can render the reference list without maintaining\na client-side copy of the catalogue.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The agent's variable catalogue.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListDynamicVariablesResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-dynamic-variables","summary":"Update Dynamic Variables","description":"Replace the agent's customer-scope dynamic variable definitions.\nThe supplied list overwrites the stored list wholesale (same\nsemantics as `updateEvaluationConfig`). Pass an empty array to\nclear all variables. Up to 20 variables per agent. Keys must\nmatch `[a-zA-Z0-9_]+` and must not start with the reserved\n`system__` prefix.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated variable catalogue.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListDynamicVariablesResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateDynamicVariablesRequest"}}}}}},"/v1/agents/{id}/evaluation-config":{"get":{"operationId":"get-evaluation-config","summary":"Get Evaluation Config","description":"Retrieve the agent's post-call evaluation criteria + data-collection config.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The evaluation config for the agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:EvaluationConfig"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-evaluation-config","summary":"Update Evaluation Config","description":"Replace the agent's evaluation criteria + data-collection fields.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated evaluation config.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:EvaluationConfig"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateEvaluationConfigRequest"}}}}}},"/v1/agents/{id}/knowledge-bases":{"get":{"operationId":"list-agent-knowledge-bases","summary":"List Agent Knowledge Bases","description":"List knowledge bases attached to an agent. Bare list \u2014 the\nattachment count is bounded by configuration, not by data\nscale, so this endpoint does not paginate.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The knowledge bases attached to the agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AttachedKnowledgeBasesResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/knowledge-bases/{kbId}":{"post":{"operationId":"attach-knowledge-base","summary":"Attach Agent Knowledge Base","description":"Attach a knowledge base to an agent. The `search_knowledge` tool\nis auto-registered on the next conversation and can only query the\nattached knowledge bases.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"kbId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Knowledge base attached.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"detach-knowledge-base","summary":"Detach Agent Knowledge Base","description":"Detach a knowledge base from an agent.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"kbId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Knowledge base detached.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/memories":{"get":{"operationId":"list-memories","summary":"List Agent Memories","description":"List per-caller memories extracted for an agent. Memories are\nwritten post-call by the built-in extractor when `memory_enabled`\nis true on the agent; the list is sorted newest-first.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Maximum rows to return. Defaults to 100, capped at 200.","required":false,"schema":{"type":"integer","default":100}},{"name":"offset","in":"query","description":"Number of rows to skip. Combine with `limit` to page through older memories.","required":false,"schema":{"type":"integer","default":0}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Memories for the agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListMemoriesResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/memories/delete":{"post":{"operationId":"delete-memories-by-caller","summary":"Delete Memories by Caller","description":"Delete every memory ever extracted for a specific caller on\nthis agent. Privacy / GDPR surface. Returns the count of rows\nsoft-deleted; rows become permanently unreachable immediately\nand are hard-deleted by the retention job after the tenant's\nconfigured retention window.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deletion summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:DeleteMemoriesByCallerResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:DeleteMemoriesByCallerRequest"}}}}}},"/v1/agents/{id}/tests":{"get":{"operationId":"list-tests","summary":"List Agent Tests","description":"List all tests configured for the agent. Each entry includes the\nmost recent run so the console can render pass/fail badges without\nan extra round-trip.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tests for the agent with last-run summaries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAgentTestsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"post":{"operationId":"create-test","summary":"Create Agent Test","description":"Create a new test for the agent.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created test.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTest"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateAgentTestRequest"}}}}}},"/v1/agents/{id}/tests/runs":{"post":{"operationId":"run-all-tests","summary":"Run All Agent Tests","description":"Enqueue runs for every test on the agent concurrently. Up to 50\ntests are dispatched in one call. Each returned run starts in\n`queued` status; poll `GET /v1/agents/tests/runs/{id}` for the terminal\nresult.\n\nAn optional request body (AIS-3443) runs the whole suite against\na proposed config: a `config_override` (prompt / model / tools)\napplied to every test without editing the tests, and/or a\n`flow_version_id` to target a specific flow version instead of\nthe agent's active flow. Omit the body to run against the\nagent's live config and active flow.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Queued runs for all tests on the agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RunAgentTestsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RunAllTestsRequest"}}}}}},"/v1/agents/{id}/tools":{"get":{"operationId":"list-tools","summary":"List Agent Tools","description":"List tools currently attached to the agent. Bare list \u2014 an\nagent's tool attachment count is bounded by configuration, so\nthis endpoint does not paginate.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Attached tools for the agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AttachedToolsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/tools/{toolId}":{"post":{"operationId":"attach-tool","summary":"Attach Tool","description":"Attach an existing tool to the agent so the LLM can call it.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"toolId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Tool attached.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"detach-tool","summary":"Detach Tool","description":"Detach a tool from the agent.","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"toolId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Tool detached.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/widget-config":{"get":{"operationId":"get-widget-config","summary":"Get Agent Widget Config","description":"Return the embed-widget appearance config for an agent. Works\nunauthenticated for public agents; the body is cosmetic only.\n","tags":["subpackage_tts.subpackage_tts/agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The agent's widget configuration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:WidgetConfig"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations":{"get":{"operationId":"list","summary":"List Conversations","description":"List conversations owned by the caller, ordered by most recent.\nCursor-paginated: omit `cursor` to fetch the first page; pass the\nprevious response's `next_cursor` back to fetch the next page.\nWalk pages while `has_more` is true.","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max conversations per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"agent_id","in":"query","description":"Filter to conversations for this agent.","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Filter by conversation status.","required":false,"schema":{"$ref":"#/components/schemas/tts:ConversationStatus"}},{"name":"transport","in":"query","description":"Filter by transport.","required":false,"schema":{"$ref":"#/components/schemas/tts:ConversationTransport"}},{"name":"caller_identity","in":"query","description":"Filter by caller identity.","required":false,"schema":{"type":"string"}},{"name":"search","in":"query","description":"Free-text search across conversation content.","required":false,"schema":{"type":"string"}},{"name":"started_after","in":"query","description":"Only conversations started at or after this RFC 3339 timestamp.","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"started_before","in":"query","description":"Only conversations started at or before this RFC 3339 timestamp.","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"duration_min_ms","in":"query","description":"Minimum conversation duration in milliseconds.","required":false,"schema":{"type":"integer"}},{"name":"duration_max_ms","in":"query","description":"Maximum conversation duration in milliseconds.","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of conversations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListConversationsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}":{"get":{"operationId":"get","summary":"Get Conversation","description":"Retrieve a conversation by ID.","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested conversation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Conversation"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/messages":{"get":{"operationId":"list-messages","summary":"List Messages","description":"Retrieve the transcript for a conversation in started_at order\n(oldest first). Cursor-paginated: omit `cursor` to fetch the\nfirst page. Default page size is 50 and max is 200. Walk pages\nwhile `has_more` is true.","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max messages per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The messages for the conversation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListMessagesResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/evaluations":{"get":{"operationId":"list-evaluations","summary":"List Evaluations","description":"Retrieve post-call evaluation results for a conversation.","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The evaluations for the conversation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListEvaluationsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/memories":{"get":{"operationId":"list-memories","summary":"List Conversation Memories","description":"List memories extracted from a specific conversation.","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Memories written during this conversation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListMemoriesResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/stats":{"get":{"operationId":"stats","summary":"Conversation stats","description":"Aggregated counts and averages over the caller's conversations, scoped by the same filters as the list endpoint.","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"agent_id","in":"query","description":"Filter to conversations for this agent.","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Filter by conversation status.","required":false,"schema":{"$ref":"#/components/schemas/tts:ConversationStatus"}},{"name":"transport","in":"query","description":"Filter by transport.","required":false,"schema":{"$ref":"#/components/schemas/tts:ConversationTransport"}},{"name":"caller_identity","in":"query","description":"Filter by caller identity.","required":false,"schema":{"type":"string"}},{"name":"search","in":"query","description":"Free-text search across conversation content.","required":false,"schema":{"type":"string"}},{"name":"started_after","in":"query","description":"Only conversations started at or after this RFC 3339 timestamp.","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"started_before","in":"query","description":"Only conversations started at or before this RFC 3339 timestamp.","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"duration_min_ms","in":"query","description":"Minimum conversation duration in milliseconds.","required":false,"schema":{"type":"integer"}},{"name":"duration_max_ms","in":"query","description":"Maximum conversation duration in milliseconds.","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Stats for the matched conversations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ConversationStats"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/recent-callees":{"get":{"operationId":"recent-callees","summary":"List recent callees","description":"Distinct phone numbers the caller's workspace has dialled on\noutbound calls, ordered by most recent. Feeds the batch-calls\ncomposer's \"Suggested from history\" surface. Cursor-paginated:\nomit `cursor` to fetch the first page. Default page size is 50\nand max is 200. Walk pages while `has_more` is true.\n","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max number of distinct phone numbers per page. Defaults to 50; clamped to 200.","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recent callees for the caller's workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListRecentCalleesResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/recording":{"get":{"operationId":"stream-recording","summary":"Stream Recording","description":"Proxy the GCS-stored audio recording for a conversation through\nthe Cloud Run service identity. Returns OGG/Opus bytes (LiveKit\nroom-composite egress default). The response is streamed so a\nlong recording does not buffer in memory; `` consumers\ncan seek directly. Only present when the agent had\n`save_audio_recording` enabled at session start.\n","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The recorded audio.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/webhook-deliveries":{"get":{"operationId":"list-webhook-deliveries","summary":"List Webhook Deliveries","description":"List post-call webhook delivery attempts for a conversation,\nnewest first. Rows appear once the LiveKit `room_finished`\nwebhook has fired and the post-call webhook has been\ndispatched to the agent's configured URL. One row per\n`(conversation, webhook-url)`, updated in place across retries.\nCursor-paginated: omit `cursor` to fetch the first page.\nDefault page size is 50 and max is 200. Walk pages while\n`has_more` is true.\n","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max deliveries per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The post-call webhook deliveries for the conversation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListWebhookDeliveriesResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/retrieval-log":{"get":{"operationId":"list-retrieval-log","summary":"List Retrieval Log","description":"Per-conversation retrieval log, newest first \u2014 one row per\n`search_knowledge` invocation made during the call. Each entry\nrecords the query, ranked chunks (denormalised so deletions\ndon't render history unreadable), `top_k`, and hit count.\nPowers the Retrieval panel on the conversation detail view.\nCursor-paginated: omit `cursor` to fetch the first page.\nDefault page size is 50 and max is 200. Walk pages while\n`has_more` is true.\n","tags":["subpackage_tts.subpackage_tts/conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max retrieval log entries per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The retrieval log entries for the conversation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListRetrievalLogsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases":{"post":{"operationId":"create","summary":"Create Knowledge Base","description":"Create a new knowledge base.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created knowledge base.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBase"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateKnowledgeBaseRequest"}}}}},"get":{"operationId":"list","summary":"List Knowledge Bases","description":"List knowledge bases owned by the caller. Cursor-paginated:\nomit `cursor` to fetch the first page. The default page size is\n50 and the max is 200; values outside that range are clamped.\nWalk pages while `has_more` is true.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max knowledge bases per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The knowledge bases for the caller.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListKnowledgeBasesResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/{id}":{"get":{"operationId":"get","summary":"Get Knowledge Base","description":"Retrieve a knowledge base by ID.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested knowledge base.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBase"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update","summary":"Update Knowledge Base","description":"Update a knowledge base.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated knowledge base.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBase"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateKnowledgeBaseRequest"}}}}},"delete":{"operationId":"delete","summary":"Delete Knowledge Base","description":"Soft-delete a knowledge base. Documents and chunks are cascaded.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Knowledge base deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/{id}/documents":{"post":{"operationId":"upload-document","summary":"Upload Knowledge Base Document","description":"Upload a document (PDF, plain text, markdown, or HTML) to a\nknowledge base. The document is extracted, chunked, embedded, and\nindexed synchronously; expect a few seconds per MB of input.\nMaximum 10 MB per upload.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The ingested document record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocument"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"413":{"description":"Request body exceeded a per-endpoint size limit (e.g. KB\ndocument upload cap, batch-call CSV cap, audio-asset WAV cap).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}}},"get":{"operationId":"list-documents","summary":"List Knowledge Base Documents","description":"List documents ingested into a knowledge base. Cursor-paginated:\nomit `cursor` to fetch the first page. Default page size is 50\nand max is 200. Walk pages while `has_more` is true.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"folder_id","in":"query","description":"Folder filter: omit for root-level documents, pass `all` for\nevery document in the KB, or a folder id to scope to that\nfolder.\n","required":false,"schema":{"type":"string"}},{"name":"q","in":"query","description":"Substring match on filename and source_url.","required":false,"schema":{"type":"string"}},{"name":"source_kind","in":"query","description":"Comma-separated source kinds (file|url|text).","required":false,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max documents per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The documents in the knowledge base.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListKnowledgeBaseDocumentsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/{id}/documents/{docId}":{"get":{"operationId":"get-document","summary":"Get Knowledge Base Document","description":"Retrieve a document by ID.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"docId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The document record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocumentDetail"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"delete-document","summary":"Delete Knowledge Base Document","description":"Delete a document and all its chunks.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"docId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Document deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-document","summary":"Update Knowledge Base Document","description":"Update a document. Currently supports moving the document\nbetween folders via `folder_id`.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"docId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Document updated.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"folder_id":{"type":["string","null"],"description":"Destination folder. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null moves the\ndocument to the knowledge base root.\n"}}}}}}}},"/v1/agents/knowledge-bases/{id}/documents/{docId}/chunks":{"get":{"operationId":"list-chunks","summary":"List Knowledge Base Chunks","description":"List the chunks for a document. Cursor-paginated: omit `cursor`\nto fetch the first page. Default page size is 50 and max is 200.\nWalk pages while `has_more` is true.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"docId","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max chunks per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The chunks for the document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListKnowledgeBaseChunksResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/search":{"post":{"operationId":"search","summary":"Search Knowledge Bases","description":"Semantic search across a caller-owned list of knowledge bases.\nReturns ranked chunks with source filename and a cosine-similarity\nscore. Limited to 50 results per request.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Ranked search hits across the selected knowledge bases.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:SearchKnowledgeBasesResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:SearchKnowledgeBasesRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/text":{"post":{"operationId":"create-text-document","summary":"Create Text Document","description":"Create a document from inline pasted text. Content is chunked,\nembedded, and indexed synchronously.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocument"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateTextDocumentRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/url":{"post":{"operationId":"create-url-document","summary":"Create URL Document","description":"Fetch a URL via Firecrawl and ingest the rendered content as a\ndocument. The fetch happens synchronously; expect a few\nseconds per page. Use the sitemap / crawl endpoints for\nmulti-page imports.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocument"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateURLDocumentRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/sitemap":{"post":{"operationId":"create-sitemap-import","summary":"Create Sitemap Import","description":"Kick off an async sitemap import. Returns 202 with the import\njob row; client polls `GET /{id}/imports` for progress.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Import job queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ImportJobResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateSitemapImportRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/crawl":{"post":{"operationId":"create-crawl-import","summary":"Create Crawl Import","description":"Kick off an async website crawl. Returns 202 with the import\njob row; client polls `GET /{id}/imports` for progress.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Import job queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ImportJobResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateCrawlImportRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/urls":{"post":{"operationId":"create-url-batch-import","summary":"Create Multi-URL Import","description":"Kick off an async multi-URL import. Accepts 1..N URLs in a\nsingle job (capped per-deployment, default 50) and runs the\nsame per-URL pipeline as the sitemap worker. Returns 202 with\nthe import job row; client polls `GET /{id}/imports` for\nprogress.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Import job queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ImportJobResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateURLBatchImportRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/imports":{"get":{"operationId":"list-import-jobs","summary":"List Import Jobs","description":"List import jobs (sitemap / crawl / refresh) for a knowledge base.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The import jobs for the knowledge base.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListImportJobsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/{id}/imports/{importId}/cancel":{"post":{"operationId":"cancel-import-job","summary":"Cancel Import Job","description":"Cancel a non-terminal import job. Idempotent on terminal jobs\n(completed / failed / cancelled) \u2014 the cancel call returns the\nunchanged row.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"importId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The (possibly already-terminal) import job row.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ImportJob"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/{id}/documents/batch":{"delete":{"operationId":"batch-delete-documents","summary":"Batch Delete Documents","description":"Delete multiple documents in a single transaction. All ids\nmust belong to the supplied knowledge base; mismatches fail\nthe request with 400 before any rows are touched. Capped at\n200 ids per call.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Documents deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:BatchDeleteDocumentsRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/batch/move":{"patch":{"operationId":"batch-move-documents","summary":"Batch Move Documents","description":"Move multiple documents into a folder in a single transaction.\nPass `folder_id: null` to move every doc to root. Capped at\n200 ids per call.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Documents moved.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:BatchMoveDocumentsRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/{docId}/refresh-config":{"patch":{"operationId":"update-refresh-config","summary":"Update Refresh Config","description":"Update the per-document auto-refresh state. Only meaningful\nfor url-sourced documents; file and text rows reject the\nrequest.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"docId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated refresh config.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RefreshConfig"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateRefreshConfigRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/documents/{docId}/refresh-history":{"get":{"operationId":"list-refresh-history","summary":"List Refresh History","description":"List recent auto-refresh attempts for a document.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"docId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recent refresh attempts for the document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListRefreshHistoryResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/knowledge-bases/{id}/folders":{"get":{"operationId":"list-folders","summary":"List Folders","description":"List folders inside a knowledge base. Root-level folders have\n`parent_folder_id: null`. Cursor-paginated: omit `cursor` to\nfetch the first page. Default page size is 50 and max is 200.\nThe console builds the folder tree from `parent_folder_id`, so\nconsumers should walk every page until `has_more` is `false`\nbefore rendering the tree.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max folders per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Folders in the knowledge base.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListKnowledgeBaseFoldersResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"post":{"operationId":"create-folder","summary":"Create Folder","description":"Create a folder inside a knowledge base.","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created folder.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBaseFolder"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateFolderRequest"}}}}}},"/v1/agents/knowledge-bases/{id}/folders/{folderId}":{"delete":{"operationId":"delete-folder","summary":"Delete Folder","description":"Delete a folder. Documents inside the folder are moved to root\n(not deleted). Sub-folders are detached likewise.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"folderId","in":"path","required":true,"schema":{"type":"string"}},{"name":"force","in":"query","description":"When true, delete the folder even if it still contains documents or sub-folders; contents are moved to root.","required":false,"schema":{"type":"boolean"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Folder deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-folder","summary":"Update Folder","description":"Update a folder. Pass `parent_folder_id: null` to move to\nroot; omit the field to leave it unchanged.\n","tags":["subpackage_tts.subpackage_tts/knowledgeBases"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"folderId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated folder.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:KnowledgeBaseFolder"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateFolderRequest"}}}}}},"/v1/agents/memories/{memoryId}":{"delete":{"operationId":"delete","summary":"Delete Memory","description":"Soft-delete one memory row.","tags":["subpackage_tts.subpackage_tts/memories"],"parameters":[{"name":"memoryId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Memory deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests":{"get":{"operationId":"list-all-tests","summary":"List Tests","description":"Workspace-wide list of tests across every agent the caller owns.\nSupports filters (agent, type, last-run status, folder), full-text\nsearch on name/description, and cursor pagination. Each row carries\nits newest run and attached agent IDs so the list renders without\nN+1 round-trips. Walk pages while `has_more` is true.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"agent_id","in":"query","description":"Comma-separated agent IDs to filter on.","required":false,"schema":{"type":"string"}},{"name":"type","in":"query","description":"Comma-separated test types (reply|tool|simulation).","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Comma-separated last-run statuses.","required":false,"schema":{"type":"string"}},{"name":"folder_id","in":"query","description":"Folder ID to filter on, or \"root\" for unfiled tests.","required":false,"schema":{"type":"string"}},{"name":"updated_after","in":"query","description":"Only return tests updated after this RFC3339 timestamp.","required":false,"schema":{"type":"string"}},{"name":"q","in":"query","description":"Substring match on name or description.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max tests per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListTestsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/stats":{"get":{"operationId":"get-test-stats","summary":"Get Test Stats","description":"Aggregate pass-rate metrics over the last N days. Returns dense\ndaily buckets (one entry per day, zero-filled) plus totals and a\nper-type breakdown. Powers the header chart on the global tests\npage. Default window is 30 days, max 90.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"window_days","in":"query","description":"Trailing window in days (default 30, max 90).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Stats payload.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:TestStats"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/{id}":{"get":{"operationId":"get-test","summary":"Get Agent Test","description":"Retrieve a test by ID.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested test.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTest"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-test","summary":"Update Agent Test","description":"Update a test. Only fields present on the request body are changed.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated test.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTest"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateAgentTestRequest"}}}}},"delete":{"operationId":"delete-test","summary":"Delete Agent Test","description":"Delete a test and all its run history.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Test deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/{id}/attachments":{"get":{"operationId":"list-test-attachments","summary":"List Test Attachments","description":"List every agent a test is attached to.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Attachment list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAgentTestAttachmentsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/{id}/attachments/{agentId}":{"post":{"operationId":"attach-test","summary":"Attach Test","description":"Attach a test to an additional agent. After this call, the test\nwill also run as part of that agent's regression suite (and\nagainst its prompt + tool config when invoked with\n`agent_id = {agentId}`). Idempotent.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"agentId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Attached.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"detach-test","summary":"Detach Test","description":"Detach a test from an agent. The owner agent (the agent the test\nwas authored against) cannot be detached; delete the test\ninstead.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"agentId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Detached.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/folders":{"get":{"operationId":"list-test-folders","summary":"List Test Folders","description":"List every test folder the caller owns. Flat list; build the tree client-side.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Folder list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAgentTestFoldersResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"post":{"operationId":"create-test-folder","summary":"Create Test Folder","description":"Create a test folder. Max depth is 3.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Created folder.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTestFolder"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateAgentTestFolderRequest"}}}}}},"/v1/agents/tests/folders/{id}":{"patch":{"operationId":"update-test-folder","summary":"Update Test Folder","description":"Rename or reparent a test folder. Cycles are rejected.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Updated folder.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTestFolder"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateAgentTestFolderRequest"}}}}},"delete":{"operationId":"delete-test-folder","summary":"Delete Test Folder","description":"Soft-delete a folder. Child tests drop back to root.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/{id}/runs":{"post":{"operationId":"run-test","summary":"Run Agent Test","description":"Enqueue a single run of the test. The returned run starts in\n`queued` status. Poll `GET /v1/agents/tests/runs/{id}` until the status\nreaches a terminal state (`passed`, `failed`, or `error`).","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"The queued run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTestRun"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"agent_id":{"type":"string","description":"Run the test against this agent instead of the test's default agent."}}}}}}},"get":{"operationId":"list-test-runs","summary":"List Agent Test Runs","description":"List one page of run history for a test, newest first.\nPaginate by passing `cursor` from the previous response.\n","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque cursor from a prior response's `next_cursor`.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size. Defaults to 50; capped at 200.","required":false,"schema":{"type":"integer","default":50}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Run history for the test.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAgentTestRunsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/runs/{id}":{"get":{"operationId":"get-test-run","summary":"Get Agent Test Run","description":"Retrieve a single test run by ID. Poll this endpoint until\n`status` reaches a terminal state (`passed`, `failed`, or `error`).\nThe `result` field is populated on terminal states.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The test run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTestRun"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/runs/batch":{"post":{"operationId":"run-tests-batch","summary":"Run Tests (Batch)","description":"Queue runs for every (test, agent) pair in the body. Entries\nwithout an `agent_id` fan out to every agent the test is\nattached to. Total expanded runs are capped at 100 per call.\nEach entry in the response is a queued run; poll\n`GET /v1/agents/tests/runs/{id}` for each.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Runs queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RunBatchResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RunBatchRequest"}}}}}},"/v1/agents/tests/suite-runs":{"get":{"operationId":"list-suite-runs","summary":"List Suite Runs","description":"List one page of suite runs (test invocations), newest first.\nA suite run groups every test run dispatched by one Run All,\nbatch, or resubmit call. Paginate by passing `cursor` from the\nprevious response.\n","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"agent_id","in":"query","description":"Narrow the list to the suite runs of one agent.","required":false,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque cursor from a prior response's `next_cursor`.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size. Defaults to 50; capped at 200.","required":false,"schema":{"type":"integer","default":50}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"One page of suite runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListSuiteRunsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/suite-runs/{id}":{"get":{"operationId":"get-suite-run","summary":"Get Suite Run","description":"Retrieve a suite run by ID with its child runs and the derived\naggregate status and pass/fail/error counts.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The suite run with its child runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AgentTestSuiteRunWithRuns"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tests/suite-runs/{id}/resubmit":{"post":{"operationId":"resubmit-suite-run","summary":"Resubmit Suite Run","description":"Re-run the failed and errored tests of a suite run as a fresh\nsuite run, linked back to the original via\n`parent_suite_run_id`. Returns 400 when the suite run has no\nfailed or errored tests to re-run.","tags":["subpackage_tts.subpackage_tts/tests"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"The new suite run and its queued child runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RunAgentTestsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tools":{"post":{"operationId":"create","summary":"Create Tool","description":"Create a tool. For webhook tools, the response includes the HMAC\n`webhook_secret` exactly once \u2014 store it immediately; subsequent\nreads return a masked placeholder.\n","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Tool"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateToolRequest"}}}}},"get":{"operationId":"list","summary":"List Tools","description":"List tools in the caller's workspace, most recently updated\nfirst. Cursor-paginated: omit `cursor` to fetch the first page.\nDefault page size is 50 and max is 200. Walk pages while\n`has_more` is true.","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"cursor","in":"query","description":"Opaque pagination cursor from a previous response.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max tools per page (default 50, max 200).","required":false,"schema":{"type":"integer"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of tools.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListToolsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tools/{id}":{"get":{"operationId":"get","summary":"Get Tool","description":"Retrieve a tool by ID. Webhook secrets are always masked here.","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Tool"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update","summary":"Update Tool","description":"Update a tool. Tool kind is immutable \u2014 create a new tool to change it.","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Tool"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateToolRequest"}}}}},"delete":{"operationId":"delete","summary":"Delete Tool","description":"Delete a tool. Agents that had it attached get a soft-detach.","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Tool deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tools/system-builtins":{"get":{"operationId":"list-system-builtins","summary":"List System Builtins","description":"Read-only catalogue of every system builtin the worker knows\nabout. The console fetches this at runtime rather than\nmaintaining a parallel client-side list (AIS-3074); the server\nis the single source of truth for the label and description\ncopy a customer sees in the builtin-instance picker.\n","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The catalogue of registered system builtins.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListSystemBuiltinsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tools/{id}/attached-agents":{"get":{"operationId":"list-attached-agents","summary":"List Tool Attached Agents","description":"List the agents in the caller's workspace that currently have\nthis tool attached. Useful before deleting a tool, to surface\nwhich agents will lose access. Soft-deleted agents are filtered\nout. Bounded by the number of agents per workspace (tens), so\nthe response is not paginated (see ADR 0013).\n","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Agents in the caller's workspace attached to the tool.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListToolAttachedAgentsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tools/{id}/rotate-secret":{"post":{"operationId":"rotate-secret","summary":"Rotate Tool Webhook Secret","description":"Rotate the HMAC signing secret on a webhook tool. The tool id\nis preserved so attached agents keep working; only the secret\nrolls. The new plaintext is returned on `webhook_secret`\nexactly once \u2014 store it immediately, subsequent reads always\nreturn the masked placeholder. The previous secret is\ninvalidated immediately on success.\n","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The tool with its newly-rotated webhook_secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Tool"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/tools/test-mcp-connection":{"post":{"operationId":"test-mcp-connection","summary":"Test MCP Connection","description":"Probe a customer-supplied MCP server config without persisting\nanything. The server opens the configured transport, runs the\n`initialize` + `list_tools` handshake, and returns either the\ndiscovered tool catalogue or a structured error string. Pass\n`tool_id` from the edit-form flow when the auth payload carries\n`_set` markers but no plaintext, so the server can hydrate the\nstored secret from the encrypted column before probing.\n","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Probe result. The 200 envelope is used for both success and\nstructured failure \u2014 inspect `error` to disambiguate. Network\nand validation failures never bubble up as non-2xx so the\nconsole can render them inline next to the form.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:MCPProbeResult"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:TestMCPConnectionRequest"}}}}}},"/v1/agents/tools/test-webhook-connection":{"post":{"operationId":"test-webhook-connection","summary":"Test Webhook Connection","description":"Probe a customer-supplied webhook tool config without persisting\nanything. The server fires the exact request shape the worker\nsends on a real invocation \u2014 same JSON body, same HMAC-SHA256\nsignature \u2014 with an empty argument set, and reports the\nendpoint's status code, latency, and a truncated response body,\nor a transport-level failure reason. The probe carries an\n`X-Speechify-Webhook-Test: true` header so a careful endpoint\ncan recognise the test and skip its real side effect. Pass\n`tool_id` from the edit-form flow so the server signs the probe\nwith the tool's stored HMAC secret.\n","tags":["subpackage_tts.subpackage_tts/tools"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Probe result. The 200 envelope is used for both success and\nstructured failure \u2014 inspect `error` to disambiguate. A\nnon-2xx response from the endpoint is NOT an `error`: it\npopulates `status_code` / `response_body` with `ok=false`.\nTransport and validation failures never bubble up as non-2xx\nso the console can render them inline next to the form.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:WebhookProbeResult"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:TestWebhookConnectionRequest"}}}}}},"/v1/agents/callers":{"get":{"operationId":"list","summary":"List Callers","description":"List the workspace's callers, ordered by most-recently-seen first.\nA caller is the per-(tenant, agent, identity) entity that owns\nlong-term memories and conversation history. Phase 2 of ADR 0011.\n","tags":["subpackage_tts.subpackage_tts/callers"],"parameters":[{"name":"agent_id","in":"query","description":"Narrow the list to callers attached to one agent.","required":false,"schema":{"type":"string"}},{"name":"q","in":"query","description":"Identity-prefix search. Filters to rows where `identity LIKE q + '%'`\n(`%`/`_` characters in the input are escaped as literals).\n","required":false,"schema":{"type":"string"}},{"name":"last_seen_after","in":"query","description":"RFC 3339 timestamp. Narrows to callers active strictly AFTER the\nsupplied moment. Useful for \"active this week / month\" filters.\n","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor from a prior response's `next_cursor`.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size. Defaults to 50; capped at 200.","required":false,"schema":{"type":"integer","default":50}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListCallersResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/callers/{id}":{"get":{"operationId":"get","summary":"Get Caller","description":"Fetch a single caller by id. Returns 404 for soft-deleted or\nforeign-tenant rows \u2014 GDPR-purged callers appear as \"not found\"\nto the API.\n","tags":["subpackage_tts.subpackage_tts/callers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetCallerResponse"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"delete","summary":"Delete Caller (GDPR purge)","description":"Soft-delete the caller AND cascade soft-delete every memory row\npointing at it. Conversations survive (forensic / billing records)\nbut their caller pointer surfaces as \"deleted\" through the API.\n\nIdempotent \u2014 re-deleting an already-purged caller returns\n`{caller_purged: 0, memories_purged: 0}`. Audit row counts\naccompany every response so a privacy operator has direct\nevidence of the purge without re-querying.\n","tags":["subpackage_tts.subpackage_tts/callers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Soft-delete completed; row counts in the body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:DeleteCallerResponse"}}}}}},"patch":{"operationId":"update","summary":"Update Caller","description":"Update the customer-editable fields on a caller. PATCH semantics:\nomitted fields are unchanged, present fields overwrite. To clear\na nullable field (`display_name`, `external_ref`) pass an empty\nstring. `metadata` REPLACES the existing JSONB blob when supplied.\n","tags":["subpackage_tts.subpackage_tts/callers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The refreshed caller row.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetCallerResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateCallerRequest"}}}}}},"/v1/agents/callers/{id}/memories":{"get":{"operationId":"list-memories","summary":"List Memories For Caller","description":"List one page of memories belonging to the caller, newest first.\nSoft-deleted memories AND memories whose parent caller is\nsoft-deleted are hidden \u2014 the GDPR purge semantics require the\nAPI to behave as if those rows do not exist.\n","tags":["subpackage_tts.subpackage_tts/callers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque cursor from a prior response's `next_cursor`.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size. Defaults to 50; capped at 200.","required":false,"schema":{"type":"integer","default":50}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListCallerMemoriesResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/callers/{id}/conversations":{"get":{"operationId":"list-conversations","summary":"List Conversations For Caller","description":"List one page of conversations belonging to the caller, newest\nstarted first. Same wire envelope as the workspace-wide\n`GET /v1/agents/conversations`, narrowed to one caller.\n","tags":["subpackage_tts.subpackage_tts/callers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","description":"Opaque cursor from a prior response's `next_cursor`.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size. Defaults to 50; capped at 200.","required":false,"schema":{"type":"integer","default":50}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListCallerConversationsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/audio-assets":{"get":{"operationId":"list","summary":"List Audio Assets","description":"List every non-deleted audio asset in the caller's workspace.\nAudio assets are pre-recorded WAV clips (intro jingles, legal\ndisclaimers, hold cues) referenced from `play_audio` flow nodes\nand the corresponding system builtin.\n","tags":["subpackage_tts.subpackage_tts/audioAssets"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of audio assets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListAudioAssetsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"post":{"operationId":"upload","summary":"Upload Audio Asset","description":"Upload a new audio asset. The body is a multipart/form-data\nrequest with a single `file` field carrying the WAV bytes.\n\nThe WAV is validated server-side against a strict format\ncontract \u2014 PCM 16-bit signed, mono, 48000 Hz, \u226430s, \u22644 MiB \u2014\nbefore any bytes hit storage. The strict shape matches the\nLiveKit room sample rate so the worker reads bytes straight\ninto `rtc.AudioFrame` with no decode dependency on either side;\nconvert MP3 sources with `ffmpeg -i in.mp3 -ar 48000 -ac 1\n-sample_fmt s16 out.wav`.\n","tags":["subpackage_tts.subpackage_tts/audioAssets"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The uploaded asset's metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UploadAudioAssetResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"The WAV file bytes. Must be PCM 16-bit signed, mono,\n48000 Hz, \u226430s duration, \u22644 MiB total.\n"}},"required":["file"]}}}}}},"/v1/agents/audio-assets/{id}":{"get":{"operationId":"get","summary":"Get Audio Asset","description":"Fetch one audio asset's metadata. Returns 404 for missing,\nsoft-deleted, or foreign-tenant assets \u2014 existence information\nis never leaked across tenants.\n","tags":["subpackage_tts.subpackage_tts/audioAssets"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The audio asset's metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:AudioAsset"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"delete","summary":"Delete Audio Asset","description":"Soft-delete an audio asset. The underlying GCS object is\nretained so any flow node or tool still referencing the asset\nkeeps working until the config is updated; the worker logs\nand skips on missing-row at session start (fail-soft).\n","tags":["subpackage_tts.subpackage_tts/audioAssets"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Audio asset soft-deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/audio-assets/{id}/bytes":{"get":{"operationId":"get-bytes","summary":"Get Audio Asset Bytes","description":"Stream the raw WAV bytes for an audio asset. Byte-stream\nsibling of the metadata endpoint at /v1/agents/audio-assets/{id}.\nThe LiveKit worker fetches through here for the play_audio\nbuiltin; SDK consumers can also download originals. Returns 404\nfor missing / soft-deleted / foreign-tenant assets.\n","tags":["subpackage_tts.subpackage_tts/audioAssets"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The raw audio bytes (PCM 16-bit signed, mono, 48 kHz, WAV-wrapped).","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}}}}},"/v1/agents/{id}/flow":{"get":{"operationId":"get-flow","summary":"Get Agent Flow","description":"Return the agent's flow graph: the current draft (if any), the\nactive published graph (if any), and the version history.\n","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The draft graph, active graph, and version history.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetFlowResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"put":{"operationId":"update-flow","summary":"Update Agent Flow Draft","description":"Replace the agent's draft flow graph. The graph is validated\nbefore it is stored; publish it separately to make it active.\n","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The stored draft graph.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowGraph"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PutFlowRequest"}}}}}},"/v1/agents/{id}/flow/draft":{"delete":{"operationId":"discard-draft","summary":"Discard Agent Flow Draft","description":"Discard the agent's unpublished draft flow graph.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Draft discarded.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/flow/publish":{"post":{"operationId":"publish","summary":"Publish Agent Flow","description":"Publish the agent's draft graph as a new active flow version.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The newly published flow version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowVersion"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PublishFlowRequest"}}}}}},"/v1/agents/{id}/flow/rollback":{"post":{"operationId":"rollback","summary":"Roll Back Agent Flow","description":"Publish a prior flow version as the active graph.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The flow version that is now active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowVersion"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:RollbackFlowRequest"}}}}}},"/v1/agents/{id}/flow/deactivate":{"post":{"operationId":"deactivate","summary":"Deactivate Agent Flow","description":"Deactivate the agent's published flow so the agent runs the synthesized default flow.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Flow deactivated.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/flow/versions":{"get":{"operationId":"list-versions","summary":"List Agent Flow Versions","description":"List every published flow version for the agent, newest first.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The agent's flow version history.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListFlowVersionsResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/{id}/flow/versions/{versionId}":{"get":{"operationId":"get-version","summary":"Get Agent Flow Version","description":"Return the full flow graph for a specific published version.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"versionId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested flow version's graph.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetFlowVersionResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/flow/schema":{"get":{"operationId":"get-schema","summary":"Get Flow Graph Schema","description":"Return the JSON Schema describing the flow graph node taxonomy.\nUnauthenticated; flow editors fetch it to validate graphs client-side.\n","tags":["subpackage_tts.subpackage_tts/flow"],"responses":{"200":{"description":"A JSON Schema document for the flow graph.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:flow_getSchema_Response_200"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/flow/templates":{"get":{"operationId":"list-templates","summary":"List Flow Templates","description":"List the reusable flow templates available to the workspace.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The available flow templates.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListFlowTemplatesResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"post":{"operationId":"create-template","summary":"Create Flow Template","description":"Create a reusable flow template from a graph.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The created flow template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowTemplate"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateFlowTemplateRequest"}}}}}},"/v1/agents/flow/templates/{id}":{"get":{"operationId":"get-template","summary":"Get Flow Template","description":"Retrieve a flow template by id.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested flow template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowTemplate"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"delete-template","summary":"Delete Flow Template","description":"Delete a flow template.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Template deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-template","summary":"Update Flow Template","description":"Replace a flow template. The whole template is replaced, not patched field-by-field.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated flow template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowTemplate"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateFlowTemplateRequest"}}}}}},"/v1/agents/flow/templates/{id}/clone":{"post":{"operationId":"clone-template","summary":"Clone Flow Template","description":"Clone a flow template onto an agent as a new draft graph.","tags":["subpackage_tts.subpackage_tts/flow"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The agent's new draft graph.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:FlowGraph"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"500":{"description":"An unexpected server-side error occurred. Safe to retry with\nexponential backoff for idempotent requests.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CloneFlowTemplateRequest"}}}}}},"/v1/agents/conversations/{id}/shadow-token":{"post":{"operationId":"shadow-token","summary":"Mint shadow-call token","description":"Mint a listen-only LiveKit access token so an authorized observer\ncan join an ongoing voice-agent conversation as a hidden\nparticipant. Caller must be an `owner` or `admin` of the\nworkspace the conversation belongs to. The token cannot publish\naudio or data; the observer is invisible to the caller and the\nagent. Speechify support engineers reach this endpoint the same\nway as any other observer \u2014 by being granted the owner/admin\nrole on the customer's workspace (typically under an NDA-backed\nsupport arrangement).\n","tags":["subpackage_tts.subpackage_tts/admin"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Shadow-call connection details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ShadowConversationResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"403":{"description":"The credential authenticated, but is not authorised for this\nresource - typically a workspace-role gate (owner / admin\nrequired) or a cross-tenant access attempt.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/conversations/{id}/end":{"post":{"operationId":"force-end","summary":"Force-end conversation","description":"Force-terminate the LiveKit room for an ongoing conversation.\nIdempotent: rooms that LiveKit has already cleaned up return\n204 the same as a successful first-time termination. Same\nowner/admin role gating as the shadow-token endpoint.\n","tags":["subpackage_tts.subpackage_tts/admin"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Conversation ended.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"403":{"description":"The credential authenticated, but is not authorised for this\nresource - typically a workspace-role gate (owner / admin\nrequired) or a cross-tenant access attempt.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/batch-calls":{"post":{"operationId":"create","summary":"Create Batch Call","description":"Dial a list of phone numbers through one of your voice agents in a\nsingle request. Each recipient can receive personalised dynamic\nvariables that your agent prompt references via `{{key}}` placeholders.\nBatches can run immediately or be scheduled up to 30 days in advance.\n\nAccepts `application/json` or `multipart/form-data` (with a CSV file).\nMax 1000 recipients per batch.\n","tags":["subpackage_tts.subpackage_tts/batchCalls"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Batch accepted for processing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateBatchCallResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateBatchCallRequest"}}}}},"get":{"operationId":"list","summary":"List Batch Calls","description":"Returns one page of batch calls for the workspace, newest first.\nPaginate by passing `cursor` from the previous response.\n","tags":["subpackage_tts.subpackage_tts/batchCalls"],"parameters":[{"name":"cursor","in":"query","description":"Opaque cursor from a prior response's `next_cursor`.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size. Defaults to 50; capped at 200.","required":false,"schema":{"type":"integer","default":50}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListBatchCallsResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/batch-calls/{id}":{"get":{"operationId":"get","summary":"Get Batch Call","description":"Returns the batch row plus all recipients so the detail view renders\nwithout a second round-trip.\n","tags":["subpackage_tts.subpackage_tts/batchCalls"],"parameters":[{"name":"id","in":"path","description":"Batch call ID.","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:GetBatchCallResponse"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/batch-calls/{id}/cancel":{"post":{"operationId":"cancel","summary":"Cancel Batch Call","description":"Cancels a scheduled or pending batch before it starts dialing.\nReturns 409 if the batch is already running or completed.\n","tags":["subpackage_tts.subpackage_tts/batchCalls"],"parameters":[{"name":"id","in":"path","description":"Batch call ID.","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Batch cancelled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateBatchCallResponse"}}}},"409":{"description":"The request conflicts with the current resource state - e.g.\nduplicate, optimistic-concurrency mismatch, or last-owner\nguard.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/outbound-calls":{"post":{"operationId":"create","summary":"Create Outbound Call","description":"Place an outbound call from an agent to a phone number. LiveKit\noriginates the SIP INVITE through the outbound trunk bound to the\nagent's workspace; the agent worker is dispatched into the room\nautomatically.\n\nThe response is returned as soon as LiveKit accepts the INVITE.\nPoll `GET /v1/agents/conversations/{conversation_id}` for status\ntransitions: `pending` \u2192 `active` (answered) \u2192 `completed`.\n\nRequires a Twilio or BYOC trunk. LiveKit-native numbers are\ninbound-only.\n","tags":["subpackage_tts.subpackage_tts/outboundCalls"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The outbound call was accepted by LiveKit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateOutboundCallResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateOutboundCallRequest"}}}}}},"/v1/agents/phone-numbers":{"post":{"operationId":"import","summary":"Import Phone Number","description":"Import a phone number into the workspace. The `source` field\ndetermines the provisioning path:\n\n- `livekit` - LiveKit purchases the number on your behalf. US\n inbound only. Quickest path for local testing.\n- `twilio` - Provide your Twilio Account SID, Auth Token, and\n the E.164 number you already own. We provision an Elastic SIP\n Trunk on your Twilio account automatically.\n- `byoc` - Provide an existing SIP trunk ID. The number is\n registered against that trunk.\n\nReturns 402 when the workspace has reached the 100-number cap.\n","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The imported phone number.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PhoneNumber"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"402":{"description":"The workspace has insufficient credits, or the request needs a\nplan tier the workspace is not on (e.g. voice cloning). Distinct\nfrom `Forbidden` so SDK consumers can drive upgrade UX.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ImportPhoneNumberRequest"}}}}},"get":{"operationId":"list","summary":"List Phone Numbers","description":"List all phone numbers in the caller's workspace.","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The phone numbers for the workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListPhoneNumbersResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/phone-numbers/{id}":{"get":{"operationId":"get","summary":"Get Phone Number","description":"Retrieve a phone number by ID.","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested phone number.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PhoneNumber"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update","summary":"Update Phone Number","description":"Update a phone number. Only `label` and `agent_id` are mutable;\n`source` and `e164` are immutable after import. Pass `null` for\n`agent_id` to unbind the number from its current agent.\n","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The updated phone number.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PhoneNumber"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdatePhoneNumberRequest"}}}}},"delete":{"operationId":"delete","summary":"Delete Phone Number","description":"Delete a phone number from the workspace. For Twilio and LiveKit\nnumbers this also deprovisions the backing SIP trunk and dispatch\nrule on LiveKit Cloud.\n","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Phone number deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/phone-numbers/available":{"get":{"operationId":"search-available","summary":"Search Available Phone Numbers","description":"Search carrier inventory for phone numbers available to purchase.\nCurrently restricted to the US (`country=US`); pass `area_code`\nto narrow to a specific NPA. The returned numbers are not held;\na subsequent `POST /v1/agents/phone-numbers/purchase` against the same\nE.164 may fail with 4xx if the number has been taken in the\nmeantime.\n","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"country","in":"query","description":"ISO-3166 alpha-2 country code. Defaults to \"US\"; only \"US\" is supported in v1.","required":false,"schema":{"type":"string","default":"US"}},{"name":"area_code","in":"query","description":"Three-digit NPA to filter inventory to a region.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max results to return. Capped at 50.","required":false,"schema":{"type":"integer","default":20}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Available numbers (may be empty if no inventory matches).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:SearchAvailablePhoneNumbersResponse"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"503":{"description":"A downstream dependency is degraded or the endpoint is\nintentionally disabled (e.g. phone-number purchase before\nops setup).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/phone-numbers/purchase":{"post":{"operationId":"purchase","summary":"Purchase Phone Number","description":"Purchase a phone number on Speechify's master Twilio account.\nThe number is billed to Speechify until released; each\nworkspace is capped at a small number of purchased numbers\n(see 422 response) independent of the overall 100-number cap.\n`e164` must come from a recent `SearchAvailablePhoneNumbers`\nresponse \u2014 carriers reject buys against numbers that are no\nlonger in inventory. The returned phone number is wired for\nboth inbound (when `agent_id` is set, or after a later\n`PATCH`) and outbound calls (via the workspace's shared\noutbound trunk).\n","tags":["subpackage_tts.subpackage_tts/phoneNumbers"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The purchased phone number.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PhoneNumber"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"422":{"description":"The request was well-formed but semantically rejected -\ntypically a referential integrity violation (e.g. flow node\nreferences an audio asset in another workspace) or a state\nmachine refusal.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"503":{"description":"A downstream dependency is degraded or the endpoint is\nintentionally disabled (e.g. phone-number purchase before\nops setup).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:PurchasePhoneNumberRequest"}}}}}},"/v1/agents/sip-trunks":{"post":{"operationId":"create","summary":"Create SIP Trunk","description":"Create a SIP trunk. For `kind=byoc` supply `sip_address` plus\noptional digest credentials and IP allowlist. For `kind=twilio`\nuse `ImportPhoneNumber` with a `twilio` spec instead - trunk\ncreation is handled automatically. Returns 402 when the workspace\nhas reached the 20-trunk cap.\n","tags":["subpackage_tts.subpackage_tts/sipTrunks"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"The created SIP trunk.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:SIPTrunk"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"402":{"description":"The workspace has insufficient credits, or the request needs a\nplan tier the workspace is not on (e.g. voice cloning). Distinct\nfrom `Forbidden` so SDK consumers can drive upgrade UX.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:CreateSIPTrunkRequest"}}}}},"get":{"operationId":"list","summary":"List SIP Trunks","description":"List all SIP trunks in the caller's workspace.","tags":["subpackage_tts.subpackage_tts/sipTrunks"],"parameters":[{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The SIP trunks for the workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListSIPTrunksResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/sip-trunks/{id}":{"get":{"operationId":"get","summary":"Get SIP Trunk","description":"Retrieve a SIP trunk by ID.","tags":["subpackage_tts.subpackage_tts/sipTrunks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested SIP trunk.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:SIPTrunk"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"delete":{"operationId":"delete","summary":"Delete SIP Trunk","description":"Delete a SIP trunk. This also removes the backing LiveKit inbound\ntrunk, outbound trunk, and dispatch rule if they were provisioned\nby us. Phone numbers attached to this trunk are left in place but\nbecome non-functional until rebound to a new trunk.\n","tags":["subpackage_tts.subpackage_tts/sipTrunks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"SIP trunk deleted.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/ivr-menus":{"get":{"operationId":"list","summary":"List IVR Menus","description":"List the active IVR menus the caller's workspace has learned\n(AIS-3267 Phase 2/1.6/3). One row per (fingerprint, tenant).\nInvalidated rows and the cross-tenant shared slot are excluded.\nSorted by `last_observed_at` DESC so the freshest IVRs land at\nthe top. Capped at 200 rows.\n\nSee `docs/adrs/0009-ivr-memory-consume-and-invalidate.md` for the\nmemorization design.\n","tags":["subpackage_tts.subpackage_tts/ivrMemory"],"parameters":[{"name":"fingerprint","in":"query","description":"Optional SHA-256 fingerprint hash to narrow the list to one menu.","required":false,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of cached IVR menus.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:ListIVRMenusResponse"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}}},"/v1/agents/ivr-menus/{id}":{"get":{"operationId":"get","summary":"Get IVR Menu","description":"Fetch one menu's full shape. Returns 404 for missing,\nsoft-deleted, or foreign-tenant menus \u2014 existence information\nis never leaked across tenants.\n","tags":["subpackage_tts.subpackage_tts/ivrMemory"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The IVR menu detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:IVRMenu"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}}},"patch":{"operationId":"update-label","summary":"Update IVR Menu Option Label","description":"Re-label one option in the stored menu_tree, matched on the\nsupplied DTMF value. The label is what the console displays in\nthe detail panel and what the worker reads back at navigate\ntime to surface the option semantically. Unknown DTMF values\nare a no-op (the response echoes the unchanged menu).\n","tags":["subpackage_tts.subpackage_tts/ivrMemory"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The refreshed menu shape.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:IVRMenu"}}}},"400":{"description":"The request was malformed or failed validation. The response\nbody is the standard `Error` envelope; for validation\nfailures `error.fields` enumerates the offending fields as\na `path -> message` map (code = `validation_failed`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:UpdateIVRMenuLabelRequest"}}}}}},"/v1/agents/ivr-menus/{id}/invalidate":{"post":{"operationId":"invalidate","summary":"Invalidate IVR Menu","description":"Soft-invalidate the named menu. Future lookups skip it; the\nnext discovery for the same fingerprint replaces it (clearing\nthe invalidation, see ADR 0009 \u00a74). Idempotent: re-invalidating\nan already-invalidated row returns 404.\n\nReason is optional and is captured in structured logs for\noperator triage. A future audit table may persist it.\n","tags":["subpackage_tts.subpackage_tts/ivrMemory"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Authorization","in":"header","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'.","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Menu invalidated.","content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"401":{"description":"Authentication is missing or invalid. The request did not\ncarry a recognised credential (Firebase ID token, API key, or\nworker JWT).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}},"404":{"description":"The referenced resource does not exist or is not visible to\nthe caller's workspace.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/tts:InvalidateIVRMenuRequest"}}}}}}},"servers":[{"url":"https://api.speechify.ai","description":"https://api.speechify.ai"}],"components":{"schemas":{"tts:GetSpeechRequestAudioFormat":{"type":"string","enum":["wav","mp3","ogg","aac","pcm"],"default":"wav","description":"The format for the output audio. Note, that the current default is \"wav\", but there's no guarantee it will not change in the future. We recommend always passing the specific param you expect.","title":"GetSpeechRequestAudioFormat"},"tts:GetSpeechRequestModel":{"type":"string","enum":["simba-english","simba-multilingual","simba-3.0"],"default":"simba-english","description":"Model used for audio synthesis. `simba-english` is optimized for English, `simba-multilingual` for non-English or mixed input. `simba-3.0` is the streaming-native model with lower TTFB and richer expressivity. Currently English only; multilingual coming soon. Non-English voices return 400 until multilingual support ships.","title":"GetSpeechRequestModel"},"tts:GetSpeechOptionsRequest":{"type":"object","properties":{"loudness_normalization":{"type":"boolean","default":false,"description":"Determines whether to normalize the audio loudness to a standard level.\nWhen enabled, loudness normalization aligns the audio output to the following standards:\nIntegrated loudness: -14 LUFS\nTrue peak: -2 dBTP\nLoudness range: 7 LU\nIf disabled, the audio loudness will match the original loudness of the selected voice, which may vary significantly and be either too quiet or too loud.\nEnabling loudness normalization can increase latency due to additional processing required for audio level adjustments."},"text_normalization":{"type":"boolean","default":true,"description":"Determines whether to normalize the text. If enabled, it will transform numbers, dates, etc. into words. For example, \"55\" is normalized into \"fifty five\".\nThis can increase latency due to additional processing required for text normalization."}},"description":"GetSpeechOptionsRequest is the wrapper for request parameters to the client","title":"GetSpeechOptionsRequest"},"tts:GetSpeechRequest":{"type":"object","properties":{"audio_format":{"$ref":"#/components/schemas/tts:GetSpeechRequestAudioFormat","default":"wav","description":"The format for the output audio. Note, that the current default is \"wav\", but there's no guarantee it will not change in the future. We recommend always passing the specific param you expect."},"input":{"type":"string","description":"Plain text or SSML to be synthesized to speech.\nRefer to https://docs.speechify.ai/docs/api-limits for the input size limits.\nEmotion, Pitch and Speed Rate are configured in the ssml input, please refer to the ssml documentation for more information: https://docs.speechify.ai/docs/ssml#prosody"},"language":{"type":"string","description":"Language of the input. Follow the format of an ISO 639-1 language code and an ISO 3166-1 region code, separated by a hyphen, e.g. en-US.\nPlease refer to the list of the supported languages and recommendations regarding this parameter: https://docs.speechify.ai/docs/language-support."},"model":{"$ref":"#/components/schemas/tts:GetSpeechRequestModel","default":"simba-english","description":"Model used for audio synthesis. `simba-english` is optimized for English, `simba-multilingual` for non-English or mixed input. `simba-3.0` is the streaming-native model with lower TTFB and richer expressivity. Currently English only; multilingual coming soon. Non-English voices return 400 until multilingual support ships."},"options":{"$ref":"#/components/schemas/tts:GetSpeechOptionsRequest"},"voice_id":{"type":"string","description":"Id of the voice to be used for synthesizing speech. Refer to /v1/voices endpoint for available voices"}},"required":["input","voice_id"],"description":"Request body for POST /v1/audio/speech.","title":"GetSpeechRequest"},"tts:GetSpeechResponseAudioFormat":{"type":"string","enum":["wav","mp3","ogg","aac","pcm"],"description":"The format of the audio data","title":"GetSpeechResponseAudioFormat"},"tts:NestedChunk":{"type":"object","properties":{"end":{"type":"integer","format":"int64"},"end_time":{"type":"number","format":"double"},"start":{"type":"integer","format":"int64"},"start_time":{"type":"number","format":"double"},"type":{"type":"string"},"value":{"type":"string"}},"description":"It details the type of segment, its start and end points in the text, and its start and end times in the synthesized speech audio.","title":"NestedChunk"},"tts:SpeechMarks":{"type":"object","properties":{"chunks":{"type":"array","items":{"$ref":"#/components/schemas/tts:NestedChunk"},"description":"Array of NestedChunk, each providing detailed segment information within the synthesized speech."},"end":{"type":"integer","format":"int64"},"end_time":{"type":"number","format":"double"},"start":{"type":"integer","format":"int64"},"start_time":{"type":"number","format":"double"},"type":{"type":"string"},"value":{"type":"string"}},"required":["chunks","end","end_time","start","start_time","type"],"description":"It is used to annotate the audio data with metadata about the synthesis process, like word timing or phoneme details.","title":"SpeechMarks"},"tts:GetSpeechResponse":{"type":"object","properties":{"audio_data":{"type":"string","format":"byte","description":"Synthesized speech audio, Base64-encoded"},"audio_format":{"$ref":"#/components/schemas/tts:GetSpeechResponseAudioFormat","description":"The format of the audio data"},"billable_characters_count":{"type":"integer","format":"int64","description":"The number of billable characters processed in the request."},"speech_marks":{"$ref":"#/components/schemas/tts:SpeechMarks"}},"required":["audio_data","audio_format","billable_characters_count","speech_marks"],"title":"GetSpeechResponse"},"tts:ErrorCode":{"type":"string","enum":["bad_request","validation_failed","unauthorized","payment_required","forbidden","not_found","method_not_allowed","conflict","payload_too_large","unsupported_media_type","rate_limited","internal_error","upstream_failure","service_unavailable","caller_not_found","credential_not_found","payment_method_required"],"description":"Stable machine-readable error code. Additive only: codes are\nnever renamed, only deprecated. SDKs may map each code to a\ntyped exception class. Status-code semantics:\n4xx codes describe caller-fixable issues; 5xx codes describe\nserver-side failures and are safe to retry with backoff for\nidempotent requests.\n","title":"ErrorCode"},"tts:ErrorDetail":{"type":"object","properties":{"code":{"$ref":"#/components/schemas/tts:ErrorCode"},"message":{"type":"string","description":"Human-readable explanation of this specific occurrence.\nSafe to surface in UI banners or pass to support. The\nwording can change between releases; clients should\nmatch on `code`, not on the message string.\n"},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Per-field validation errors as `path -> message`. Only\npresent on 400 responses caused by request validation\n(typically code=`validation_failed`). Keys are field\npaths in dotted/bracket notation; values are short\nhuman explanations safe to inline-surface next to the\noffending form field.\n"}},"required":["code","message"],"title":"ErrorDetail"},"tts:Error":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/tts:ErrorDetail"},"request_id":{"type":"string","description":"Server-side request identifier. Echoes the\n`X-Request-ID` response header. Stable across the\nrequest's lifetime, written to structured logs, and\nuseful when reporting issues.\n"}},"required":["error"],"description":"Standard error envelope returned on every non-2xx response.\nContent-Type is `application/json`. The shape mirrors OpenAI /\nAnthropic / Stripe style: a machine-readable `error.code` for\nSDK consumers to switch on, a human `error.message` for UI,\nand an optional `error.fields` map for per-field validation\nerrors. `request_id` matches the `X-Request-ID` response\nheader and is what customers quote when filing support\ntickets.\n","title":"Error"},"tts:V1AudioStreamPostParametersAccept":{"type":"string","enum":["audio/mpeg","audio/ogg","audio/aac","audio/pcm"],"title":"V1AudioStreamPostParametersAccept"},"tts:GetStreamRequestModel":{"type":"string","enum":["simba-english","simba-multilingual","simba-3.0"],"default":"simba-english","description":"Model used for audio synthesis. `simba-english` is optimized for English, `simba-multilingual` for non-English or mixed input. `simba-3.0` is the streaming-native model with lower TTFB and richer expressivity. Currently English only; multilingual coming soon. Non-English voices return 400 until multilingual support ships.","title":"GetStreamRequestModel"},"tts:GetStreamOptionsRequest":{"type":"object","properties":{"loudness_normalization":{"type":"boolean","default":false,"description":"Determines whether to normalize the audio loudness to a standard level.\nWhen enabled, loudness normalization aligns the audio output to the following standards:\nIntegrated loudness: -14 LUFS\nTrue peak: -2 dBTP\nLoudness range: 7 LU\nIf disabled, the audio loudness will match the original loudness of the selected voice, which may vary significantly and be either too quiet or too loud.\nEnabling loudness normalization can increase latency due to additional processing required for audio level adjustments."},"text_normalization":{"type":"boolean","default":false,"description":"Determines whether to normalize the text. If enabled, it will transform numbers, dates, etc. into words. For example, \"55\" is normalized into \"fifty five\".\nThis can increase latency due to additional processing required for text normalization."}},"description":"GetStreamOptionsRequest is the wrapper for request parameters to the client","title":"GetStreamOptionsRequest"},"tts:GetStreamRequest":{"type":"object","properties":{"input":{"type":"string","description":"Plain text or SSML to be synthesized to speech.\nRefer to https://docs.speechify.ai/docs/api-limits for the input size limits.\nEmotion, Pitch and Speed Rate are configured in the ssml input, please refer to the ssml documentation for more information: https://docs.speechify.ai/docs/ssml#prosody"},"language":{"type":"string","description":"Language of the input. Follow the format of an ISO 639-1 language code and an ISO 3166-1 region code, separated by a hyphen, e.g. en-US.\nPlease refer to the list of the supported languages and recommendations regarding this parameter: https://docs.speechify.ai/docs/language-support."},"model":{"$ref":"#/components/schemas/tts:GetStreamRequestModel","default":"simba-english","description":"Model used for audio synthesis. `simba-english` is optimized for English, `simba-multilingual` for non-English or mixed input. `simba-3.0` is the streaming-native model with lower TTFB and richer expressivity. Currently English only; multilingual coming soon. Non-English voices return 400 until multilingual support ships."},"options":{"$ref":"#/components/schemas/tts:GetStreamOptionsRequest"},"voice_id":{"type":"string","description":"Id of the voice to be used for synthesizing speech. Refer to /v1/voices endpoint for available voices"}},"required":["input","voice_id"],"description":"GetStreamRequest is the wrapper for request parameters to the client","title":"GetStreamRequest"},"tts:GetVoiceGender":{"type":"string","enum":["male","female","notSpecified"],"title":"GetVoiceGender"},"tts:GetVoiceLanguage":{"type":"object","properties":{"locale":{"type":"string"},"preview_audio":{"type":["string","null"]}},"required":["locale"],"title":"GetVoiceLanguage"},"tts:GetVoicesModelName":{"type":"string","enum":["simba-english","simba-multilingual","simba-3.0"],"title":"GetVoicesModelName"},"tts:GetVoicesModel":{"type":"object","properties":{"languages":{"type":"array","items":{"$ref":"#/components/schemas/tts:GetVoiceLanguage"}},"name":{"$ref":"#/components/schemas/tts:GetVoicesModelName"}},"required":["languages","name"],"title":"GetVoicesModel"},"tts:GetVoiceType":{"type":"string","enum":["shared","personal"],"title":"GetVoiceType"},"tts:GetVoice":{"type":"object","properties":{"avatar_image":{"type":["string","null"]},"display_name":{"type":"string"},"gender":{"$ref":"#/components/schemas/tts:GetVoiceGender"},"locale":{"type":"string"},"id":{"type":"string"},"models":{"type":"array","items":{"$ref":"#/components/schemas/tts:GetVoicesModel"}},"preview_audio":{"type":["string","null"]},"tags":{"type":["array","null"],"items":{"type":"string"}},"type":{"$ref":"#/components/schemas/tts:GetVoiceType"}},"required":["display_name","gender","locale","id","models","type"],"title":"GetVoice"},"tts:V1VoicesPostRequestBodyContentMultipartFormDataSchemaGender":{"type":"string","enum":["male","female","notSpecified"],"description":"Gender marker for the personal voice\nmale GenderMale\nfemale GenderFemale\nnotSpecified GenderNotSpecified","title":"V1VoicesPostRequestBodyContentMultipartFormDataSchemaGender"},"tts:CreatedVoiceGender":{"type":"string","enum":["male","female","notSpecified"],"title":"CreatedVoiceGender"},"tts:CreateVoiceLanguage":{"type":"object","properties":{"locale":{"type":"string"},"preview_audio":{"type":["string","null"]}},"title":"CreateVoiceLanguage"},"tts:CreateVoiceModelName":{"type":"string","enum":["simba-english","simba-multilingual","simba-3.0"],"title":"CreateVoiceModelName"},"tts:CreateVoiceModel":{"type":"object","properties":{"languages":{"type":"array","items":{"$ref":"#/components/schemas/tts:CreateVoiceLanguage"}},"name":{"$ref":"#/components/schemas/tts:CreateVoiceModelName"}},"title":"CreateVoiceModel"},"tts:CreatedVoiceType":{"type":"string","enum":["shared","personal"],"title":"CreatedVoiceType"},"tts:CreatedVoice":{"type":"object","properties":{"avatar_image":{"type":"string"},"display_name":{"type":"string"},"gender":{"$ref":"#/components/schemas/tts:CreatedVoiceGender"},"locale":{"type":"string"},"id":{"type":"string"},"models":{"type":"array","items":{"$ref":"#/components/schemas/tts:CreateVoiceModel"}},"type":{"$ref":"#/components/schemas/tts:CreatedVoiceType"}},"required":["display_name","gender","locale","id","models","type"],"title":"CreatedVoice"},"tts:CreateAgentRequestLlmProvider":{"type":"string","enum":["openai","speechify","custom",""],"description":"LLM backend. Leave empty (or omit both `llm_provider` and\n`llm_model`) to use the platform default (today: Speechify\nKimi K2.6, resolved server-side at dispatch). When set,\nmust be paired with a non-empty `llm_model`; mixing a\npopulated provider with an empty model is rejected as a\n400. `custom` additionally requires `llm_base_url`.\n","title":"CreateAgentRequestLlmProvider"},"tts:WidgetConfigStyle":{"type":"string","enum":["pill","fab"],"title":"WidgetConfigStyle"},"tts:WidgetConfigTheme":{"type":"string","enum":["dark","light","auto"],"title":"WidgetConfigTheme"},"tts:WidgetConfigAvatarType":{"type":"string","enum":["orb","image"],"title":"WidgetConfigAvatarType"},"tts:WidgetConfigAvatar":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/tts:WidgetConfigAvatarType"},"image_url":{"type":"string"},"orb_color_1":{"type":"string"},"orb_color_2":{"type":"string"}},"title":"WidgetConfigAvatar"},"tts:WidgetConfigText":{"type":"object","properties":{"start_call":{"type":"string"},"end_call":{"type":"string"},"listening":{"type":"string"},"thinking":{"type":"string"},"speaking":{"type":"string"}},"title":"WidgetConfigText"},"tts:WidgetConfigTerms":{"type":"object","properties":{"enabled":{"type":"boolean"},"content":{"type":"string"}},"title":"WidgetConfigTerms"},"tts:WidgetConfigTranscript":{"type":"object","properties":{"enabled":{"type":"boolean"}},"title":"WidgetConfigTranscript"},"tts:WidgetConfig":{"type":"object","properties":{"version":{"type":"integer"},"style":{"$ref":"#/components/schemas/tts:WidgetConfigStyle"},"theme":{"$ref":"#/components/schemas/tts:WidgetConfigTheme"},"avatar":{"$ref":"#/components/schemas/tts:WidgetConfigAvatar"},"text":{"$ref":"#/components/schemas/tts:WidgetConfigText"},"terms":{"$ref":"#/components/schemas/tts:WidgetConfigTerms"},"transcript":{"$ref":"#/components/schemas/tts:WidgetConfigTranscript"}},"description":"Customer-editable appearance + behaviour payload for the\nembedded `` pill: button text, avatar style,\norb colours, terms-and-conditions markdown, transcript display.\nEvery field is optional - empty fields fall back to the\nwidget's compile-time defaults.\n","title":"WidgetConfig"},"tts:AmdConfigOnVoicemailAction":{"type":"string","enum":["hangup","leave_message"],"title":"AmdConfigOnVoicemailAction"},"tts:AmdConfigOnVoicemail":{"type":"object","properties":{"action":{"$ref":"#/components/schemas/tts:AmdConfigOnVoicemailAction"},"message":{"type":"string","description":"Spoken before terminating when action=leave_message.\nSupports {{variable}} substitution. Required (non-empty)\nwhen action=leave_message; rejected by the validator\notherwise.\n"}},"required":["action"],"description":"Action when AMD returns category=machine-vm.","title":"AmdConfigOnVoicemail"},"tts:AmdConfigOnIvrAction":{"type":"string","enum":["proceed","hangup","navigate"],"description":"proceed: hand control to the agent's flow as if the\ncalled party were human. hangup: terminate immediately.\nnavigate: hand control to the IVR Navigator subagent\nwith menu-memoization-aware session config (cache hit\nseeds the agent context; cache miss triggers cold\ndiscovery and the post-call pipeline extracts the\nmenu for future calls).\n","title":"AmdConfigOnIvrAction"},"tts:AmdConfigOnIvr":{"type":"object","properties":{"action":{"$ref":"#/components/schemas/tts:AmdConfigOnIvrAction","description":"proceed: hand control to the agent's flow as if the\ncalled party were human. hangup: terminate immediately.\nnavigate: hand control to the IVR Navigator subagent\nwith menu-memoization-aware session config (cache hit\nseeds the agent context; cache miss triggers cold\ndiscovery and the post-call pipeline extracts the\nmenu for future calls).\n"}},"required":["action"],"description":"Action when AMD returns category=machine-ivr.","title":"AmdConfigOnIvr"},"tts:AmdConfigOnUnavailableAction":{"type":"string","enum":["hangup"],"title":"AmdConfigOnUnavailableAction"},"tts:AmdConfigOnUnavailable":{"type":"object","properties":{"action":{"$ref":"#/components/schemas/tts:AmdConfigOnUnavailableAction"}},"required":["action"],"description":"Action when AMD returns category=machine-unavailable (mailbox full or disconnected).","title":"AmdConfigOnUnavailable"},"tts:AmdConfigTuning":{"type":"object","properties":{"human_speech_threshold_seconds":{"type":"number","format":"double"},"no_speech_threshold_seconds":{"type":"number","format":"double"},"timeout_seconds":{"type":"number","format":"double"},"classification_prompt":{"type":"string"}},"description":"Optional overrides for LiveKit's detection thresholds and\ntimeouts. Cross-field rule (enforced at the application\nvalidator): `timeout_seconds` must be greater than or equal\nto `no_speech_threshold_seconds` when both are set.\n","title":"AmdConfigTuning"},"tts:AMDConfig":{"type":"object","properties":{"enabled":{"type":"boolean","description":"When false, the worker skips AMD entirely. When true, the\nworker runs AMD on the called party's greeting before\ndelivering the agent's first message and dispatches per\nresult.category. The per-route fields below are still\nrequired by the schema regardless of `enabled` state so a\ncustomer flipping `enabled: false \u2192 true` ships coherent\nroute configuration immediately.\n"},"on_voicemail":{"$ref":"#/components/schemas/tts:AmdConfigOnVoicemail","description":"Action when AMD returns category=machine-vm."},"on_ivr":{"$ref":"#/components/schemas/tts:AmdConfigOnIvr","description":"Action when AMD returns category=machine-ivr."},"on_unavailable":{"$ref":"#/components/schemas/tts:AmdConfigOnUnavailable","description":"Action when AMD returns category=machine-unavailable (mailbox full or disconnected)."},"tuning":{"$ref":"#/components/schemas/tts:AmdConfigTuning","description":"Optional overrides for LiveKit's detection thresholds and\ntimeouts. Cross-field rule (enforced at the application\nvalidator): `timeout_seconds` must be greater than or equal\nto `no_speech_threshold_seconds` when both are set.\n"}},"required":["enabled","on_voicemail","on_ivr","on_unavailable"],"description":"Answering Machine Detection routing config for outbound voice\nagents. AMD classifies the called party's first ~3-15 seconds of\naudio into one of LiveKit's categories (human, uncertain,\nmachine-vm, machine-ivr, machine-unavailable) and dispatches per\ncategory to the configured action. Stored on the agent row;\nflowed onto outbound dispatch metadata under the `amd` key.\nRationale: see ADR 0008 (docs/adrs/0008-amd-as-session-routing-primitive.md).\n","title":"AMDConfig"},"tts:CreateAgentRequestSttOverride":{"type":"string","enum":["flux","whisper-v3","gpt-realtime-whisper"],"description":"Optional non-default streaming-STT stack for this agent.\nOmit to use the worker's default stack (today: whisper-v3).\nSee the Agent schema for the full option semantics.\n","title":"CreateAgentRequestSttOverride"},"tts:CreateAgentRequest":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string","description":"Optional. Server derives slug from name with a random suffix when omitted; if you supply your own, a collision returns 400 'slug already taken'."},"prompt":{"type":"string"},"first_message":{"type":"string","description":"Greeting spoken verbatim at session start when included in the agent's flow graph."},"language":{"type":"string","description":"ISO 639-1 code. Defaults to 'en' when omitted."},"llm_provider":{"$ref":"#/components/schemas/tts:CreateAgentRequestLlmProvider","description":"LLM backend. Leave empty (or omit both `llm_provider` and\n`llm_model`) to use the platform default (today: Speechify\nKimi K2.6, resolved server-side at dispatch). When set,\nmust be paired with a non-empty `llm_model`; mixing a\npopulated provider with an empty model is rejected as a\n400. `custom` additionally requires `llm_base_url`.\n"},"llm_model":{"type":"string","description":"Chat model slug. Leave empty to use the platform default.\nFor `openai` / `speechify` the (provider, model) pair must\nbe in the allowed table; for `custom` it is free-form.\n"},"llm_base_url":{"type":"string","description":"Custom OpenAI/vLLM-compatible endpoint base URL. Required\nwhen `llm_provider` is `custom`, rejected otherwise.\n"},"llm_api_key":{"type":"string","description":"Bearer key for the custom endpoint. Write-only - stored\nencrypted, never returned (GET exposes `llm_api_key_set`).\nOptional even for `custom` (keyless endpoints); rejected\nfor any other provider.\n"},"llm_extra_body":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Optional JSON object forwarded verbatim to the custom\nendpoint as the chat.completions `extra_body` (reasoning /\nsampling knobs). Valid only when `llm_provider` is\n`custom`.\n"},"voice_id":{"type":"string","description":"Voice slug from the VMS catalog (see GET /v1/voices). Required \u2014 the server rejects writes with an unknown or empty slug."},"temperature":{"type":"number","format":"double","description":"0.0..1.0. Defaults to 0.7 when omitted."},"widget_config":{"$ref":"#/components/schemas/tts:WidgetConfig"},"is_public":{"type":"boolean","description":"Defaults to false when omitted."},"allowed_origins":{"type":"array","items":{"type":"string"}},"hostname_allowlist":{"type":"array","items":{"type":"string"},"description":"Optional per-agent hostname allowlist (see Agent schema)."},"memory_enabled":{"type":"boolean","description":"Defaults to false when omitted."},"memory_retention_days":{"type":"integer","description":"Defaults to 90 when omitted."},"webhook_url":{"type":"string","description":"Customer-facing post-call webhook URL."},"webhook_secret":{"type":"string","description":"HMAC-SHA256 secret seed. Write-only \u2014 never echoed back on\nreads; clients see `webhook_secret_set: true` instead.\n"},"amd":{"$ref":"#/components/schemas/tts:AMDConfig","description":"AMD routing config. Optional on create; omitted means AMD off. See AMDConfig schema."},"save_audio_recording":{"type":"boolean","description":"When set, opts the agent into per-conversation audio recording. Defaults to false when omitted."},"navigator_mode":{"type":"boolean","description":"When set, opts the agent into IVR-tuned turn handling. Defaults to false when omitted."},"ivr_memory_enabled":{"type":"boolean","description":"When omitted, defaults to true. Set to false to opt-out of the IVR-memory cache lookup for this agent."},"tts_speaking_rate":{"type":["number","null"],"format":"double"},"tts_playback_rate":{"type":["number","null"],"format":"double","description":"Post-process pitch-preserving time-stretch on the synthesized\naudio. See the field on Agent for semantics.\n"},"response_delay_seconds":{"type":["number","null"],"format":"double","description":"Per-agent override for the worker's endpointing min_delay on\nthe VAD path (seconds). See the field on Agent for semantics.\nRange 0.0..5.0; null means use the stack default.\n"},"inactivity_timeout_seconds":{"type":"integer","description":"Per-agent silence-tolerance override in seconds. Send `0`\nto clear the override and fall back to the platform\ndefault. Negative values are rejected.\n"},"background_noise_preset":{"type":"string","description":"Pre-mixed ambient bed slug. Send empty string (\"\") to\ndisable the bed, which also clears `background_noise_volume`.\n"},"background_noise_volume":{"type":"number","format":"double","description":"Volume of the background-noise bed (0..1). Ignored when\n`background_noise_preset` is empty.\n"},"stt_override":{"$ref":"#/components/schemas/tts:CreateAgentRequestSttOverride","description":"Optional non-default streaming-STT stack for this agent.\nOmit to use the worker's default stack (today: whisper-v3).\nSee the Agent schema for the full option semantics.\n"}},"required":["name","voice_id"],"title":"CreateAgentRequest"},"tts:AgentLlmProvider":{"type":"string","enum":["openai","speechify","custom"],"description":"LLM backend the worker constructs for this agent. Null\nmeans \"use the platform default\" (resolved server-side at\ndispatch; today: Speechify Kimi K2.6). `openai` and\n`speechify` pair with a model from the allowed (provider,\nmodel) table. `custom` points the worker at any OpenAI /\nvLLM-compatible endpoint - see `llm_base_url`,\n`llm_api_key`, `llm_extra_body`.\n","title":"AgentLlmProvider"},"tts:AgentSttOverride":{"type":"string","enum":["flux","whisper-v3","gpt-realtime-whisper"],"description":"Optional override for the streaming-STT stack this agent\ndispatches with. Null means use the worker's default\nstack (today: whisper-v3, Baseten Whisper Large V3). Pick\n`whisper-v3` to pin Whisper Large V3 explicitly, `flux` to\nopt into Deepgram Flux's semantic end-of-turn detection, or\n`gpt-realtime-whisper` for OpenAI's streaming Whisper-class\nSTT.\n","title":"AgentSttOverride"},"tts:Agent":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`).\nADR 0015 Cluster 1 hard-break: this is the sole customer-facing\nidentifier. URL paths accept only this prefixed form; legacy\nUUID path parameters are rejected with 404 as of Cluster 1.\n"},"name":{"type":"string"},"slug":{"type":"string"},"prompt":{"type":"string"},"first_message":{"type":"string","description":"Spoken verbatim at session start when present in the customer's flow graph."},"language":{"type":"string","description":"ISO 639-1 code, e.g. 'en'."},"llm_provider":{"$ref":"#/components/schemas/tts:AgentLlmProvider","description":"LLM backend the worker constructs for this agent. Null\nmeans \"use the platform default\" (resolved server-side at\ndispatch; today: Speechify Kimi K2.6). `openai` and\n`speechify` pair with a model from the allowed (provider,\nmodel) table. `custom` points the worker at any OpenAI /\nvLLM-compatible endpoint - see `llm_base_url`,\n`llm_api_key`, `llm_extra_body`.\n"},"llm_model":{"type":["string","null"],"description":"Chat model slug. Null means \"use the platform default\"\n(resolved server-side at dispatch; today: Speechify Kimi\nK2.6). For `openai` / `speechify` it must be a slug from\nthe allowed table; for `custom` it is free-form (the\ncustomer's endpoint owns the namespace).\n"},"llm_base_url":{"type":["string","null"],"description":"Custom OpenAI/vLLM-compatible endpoint base URL. Non-null\nonly when `llm_provider` is `custom`.\n"},"llm_api_key_set":{"type":"boolean","description":"Whether a bearer key is stored for the custom endpoint.\nThe key itself is write-only and never returned.\n"},"llm_extra_body":{"type":["object","null"],"additionalProperties":{"description":"Any type"},"description":"JSON object forwarded verbatim to the custom endpoint as\nthe chat.completions `extra_body` (reasoning / sampling\nknobs). Non-null only when `llm_provider` is `custom`.\n"},"voice_id":{"type":"string","description":"Speechify voice slug."},"temperature":{"type":"number","format":"double"},"widget_config":{"$ref":"#/components/schemas/tts:WidgetConfig"},"is_public":{"type":"boolean","description":"When true, the `` web component can start a\nsession against this agent without an API key, subject to\nthe `allowed_origins` allowlist. When false (default), only\nauthenticated callers can start sessions.\n"},"allowed_origins":{"type":"array","items":{"type":"string"},"description":"Exact `Origin` header values (e.g. `https://example.com`)\nthat are allowed to start public sessions. Empty array\nwith `is_public = true` means any origin is accepted \u2014\nintended for open demos. No subdomain wildcards.\n"},"hostname_allowlist":{"type":["array","null"],"items":{"type":"string"},"description":"Optional per-agent hostname allowlist enforced at\nsession-creation time. When set and non-empty, the\n`Origin` header's hostname must be an exact member.\nBare hostnames only \u2014 no scheme, port, or path. Up to\n10 entries. Omit (null) or leave empty for no\nenforcement (public agents accept any hostname).\n"},"memory_enabled":{"type":"boolean","description":"When true, the post-call extractor writes durable facts about\neach caller; at conversation-start the retriever injects the\ntop matches into the system prompt via the `{{memory}}`\ntemplate variable. Defaults to false.\n"},"memory_retention_days":{"type":"integer","description":"Maximum age (in days) of memories kept and surfaced to the\nretriever. 0 disables the cap. Defaults to 90.\n"},"webhook_url":{"type":"string","description":"Customer-facing post-call webhook target. When non-empty,\nthe control plane POSTs a signed payload (transcript +\nevals + extractors + recording URL) once the conversation\ncompletes. Empty disables the fire path.\n"},"webhook_secret_set":{"type":"boolean","description":"True when an HMAC-SHA256 webhook secret is configured. The\nsecret itself is write-only \u2014 supplied on PATCH and never\nechoed back on reads.\n"},"amd":{"$ref":"#/components/schemas/tts:AMDConfig"},"save_audio_recording":{"type":"boolean","description":"When true, every conversation produces a room-composite\nOGG egress uploaded to the recordings bucket. Defaults\nFALSE for new agents (privacy by default).\n"},"navigator_mode":{"type":"boolean","description":"Tunes worker turn handling for autonomous outbound IVR\nnavigation - longer endpointing and no barge-in. The goal\nitself lives in the agent's prompt; this flag is the\nbehaviour switch only. Defaults FALSE.\n"},"ivr_memory_enabled":{"type":"boolean","description":"Per-agent kill switch for the IVR-memory cache lookup\nperformed at AMD time. Defaults TRUE so existing navigator\nagents keep their always-on behaviour. Set to false to skip\nthe cache and force every outbound dial on this agent to\nstart cold (LLM-driven navigation only).\n"},"tts_speaking_rate":{"type":["number","null"],"format":"double","description":"Per-agent override for the voice's default speaking rate\n(0.5 = half speed, 2.0 = double, 1.0 = neutral). Null\nmeans \"use the voice's default rate\".\n"},"tts_playback_rate":{"type":["number","null"],"format":"double","description":"Per-agent post-process pitch-preserving time-stretch applied\nto the synthesized audio in the worker before publishing.\nDistinct from tts_speaking_rate: speaking_rate biases the\nmodel's generation prosody (clipped syllables, pauses\npreserved); playback_rate uniformly stretches the rendered\nwaveform (every sample, every pause, every breath). Range\n0.5..3.0; null means no post-process.\n"},"response_delay_seconds":{"type":["number","null"],"format":"double","description":"How long the agent waits after the caller stops talking\nbefore generating a reply (the worker's endpointing\nmin_delay on the VAD path). Range 0.0..5.0. Null means\n\"use the stack default\" \u2014 Deepgram VAD: 0.5s, or 0.75s\nwhen `navigator_mode=true`. Ignored on Flux + Whisper\nSTT, which use semantic turn detection instead.\n"},"inactivity_timeout_seconds":{"type":["integer","null"],"description":"Optional override for the per-agent silence-tolerance\nbefore the worker tears the call down. Null means use\nthe platform default.\n"},"background_noise_preset":{"type":["string","null"],"description":"Optional pre-mixed ambient bed (e.g. office, cafe). Null\ndisables background noise.\n"},"background_noise_volume":{"type":["number","null"],"format":"double","description":"Volume of the background-noise bed. Null disables."},"stt_override":{"$ref":"#/components/schemas/tts:AgentSttOverride","description":"Optional override for the streaming-STT stack this agent\ndispatches with. Null means use the worker's default\nstack (today: whisper-v3, Baseten Whisper Large V3). Pick\n`whisper-v3` to pin Whisper Large V3 explicitly, `flux` to\nopt into Deepgram Flux's semantic end-of-turn detection, or\n`gpt-realtime-whisper` for OpenAI's streaming Whisper-class\nSTT.\n"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","slug","prompt","first_message","language","llm_provider","llm_model","voice_id","temperature","is_public","allowed_origins","memory_enabled","memory_retention_days","amd","save_audio_recording","navigator_mode","ivr_memory_enabled","created_at","updated_at"],"title":"Agent"},"tts:ListAgentsResponse":{"type":"object","properties":{"agents":{"type":"array","items":{"$ref":"#/components/schemas/tts:Agent"}}},"required":["agents"],"title":"ListAgentsResponse"},"tts:UpdateAgentRequestLlmProvider":{"type":"string","enum":["openai","speechify","custom",""],"description":"LLM backend. Send an empty string together with\n`llm_model: \"\"` to clear the pair to the platform default\n(today: Speechify Kimi K2.6). Sending one populated and\none empty is rejected as a 400. Omit both to leave the\nstored pair unchanged. Switching to a non-`custom` provider\nclears any stored `llm_base_url` / `llm_api_key` /\n`llm_extra_body`.\n","title":"UpdateAgentRequestLlmProvider"},"tts:UpdateAgentRequestSttOverride":{"type":"string","enum":["flux","whisper-v3","gpt-realtime-whisper",""],"description":"Streaming-STT stack override. Send an empty string (\"\") to\nclear the override and fall back to the worker default\n(today: whisper-v3). Any non-empty value must be a known\nstack name.\n","title":"UpdateAgentRequestSttOverride"},"tts:UpdateAgentRequest":{"type":"object","properties":{"name":{"type":"string"},"prompt":{"type":"string"},"first_message":{"type":"string"},"language":{"type":"string"},"llm_provider":{"$ref":"#/components/schemas/tts:UpdateAgentRequestLlmProvider","description":"LLM backend. Send an empty string together with\n`llm_model: \"\"` to clear the pair to the platform default\n(today: Speechify Kimi K2.6). Sending one populated and\none empty is rejected as a 400. Omit both to leave the\nstored pair unchanged. Switching to a non-`custom` provider\nclears any stored `llm_base_url` / `llm_api_key` /\n`llm_extra_body`.\n"},"llm_model":{"type":"string","description":"Chat model slug. Empty string + empty `llm_provider`\nclears the pair to the platform default. For `openai` /\n`speechify` the (provider, model) pair must be in the\nallowed table; for `custom` it is free-form.\n"},"llm_base_url":{"type":"string","description":"Custom-endpoint base URL. Required when the resulting\nprovider is `custom`, rejected otherwise.\n"},"llm_api_key":{"type":"string","description":"Bearer key for the custom endpoint. Write-only. Omit to\nkeep the stored key, send \"\" to clear it, send a value to\nreplace it. Rejected for non-`custom` providers.\n"},"llm_extra_body":{"type":"object","additionalProperties":{"description":"Any type"},"description":"JSON object forwarded to the custom endpoint as\nchat.completions `extra_body`. Omit to leave unchanged;\na JSON object (including `{}`) replaces it. Valid only\nwhen the resulting provider is `custom`.\n"},"voice_id":{"type":"string"},"temperature":{"type":"number","format":"double"},"widget_config":{"$ref":"#/components/schemas/tts:WidgetConfig"},"is_public":{"type":"boolean"},"allowed_origins":{"type":"array","items":{"type":"string"}},"hostname_allowlist":{"type":"array","items":{"type":"string"},"description":"When supplied, replaces the stored list. Pass an empty\narray to clear enforcement (public agent is open again).\nOmit the field to leave the existing value unchanged.\n"},"memory_enabled":{"type":"boolean"},"memory_retention_days":{"type":"integer"},"webhook_url":{"type":"string"},"webhook_secret":{"type":"string","description":"Rotate the HMAC secret. Write-only."},"amd":{"$ref":"#/components/schemas/tts:AMDConfig","description":"AMD routing config (PATCH-replace, wholesale). Omit to leave the stored config unchanged."},"save_audio_recording":{"type":"boolean"},"navigator_mode":{"type":"boolean"},"ivr_memory_enabled":{"type":"boolean","description":"Per-agent kill switch for the IVR-memory cache lookup. nil/omit = unchanged."},"tts_speaking_rate":{"type":["number","null"],"format":"double"},"clear_tts_speaking_rate":{"type":"boolean","description":"Two-headed clear: PATCH cannot distinguish \"absent\" from\n\"explicit null\" reliably across stacks. Setting this to\n`true` resets `tts_speaking_rate` to the voice default.\nIf both are sent, `clear_tts_speaking_rate` wins.\n"},"tts_playback_rate":{"type":["number","null"],"format":"double"},"clear_tts_playback_rate":{"type":"boolean","description":"Two-headed clear, mirroring `clear_tts_speaking_rate`.\nSetting this to `true` resets `tts_playback_rate` to null\n(no post-process). If both fields are sent,\n`clear_tts_playback_rate` wins.\n"},"response_delay_seconds":{"type":["number","null"],"format":"double","description":"Per-agent silence-wait override (seconds). See the field\non Agent for semantics. Range 0.0..5.0; null is allowed\nbut `clear_response_delay_seconds=true` is the canonical\nway to revert to the stack default.\n"},"clear_response_delay_seconds":{"type":"boolean","description":"Two-headed clear, mirroring `clear_tts_playback_rate`.\nSetting this to `true` resets `response_delay_seconds` to\nnull (revert to the stack default). If both are sent,\n`clear_response_delay_seconds` wins.\n"},"inactivity_timeout_seconds":{"type":"integer","description":"Per-agent silence-tolerance override. Send `0` to clear\nthe override and fall back to the platform default.\nNegative values are rejected.\n"},"background_noise_preset":{"type":"string","description":"Pre-mixed ambient bed slug. Send empty string (\"\") to\ndisable the bed, which also clears `background_noise_volume`.\n"},"background_noise_volume":{"type":"number","format":"double","description":"Volume of the background-noise bed (0..1). Ignored when\nthe preset is empty; clearing the preset also clears\nthis field server-side.\n"},"stt_override":{"$ref":"#/components/schemas/tts:UpdateAgentRequestSttOverride","description":"Streaming-STT stack override. Send an empty string (\"\") to\nclear the override and fall back to the worker default\n(today: whisper-v3). Any non-empty value must be a known\nstack name.\n"}},"description":"Body for PATCH /v1/agents/{id}. Every field is optional;\nomitting a field leaves it unchanged. `slug` is intentionally\nnot patchable (changing it would break embed URLs).\n","title":"UpdateAgentRequest"},"tts:CreateConversationRequest":{"type":"object","properties":{"transport":{"type":["string","null"],"description":"Transport hint. Omit to use the agent's default."},"dynamic_variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-session variable overrides that merge on top of the agent's\nstored variable defaults for this one conversation. Keys in the\nreserved `system__` namespace are rejected. Values must match the\ndeclared type of the corresponding variable definition on the agent.\n"}},"description":"Optional body for `POST /v1/agents/{id}/conversations`.","title":"CreateConversationRequest"},"tts:ConversationStatus":{"type":"string","enum":["pending","active","completed","failed"],"title":"ConversationStatus"},"tts:ConversationTransport":{"type":"string","enum":["web","phone","whatsapp","sip_inbound","sip_outbound"],"description":"How the caller reached the agent. `web` is the browser /\nSDK realtime path; the `sip_*` and `phone` variants come\nfrom the telephony stack.\n","title":"ConversationTransport"},"tts:ConversationEndReason":{"type":"string","enum":["voicemail_message_left","voicemail_hangup","ivr_hangup","unavailable_hangup","agent_ended","caller_hangup","inactivity_timeout","loop_detected","max_duration_reached","over_capacity"],"description":"Coarse termination category. Worker-stamped reasons arrive\nbefore `terminate_call` fires; `caller_hangup` has two\nemit sites (worker-observed SIP disconnect, plus a\nserver-side post-call catch-all).\n* `voicemail_message_left` \u2014 AMD machine-vm + we spoke the configured drop-message.\n* `voicemail_hangup` \u2014 AMD machine-vm + we terminated silently (action=hangup or empty-message bypass).\n* `ivr_hangup` \u2014 AMD machine-ivr + action=hangup.\n* `unavailable_hangup` \u2014 AMD machine-unavailable (mailbox full / disconnected).\n* `agent_ended` \u2014 LLM-driven end_call builtin.\n* `inactivity_timeout` \u2014 worker's inactivity handler fired terminate after the configured silence window.\n* `loop_detected` \u2014 worker's runtime loop guard force-ended the call after N consecutive near-identical user turns (typically an IVR replaying its menu while the LLM kept reacting instead of calling end_call).\n* `max_duration_reached` - worker's max-call-duration watchdog force-ended the call at the platform ceiling (a safety bound on runaway calls).\n* `over_capacity` \u2014 inbound call refused because the workspace was over its active-call concurrency cap; the busy message played and the call hung up. Stamped server-side and excluded from billing.\n* `caller_hangup` \u2014 caller's leg went away. Precise when the worker observed the SIP `participant_disconnected` event (stamped immediately); otherwise stamped server-side ~10s after `room_finished` as a catch-all (web tab close, network blip, worker crash, etc.).\n* `null` \u2014 pre-rollout calls only (anything that landed after the rollout completes without a stamp gets `caller_hangup` from the post-call goroutine).\n","title":"ConversationEndReason"},"tts:AgentSnapshot":{"type":"object","properties":{"schema_version":{"type":"integer"},"captured_at":{"type":"string","format":"date-time"},"name":{"type":"string"},"prompt":{"type":"string"},"first_message":{"type":"string"},"language":{"type":"string"},"llm_model":{"type":"string"},"voice_id":{"type":"string"},"temperature":{"type":"number","format":"double"},"memory_enabled":{"type":"boolean"},"memory_retention_days":{"type":"integer"},"tts_speaking_rate":{"type":["number","null"],"format":"double"},"tts_playback_rate":{"type":["number","null"],"format":"double"},"response_delay_seconds":{"type":["number","null"],"format":"double"}},"description":"Frozen subset of the agent's configuration captured at\nconversation-create time (AIS-2778) so the detail view can\nrender historical calls accurately even after the live\nagent's prompt or voice has been edited. Carries its own\n`schema_version` because the snapshot shape evolves\nindependently of the live Agent shape.\n","title":"AgentSnapshot"},"tts:ConversationIvrSurrenderReason":{"type":"string","enum":["no_goal","no_cached_menu","below_threshold","fingerprint_mismatch","goal_ambiguous","child_cache_miss","dtmf_send_failure","matched_option_missing_dtmf","disabled","repeated_prompt_max_retries"],"description":"AIS-3322 canonical code the worker emits when the IVR\nnavigator gave up. NULL when the navigator completed\ncleanly OR never started a plan.\n* `no_goal` - the goal extractor returned empty.\n* `no_cached_menu` - AMD-time cache miss for the root fingerprint.\n* `below_threshold` - cached menu loaded but confidence < threshold.\n* `fingerprint_mismatch` - in-call prompt diverged from the cached menu fingerprint.\n* `goal_ambiguous` - cached options matched the goal more than once or not at all.\n* `child_cache_miss` - sub-menu fingerprint had no cached row.\n* `dtmf_send_failure` - DTMF press could not be delivered.\n* `matched_option_missing_dtmf` - defensive shape guard.\n* `disabled` - per-agent toggle off OR operator kill switch on.\n* `repeated_prompt_max_retries` - bounded press-retry on the same fingerprint hit its cap of 1.\n","title":"ConversationIvrSurrenderReason"},"tts:Conversation":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`conv_<26 char Crockford base32>`).\nADR 0015 Cluster 2 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 2.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nfor the agent that answers this conversation. ADR 0015\nFK consistency: customer-facing responses emit the prefixed\nform, never raw UUIDs.\n"},"room_name":{"type":"string","description":"LiveKit room name. Equals the conversation `id` for `web`\nand `sip_outbound` transports; `sip_inbound` rooms use a\n`sip__` name assigned by the SIP dispatch rule.\n"},"room_sid":{"type":"string"},"status":{"$ref":"#/components/schemas/tts:ConversationStatus"},"transport":{"$ref":"#/components/schemas/tts:ConversationTransport"},"created_at":{"type":"string","format":"date-time","description":"When the conversation row was created (the call was\ninitiated). Always present, including for conversations\nthat never started \u2014 unlike `started_at` \u2014 so it is the\ntimestamp to display and sort pending calls by.\n"},"started_at":{"type":["string","null"],"format":"date-time","description":"Set when the first user participant joins the realtime\nvoice session. Null between CreateConversation and the\nparticipant-joined event, and stays null if no user ever\njoins.\n"},"ended_at":{"type":["string","null"],"format":"date-time"},"duration_ms":{"type":["integer","null"]},"cost_cents":{"type":["integer","null"]},"recording_url":{"type":["string","null"]},"recording_started_at":{"type":["string","null"],"format":"date-time","description":"When the recording file actually began capturing audio\n(LiveKit egress file started_at). Anchor transcript message\noffsets on this \u2014 not `started_at` \u2014 when seeking the\nrecording: the file's first frame trails the participant\njoin by the egress recorder's spin-up (~1-2s). Null when\nthere is no recording or the row pre-dates the field.\n"},"end_reason":{"$ref":"#/components/schemas/tts:ConversationEndReason","description":"Coarse termination category. Worker-stamped reasons arrive\nbefore `terminate_call` fires; `caller_hangup` has two\nemit sites (worker-observed SIP disconnect, plus a\nserver-side post-call catch-all).\n* `voicemail_message_left` \u2014 AMD machine-vm + we spoke the configured drop-message.\n* `voicemail_hangup` \u2014 AMD machine-vm + we terminated silently (action=hangup or empty-message bypass).\n* `ivr_hangup` \u2014 AMD machine-ivr + action=hangup.\n* `unavailable_hangup` \u2014 AMD machine-unavailable (mailbox full / disconnected).\n* `agent_ended` \u2014 LLM-driven end_call builtin.\n* `inactivity_timeout` \u2014 worker's inactivity handler fired terminate after the configured silence window.\n* `loop_detected` \u2014 worker's runtime loop guard force-ended the call after N consecutive near-identical user turns (typically an IVR replaying its menu while the LLM kept reacting instead of calling end_call).\n* `max_duration_reached` - worker's max-call-duration watchdog force-ended the call at the platform ceiling (a safety bound on runaway calls).\n* `over_capacity` \u2014 inbound call refused because the workspace was over its active-call concurrency cap; the busy message played and the call hung up. Stamped server-side and excluded from billing.\n* `caller_hangup` \u2014 caller's leg went away. Precise when the worker observed the SIP `participant_disconnected` event (stamped immediately); otherwise stamped server-side ~10s after `room_finished` as a catch-all (web tab close, network blip, worker crash, etc.).\n* `null` \u2014 pre-rollout calls only (anything that landed after the rollout completes without a stamp gets `caller_hangup` from the post-call goroutine).\n"},"metadata":{"type":"object","additionalProperties":{"description":"Any type"}},"caller_identity":{"type":"string","description":"Stable caller key (LiveKit participant identity) persisted\nat session start so the post-call memory extractor can\npivot memories by `(agent_id, caller_identity)`. Empty\nstring for anonymous widget sessions.\n"},"agent_snapshot":{"$ref":"#/components/schemas/tts:AgentSnapshot","description":"Frozen snapshot of the agent's configuration at create\ntime. Populated only on detail responses; list responses\nintentionally skip the column to keep the row small.\n"},"dynamic_variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Customer-facing dynamic variables this call ran with: the\nagent's stored variable defaults overlaid with the\nper-session `dynamic_variables` overrides, resolved to\ntheir values. Reserved `system__*` keys are excluded \u2014\nthey are runtime-derived and not part of the audit\nsnapshot. Omitted for SIP inbound calls (which take no\nper-session variables) and for any pre-rollout\nconversation. Populated only on detail responses; the\nlist endpoint skips it, mirroring `agent_snapshot`.\n"},"message_count":{"type":"integer","description":"Populated only on the list endpoint via a correlated\nsubquery. Zero on single-row reads where the join cost\nisn't paid.\n"},"ivr_menu_id":{"type":["string","null"],"description":"AIS-3322 audit pointer at the cached IVR menu the\nnavigator consulted on this call. NULL when the navigator\nnever engaged OR after the referenced menu was\ninvalidated (FK is ON DELETE SET NULL).\n"},"ivr_path_taken":{"type":["array","null"],"items":{"type":"object","additionalProperties":{"description":"Any type"}},"description":"AIS-3322 ordered log of the navigator's per-call presses:\n`[{fingerprint, dtmf, label}, ...]`. Empty array means\n\"navigator engaged but pressed nothing\" (distinct from\nNULL = \"navigator never engaged\").\n"},"ivr_surrender_reason":{"$ref":"#/components/schemas/tts:ConversationIvrSurrenderReason","description":"AIS-3322 canonical code the worker emits when the IVR\nnavigator gave up. NULL when the navigator completed\ncleanly OR never started a plan.\n* `no_goal` - the goal extractor returned empty.\n* `no_cached_menu` - AMD-time cache miss for the root fingerprint.\n* `below_threshold` - cached menu loaded but confidence < threshold.\n* `fingerprint_mismatch` - in-call prompt diverged from the cached menu fingerprint.\n* `goal_ambiguous` - cached options matched the goal more than once or not at all.\n* `child_cache_miss` - sub-menu fingerprint had no cached row.\n* `dtmf_send_failure` - DTMF press could not be delivered.\n* `matched_option_missing_dtmf` - defensive shape guard.\n* `disabled` - per-agent toggle off OR operator kill switch on.\n* `repeated_prompt_max_retries` - bounded press-retry on the same fingerprint hit its cap of 1.\n"}},"required":["id","agent_id","room_name","status","transport","created_at","metadata","message_count"],"title":"Conversation"},"tts:CreateConversationResponse":{"type":"object","properties":{"conversation":{"$ref":"#/components/schemas/tts:Conversation"},"room":{"type":"string"},"token":{"type":"string","description":"Short-lived realtime session access token (JWT)."},"url":{"type":"string","description":"Realtime session wss:// URL to connect to."}},"required":["conversation","room","token","url"],"description":"Returned when a conversation is created. The `token` + `url`\nlet the caller connect its browser/SDK directly to the\nrealtime voice session \u2014 the agent that answers is dispatched\nserver-side.\n","title":"CreateConversationResponse"},"tts:CreateSessionRequest":{"type":"object","properties":{"user_identity":{"type":"string","description":"Opaque identifier for the end-user (e.g. your app's user ID). Stamped onto the conversation. Optional - defaults to an anonymous per-session ID."},"dynamic_variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-session variable overrides that merge on top of the agent's\nstored variable defaults for this one session. Keys in the\nreserved `system__` namespace are rejected at this boundary.\nValues must match the declared type of the corresponding variable\ndefinition on the agent (a `string` type expects a JSON string,\n`number` expects a JSON number, etc.).\n"}},"description":"Optional body for `POST /v1/agents/{id}/sessions`. Widget embeds usually pass nothing.","title":"CreateSessionRequest"},"tts:AgentVoiceType":{"type":"string","enum":["shared"],"description":"Voice provenance. Always `shared` on this endpoint \u2014 personal\n/ cloned voices are not exposed here; they stay on\n`GET /v1/voices`.\n","title":"AgentVoiceType"},"tts:AgentVoiceModelName":{"type":"string","enum":["simba-english","simba-multilingual"],"title":"AgentVoiceModelName"},"tts:AgentVoiceLanguage":{"type":"object","properties":{"locale":{"type":"string","description":"BCP-47-ish locale tag (e.g. `en-US`, `de-DE`)."},"preview_audio":{"type":["string","null"],"description":"URL to a short audio preview for this locale, or null if\nno preview is available.\n"}},"required":["locale","preview_audio"],"title":"AgentVoiceLanguage"},"tts:AgentVoiceModel":{"type":"object","properties":{"name":{"$ref":"#/components/schemas/tts:AgentVoiceModelName"},"languages":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentVoiceLanguage"}}},"required":["name","languages"],"description":"One TTS engine the voice can be synthesised through. Each\nagent voice exposes a multilingual model, plus an\nenglish-specific model for voices whose locale starts with\n`en`.\n","title":"AgentVoiceModel"},"tts:AgentVoiceGender":{"type":"string","enum":["male","female","notSpecified"],"description":"Speaker gender as classified by VMS. `notSpecified` is used\nwhen the source dataset didn't carry the metadata; the\nconsole treats it as a neutral display label rather than a\nfilter gap.\n","title":"AgentVoiceGender"},"tts:AgentVoice":{"type":"object","properties":{"id":{"type":"string","description":"Voice slug. Passed verbatim as `voice_id` on agent writes."},"type":{"$ref":"#/components/schemas/tts:AgentVoiceType"},"display_name":{"type":"string"},"models":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentVoiceModel"}},"gender":{"$ref":"#/components/schemas/tts:AgentVoiceGender"},"locale":{"type":"string","description":"Default locale for the voice (BCP-47-ish, e.g. `en-US`)."},"preview_audio":{"type":["string","null"],"description":"Preferred preview clip URL, locale-matched when possible."},"avatar_image":{"type":["string","null"],"description":"Avatar URL for the picker UI. Null when no avatar is\nconfigured; the wire is intentionally `null` rather than\n`\"\"` so the picker doesn't render a broken ` `.\n"},"tags":{"type":["array","null"],"items":{"type":"string"},"description":"VMS-defined tags (e.g. `narrator`, `young`)."}},"required":["id","type","display_name","models","gender","locale","preview_audio","avatar_image"],"description":"One row in the curated voice catalogue returned by\n`GET /v1/agents/voices`. Matches the slug set accepted by\nagent create/update.\n","title":"AgentVoice"},"tts:SystemBuiltin":{"type":"string","description":"Identifier of a worker-resident system builtin. New entries are\nadded together on the server (a new `tool_builtin_.go`\nfile) and worker (`tools/builtins/.py`) - the 2-file rule\nAIS-3053 pins. Customers read the catalogue from\n`GET /v1/agents/tools/system-builtins` rather than depending on this\nstring set staying stable across releases.\n","title":"SystemBuiltin"},"tts:CreateAgentBuiltinRequest":{"type":"object","properties":{"builtin":{"$ref":"#/components/schemas/tts:SystemBuiltin"},"name":{"type":"string","description":"LLM-facing tool name. Must match the tool-name regex and be unique within the agent's builtin set."},"description":{"type":"string"},"config":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-instance configuration matching the per-builtin schema."},"params":{"type":"array","items":{"type":"object","additionalProperties":{"description":"Any type"}},"description":"Per-call parameter descriptors."},"enabled":{"type":"boolean","description":"Defaults to true on the server when omitted."}},"required":["builtin","name"],"title":"CreateAgentBuiltinRequest"},"tts:AgentBuiltin":{"type":"object","properties":{"id":{"type":"string","description":"Opaque builtin instance ID."},"tenant_id":{"type":"string","description":"The workspace owning this instance."},"agent_id":{"type":"string","description":"The agent this instance is bound to."},"builtin":{"$ref":"#/components/schemas/tts:SystemBuiltin"},"name":{"type":"string","description":"LLM-facing tool name. Unique within the agent's builtin set."},"description":{"type":"string","description":"LLM-facing one-line description of when to call the tool."},"config":{"type":["object","null"],"additionalProperties":{"description":"Any type"},"description":"Per-instance configuration shape. The schema depends on\n`builtin` \u2014 see the per-builtin contracts under\n`/contracts/tools/system_*.schema.json`. Null when the\nbuiltin takes no instance-level config.\n"},"params":{"type":["array","null"],"items":{"type":"object","additionalProperties":{"description":"Any type"}},"description":"Per-call parameter schema fragment merged into the model's\ntool spec. Each entry is one parameter descriptor (the\nper-builtin contract pins the exact shape). Null when the\nbuiltin takes no caller arguments.\n"},"enabled":{"type":"boolean","description":"When false, the instance is persisted but skipped at dispatch."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","tenant_id","agent_id","builtin","name","description","enabled","created_at","updated_at"],"description":"One instance of a system builtin bound to a specific agent.\nStorage lives in the `agent_builtins` table (migration 00061);\nwire format intentionally matches the legacy `kind=\"system\"`\nTool shape so the worker is untouched by the AIS-3116 split.\n","title":"AgentBuiltin"},"tts:ListAgentBuiltinsResponse":{"type":"object","properties":{"builtins":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentBuiltin"}}},"required":["builtins"],"title":"ListAgentBuiltinsResponse"},"tts:UpdateAgentBuiltinRequest":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"config":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-instance configuration matching the per-builtin schema."},"params":{"type":"array","items":{"type":"object","additionalProperties":{"description":"Any type"}},"description":"Per-call parameter descriptors."},"enabled":{"type":"boolean"}},"description":"PATCH body. All fields optional; omitting a field leaves it\nunchanged. The underlying `builtin` is NOT patchable \u2014 delete\nand recreate to change which capability an instance maps to.\n","title":"UpdateAgentBuiltinRequest"},"tts:DynamicVariableType":{"type":"string","enum":["string","number","boolean","json"],"description":"Declared type of a customer-scope variable. Enforced at save time\nand again at session-start when an override value is supplied.\n- `string` - plain text value; interpolated verbatim with `{{name}}`\n- `number` - numeric value; rendered as its decimal representation\n- `boolean` - `true` or `false`\n- `json` - any valid JSON value; use `{{name|json}}` to inject\n safely inside JSON tool bodies\n","title":"DynamicVariableType"},"tts:DynamicVariable":{"type":"object","properties":{"key":{"type":"string","description":"Variable name. Must match `[a-zA-Z0-9_]+`. The `system__` prefix\nis reserved for platform-populated variables and will be rejected.\n"},"type":{"$ref":"#/components/schemas/tts:DynamicVariableType"},"default":{"description":"Optional default value used when no per-session override is\nsupplied. Must conform to the declared `type`.\n"},"description":{"type":"string","description":"Human-readable note shown in the console variable editor."}},"required":["key","type"],"description":"One customer-scope variable definition on an agent. Referenced in\nprompts, first messages, and webhook tool configs via `{{key}}` or\n`{{key|json}}`. Missing variables render as empty string at dispatch\ntime - a typo never breaks a session.\n","title":"DynamicVariable"},"tts:SystemVariableDoc":{"type":"object","properties":{"key":{"type":"string","description":"The reserved variable key (always starts with `system__`)."},"description":{"type":"string","description":"What the variable contains and when it is populated."}},"required":["key","description"],"description":"Documents one reserved `system__*` variable that the platform\nauto-populates at session start. Customers cannot define or\noverride these keys.\n","title":"SystemVariableDoc"},"tts:ListDynamicVariablesResponse":{"type":"object","properties":{"variables":{"type":"array","items":{"$ref":"#/components/schemas/tts:DynamicVariable"},"description":"Customer-defined variables for this agent."},"system_variables":{"type":"array","items":{"$ref":"#/components/schemas/tts:SystemVariableDoc"},"description":"Platform-populated `system__*` variables, provided for\nreference. This list is the same for every agent.\n"}},"required":["variables","system_variables"],"description":"Response for `GET /v1/agents/{id}/variables`. Returns both the\ncustomer-scope variable catalogue and the read-only `system__*`\ncatalogue so the editor UI has a single source of truth.\n","title":"ListDynamicVariablesResponse"},"tts:UpdateDynamicVariablesRequest":{"type":"object","properties":{"variables":{"type":"array","items":{"$ref":"#/components/schemas/tts:DynamicVariable"},"description":"The new variable list. Replaces the existing list entirely."}},"required":["variables"],"description":"PATCH body for `PATCH /v1/agents/{id}/variables`. Replaces the\nstored variable list wholesale. Pass an empty array to clear all\nvariables. Up to 20 variables per agent.\n","title":"UpdateDynamicVariablesRequest"},"tts:EvaluationCriterion":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"}},"required":["id","name","description"],"description":"One LLM-scored assertion about the call (\"Did the agent confirm the customer's name?\").","title":"EvaluationCriterion"},"tts:DataCollectionFieldType":{"type":"string","enum":["string","int","number","boolean"],"title":"DataCollectionFieldType"},"tts:DataCollectionField":{"type":"object","properties":{"key":{"type":"string"},"description":{"type":"string"},"type":{"$ref":"#/components/schemas/tts:DataCollectionFieldType"}},"required":["key","description","type"],"description":"A structured value the post-call evaluator should extract from the\ntranscript. `int` is distinct from `number` so downstream consumers\nreceive whole integers without a synthetic decimal.\n","title":"DataCollectionField"},"tts:EvaluationConfig":{"type":"object","properties":{"criteria":{"type":"array","items":{"$ref":"#/components/schemas/tts:EvaluationCriterion"}},"data_collection":{"type":"array","items":{"$ref":"#/components/schemas/tts:DataCollectionField"}}},"required":["criteria","data_collection"],"title":"EvaluationConfig"},"tts:UpdateEvaluationConfigRequest":{"type":"object","properties":{"criteria":{"type":"array","items":{"$ref":"#/components/schemas/tts:EvaluationCriterion"}},"data_collection":{"type":"array","items":{"$ref":"#/components/schemas/tts:DataCollectionField"}}},"required":["criteria","data_collection"],"title":"UpdateEvaluationConfigRequest"},"tts:KnowledgeBase":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`kb_<26 char Crockford base32>`).\nADR 0015 Cluster 1 hard-break.\n"},"name":{"type":"string","description":"Human-readable label, shown in the console."},"description":{"type":"string","description":"Optional description."},"document_count":{"type":"integer","description":"Number of ingested documents."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","description","document_count","created_at","updated_at"],"description":"A bundle of documents that can be attached to one or more voice\nagents. Chunks across every document in the knowledge base are\nembedded and searched together.","title":"KnowledgeBase"},"tts:AttachedKnowledgeBasesResponse":{"type":"object","properties":{"knowledge_bases":{"type":"array","items":{"$ref":"#/components/schemas/tts:KnowledgeBase"}}},"required":["knowledge_bases"],"description":"Bare list of the knowledge bases attached to an agent. Not\npaginated \u2014 an agent's KB attachment count is naturally\nbounded (configuration, not data scale). See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the \"pagination only where needed\" rule.\n","title":"AttachedKnowledgeBasesResponse"},"tts:Memory":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`memory_<26 char Crockford base32>`).\nADR 0015 Cluster 2 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 2.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the owning agent. ADR 0015 FK consistency.\n"},"caller_identity":{"type":"string","description":"Stable caller key (LiveKit participant identity) the memory is scoped to."},"fact":{"type":"string","description":"Short third-person statement about the caller."},"source_conversation_id":{"type":["string","null"],"description":"When set, the prefixed wire identifier\n(`conv_<26 char Crockford base32>`) of the conversation this\nmemory was extracted from. May be null if the source was\ndeleted. ADR 0015 FK consistency.\n"},"confidence":{"type":"number","format":"double","description":"LLM self-reported 0-1 confidence in the fact's durability and relevance."},"score":{"type":"number","format":"double","description":"Populated only on retrieval hits \u2014 recency-weighted cosine similarity."},"created_at":{"type":"string","format":"date-time"}},"required":["id","agent_id","caller_identity","fact","confidence","created_at"],"description":"One salient fact extracted post-call about a specific caller on\na specific agent. Retrieved at the next conversation-start for\nthe same caller and injected into the agent's system prompt via\nthe `{{memory}}` template variable.","title":"Memory"},"tts:ListMemoriesResponse":{"type":"object","properties":{"memories":{"type":"array","items":{"$ref":"#/components/schemas/tts:Memory"}}},"required":["memories"],"title":"ListMemoriesResponse"},"tts:DeleteMemoriesByCallerRequest":{"type":"object","properties":{"agent_id":{"type":"string"},"caller_identity":{"type":"string"}},"required":["agent_id","caller_identity"],"title":"DeleteMemoriesByCallerRequest"},"tts:DeleteMemoriesByCallerResponse":{"type":"object","properties":{"deleted":{"type":"integer","description":"Number of memories soft-deleted."}},"required":["deleted"],"title":"DeleteMemoriesByCallerResponse"},"tts:TestType":{"type":"string","enum":["reply","tool","simulation"],"description":"Discriminates the shape of `AgentTest.config`.\n- `reply` - send one message to the agent and judge the response with an LLM.\n- `tool` - assert that the agent calls a specific tool given a context.\n- `simulation` - run a multi-turn conversation between the agent and an AI caller.\n","title":"TestType"},"tts:SimulationMessageRole":{"type":"string","enum":["user","assistant"],"title":"SimulationMessageRole"},"tts:SimulationMessage":{"type":"object","properties":{"role":{"$ref":"#/components/schemas/tts:SimulationMessageRole"},"content":{"type":"string"}},"required":["role","content"],"description":"One turn in a simulation conversation. `role` is `user` (the AI caller) or `assistant` (the agent).","title":"SimulationMessage"},"tts:ReplyConfig":{"type":"object","properties":{"context":{"type":"string","description":"User message sent to the agent to trigger the behaviour under test. Optional when `initial_chat_history` already ends with a user message."},"success_criteria":{"type":"string","description":"Natural-language description of what a passing agent response looks like."},"success_examples":{"type":"array","items":{"type":"string"},"description":"Concrete examples of passing responses (few-shot for the judge)."},"failure_examples":{"type":"array","items":{"type":"string"},"description":"Concrete examples of failing responses (few-shot for the judge)."},"initial_chat_history":{"type":"array","items":{"$ref":"#/components/schemas/tts:SimulationMessage"},"description":"Optional seed conversation prepended before `context`. Lets you test the agent's reply mid-conversation rather than on a cold single-turn prompt."},"system_prompt_override":{"type":"string","description":"Deprecated (AIS-3443). Prefer the run-level `config_override`\non `POST /v1/agents/{id}/tests/runs`, which applies a proposed\nprompt to every test in the run without editing each one.\nStill honoured; the run-level override wins when both are set.\nReplaces the agent's system prompt for this run only."},"first_message_override":{"type":"string","description":"Replaces the agent's first message for this run only."},"model_override":{"type":"string","description":"Deprecated (AIS-3443). Prefer the run-level `config_override`\non `POST /v1/agents/{id}/tests/runs`. Still honoured; the\nrun-level override wins when both are set. Overrides the LLM\nmodel used by the agent for this run only."}},"required":["success_criteria"],"description":"Configuration for a `reply` test. The runner sends `context` as\na user message and asks an LLM judge to evaluate the agent response\nagainst `success_criteria`. Optional few-shot examples sharpen the\njudge's calibration. Use `initial_chat_history` to prepend prior\nturns before `context`; when the history already ends with a user\nmessage, `context` may be omitted and the agent is evaluated on\nits reply to that last history turn.","title":"ReplyConfig"},"tts:ParameterCheckMode":{"type":"string","enum":["exact","regex","llm"],"description":"How a `ParameterCheck` validates a tool argument.\n- `exact` - JSON equality.\n- `regex` - the argument stringified is matched against the pattern.\n- `llm` - an LLM judge decides whether the value semantically satisfies\n the criteria (e.g. \"is a plausible email address\").\n","title":"ParameterCheckMode"},"tts:ParameterCheck":{"type":"object","properties":{"path":{"type":"string","description":"Dotted JSON path to the argument being checked. Empty means the whole args object."},"mode":{"$ref":"#/components/schemas/tts:ParameterCheckMode"},"expected":{"type":"string","description":"Expected value string for `exact` and `regex` modes."},"criteria":{"type":"string","description":"Natural-language criteria for `llm` mode (e.g. \"is a valid email address\")."}},"required":["path","mode"],"description":"Validates one argument of an expected tool call. `path` is a\ndotted JSON path (e.g. `customer.email`); use zero-indexed\nnotation for arrays (`items.0.sku`). An empty path checks the\nwhole args object.","title":"ParameterCheck"},"tts:ToolCallConfig":{"type":"object","properties":{"context":{"type":"string","description":"User message that should cause the agent to invoke the expected tool. Optional when `initial_chat_history` already ends with a user message."},"expected_tool":{"type":"string","description":"Name of the tool the agent is expected to call. Leave empty to\ninvert the assertion: the test passes only when the agent calls\nno tool at all."},"parameter_checks":{"type":"array","items":{"$ref":"#/components/schemas/tts:ParameterCheck"},"description":"Assertions on specific arguments of the tool call."},"initial_chat_history":{"type":"array","items":{"$ref":"#/components/schemas/tts:SimulationMessage"},"description":"Optional seed conversation prepended before `context`."},"system_prompt_override":{"type":"string","description":"Deprecated (AIS-3443). Prefer the run-level `config_override`\non `POST /v1/agents/{id}/tests/runs`. Still honoured; the\nrun-level override wins when both are set. Replaces the\nagent's system prompt for this run only."},"model_override":{"type":"string","description":"Deprecated (AIS-3443). Prefer the run-level `config_override`\non `POST /v1/agents/{id}/tests/runs`. Still honoured; the\nrun-level override wins when both are set. Overrides the LLM\nmodel used by the agent for this run only."}},"required":["expected_tool"],"description":"Configuration for a `tool` test. The runner sends `context` as a\nuser message and asserts that the agent calls `expected_tool` with\narguments matching all `parameter_checks`. Use\n`initial_chat_history` to test tool invocations that only make\nsense mid-conversation.","title":"ToolCallConfig"},"tts:DataAssertionMode":{"type":"string","enum":["exact","regex","llm"],"description":"How the assertion validates the extracted value.","title":"DataAssertionMode"},"tts:DataAssertion":{"type":"object","properties":{"key":{"type":"string","description":"Name of the data-collection field on the agent's evaluation config. The assertion fails when this key is missing from the extracted data."},"mode":{"$ref":"#/components/schemas/tts:DataAssertionMode","description":"How the assertion validates the extracted value."},"expected":{"type":"string","description":"Expected value string for `exact` and `regex` modes."},"criteria":{"type":"string","description":"Natural-language criteria for `llm` mode."}},"required":["key","mode"],"description":"Asserts on one entry in the LLM-extracted data-collection map\nproduced by the unified evaluator. `key` matches a\ndata-collection field configured on the agent; the assertion\nruns against the value the judge wrote under that key. Same\nexact / regex / llm modes as `ParameterCheck` so the tool-call\nand data-collection assertion surfaces are uniform.","title":"DataAssertion"},"tts:SimulationConfig":{"type":"object","properties":{"scenario":{"type":"string","description":"Instructions for the AI caller describing who they are and what they want."},"max_turns":{"type":"integer","default":5,"description":"Maximum agent turns before the simulation is cut off and judged."},"initial_chat_history":{"type":"array","items":{"$ref":"#/components/schemas/tts:SimulationMessage"},"description":"Optional seed conversation that precedes the AI caller's first generated message."},"data_assertions":{"type":"array","items":{"$ref":"#/components/schemas/tts:DataAssertion"},"description":"Optional assertions on the LLM-extracted data-collection\nmap. Each entry references a key from the agent's\ndata_collection config and validates the extracted value.\nThe test fails if any assertion fails."},"system_prompt_override":{"type":"string","description":"Deprecated (AIS-3443). Prefer the run-level `config_override`\non `POST /v1/agents/{id}/tests/runs`. Still honoured; the\nrun-level override wins when both are set. Replaces the\nagent's system prompt for this run only."},"model_override":{"type":"string","description":"Deprecated (AIS-3443). Prefer the run-level `config_override`\non `POST /v1/agents/{id}/tests/runs`. Still honoured; the\nrun-level override wins when both are set. Overrides the LLM\nmodel used by the agent for this run only."}},"required":["scenario"],"description":"Configuration for a `simulation` test. An AI caller drives a\nmulti-turn conversation with the agent according to `scenario`.\nAfter `max_turns` exchanges (or when the agent ends the call),\nthe unified post-call evaluator scores the synthetic transcript\nagainst the agent's configured evaluation criteria + data\ncollection fields. A test passes when no configured criterion\nfails and every `data_assertions` entry passes.","title":"SimulationConfig"},"tts:AgentTestConfig":{"oneOf":[{"$ref":"#/components/schemas/tts:ReplyConfig"},{"$ref":"#/components/schemas/tts:ToolCallConfig"},{"$ref":"#/components/schemas/tts:SimulationConfig"}],"description":"Type-specific configuration document.","title":"AgentTestConfig"},"tts:MockingStrategy":{"type":"string","enum":["none","all","selected"],"description":"Controls which tool calls the runner intercepts during a run.\nSystem tools (`end_call`, `transfer_to_number`, etc.) are never\nmocked regardless of strategy.\n- `none` - no interception; all tools are called normally.\n- `all` - every non-system tool call is intercepted and matched\n against the `mocks` list.\n- `selected` - only tools explicitly listed in `mocks` are\n intercepted; others are called normally.\n","title":"MockingStrategy"},"tts:ToolMock":{"type":"object","properties":{"tool_name":{"type":"string","description":"Name of the tool to intercept."},"args_match":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Optional structured argument matcher. When set, the mock fires\nonly if the tool call's arguments deep-contain every key/value\nin this object: nested objects match recursively as subsets,\narrays and scalar leaves match by deep equality. An empty\nobject matches unconditionally. When absent the mock matches\nunconditionally for this tool."},"response":{"description":"JSON value returned to the agent as the tool result."}},"required":["tool_name","response"],"description":"A canned response returned when the agent calls `tool_name`. If\n`args_match` is set the mock only triggers when the call arguments\ndeep-contain it (a structured subset match). A mock without\n`args_match` always matches for its tool.","title":"ToolMock"},"tts:NoMatchBehavior":{"type":"string","enum":["call_real_tool","finish_with_error","skip"],"description":"Fallback when a mockable tool is called but no configured mock\nmatches the call arguments.\n- `call_real_tool` - pass-through: actually invoke the underlying\n tool (a webhook tool POSTs to the customer endpoint). Use only\n when the real call is safe to make from a test.\n- `finish_with_error` - fail: the run finishes as a `failed`\n verdict. Useful when a test wants to assert that a specific\n mocked response path is taken - any unmocked tool call fails the\n test.\n- `skip` - return an empty stub (`{\"skipped\":true}`) to the agent so\n the simulation proceeds without treating the call as a failure.\n Useful when a tool's output is irrelevant to the behaviour under\n test but the model may still decide to call it. This is the\n default for a test with no mock configuration.\n","title":"NoMatchBehavior"},"tts:ToolMockConfig":{"type":"object","properties":{"strategy":{"$ref":"#/components/schemas/tts:MockingStrategy"},"mocks":{"type":"array","items":{"$ref":"#/components/schemas/tts:ToolMock"},"description":"Canned responses for specific tools (order matters - first match wins)."},"no_match_behavior":{"$ref":"#/components/schemas/tts:NoMatchBehavior"}},"required":["strategy","no_match_behavior"],"description":"Controls tool-call interception during a test run.","title":"ToolMockConfig"},"tts:TestRunStatus":{"type":"string","enum":["queued","running","passed","failed","error"],"description":"Lifecycle of a test run: `queued` - `running` - terminal.\n\nTerminal states:\n- `passed` - the agent behaviour met the success criteria.\n- `failed` - the agent behaviour did not meet the success criteria.\n- `error` - the runner itself could not complete (LLM outage, network error, etc.),\n distinct from `failed` which means the agent behaviour was judged and found lacking.\n","title":"TestRunStatus"},"tts:ReplyResult":{"type":"object","properties":{"agent_response":{"type":"string","description":"The raw text response the agent produced."},"passed":{"type":"boolean"},"rationale":{"type":"string","description":"LLM judge's explanation of the verdict."},"score":{"type":"number","format":"double","description":"0-1 judge confidence score."},"duration_ms":{"type":"integer","format":"int64","description":"Wall-clock time for the run in milliseconds."}},"required":["agent_response","passed","rationale","score","duration_ms"],"description":"Result details for a `reply` test run.","title":"ReplyResult"},"tts:ParameterCheckResult":{"type":"object","properties":{"path":{"type":"string"},"mode":{"$ref":"#/components/schemas/tts:ParameterCheckMode"},"actual_json":{"type":"string","description":"JSON-serialised actual value at `path`."},"passed":{"type":"boolean"},"rationale":{"type":"string","description":"LLM rationale (populated for `llm` mode checks)."}},"required":["path","mode","actual_json","passed"],"description":"Result of one `ParameterCheck` within a tool-call test run.","title":"ParameterCheckResult"},"tts:ToolCallResult":{"type":"object","properties":{"tool_called":{"type":"string","description":"Name of the tool the agent actually called (may differ from `expected_tool`)."},"tool_args":{"description":"Arguments the agent passed to the tool, as a JSON object."},"expected_tool":{"type":"string","description":"Name of the tool the test expected the agent to call."},"tool_matched":{"type":"boolean","description":"True when `tool_called` equals `expected_tool`."},"parameter_results":{"type":"array","items":{"$ref":"#/components/schemas/tts:ParameterCheckResult"}},"passed":{"type":"boolean"},"rationale":{"type":"string","description":"Explanation of the overall verdict."},"duration_ms":{"type":"integer","format":"int64"}},"required":["tool_called","expected_tool","tool_matched","parameter_results","passed","rationale","duration_ms"],"description":"Result details for a `tool` test run.","title":"ToolCallResult"},"tts:SimulationToolCall":{"type":"object","properties":{"turn_index":{"type":"integer","description":"Zero-based index of the conversation turn in which this call occurred."},"tool_name":{"type":"string"},"args":{"description":"Arguments passed to the tool, as a JSON object."},"response":{"description":"Response returned to the agent (absent for system tools that end the call)."},"mocked":{"type":"boolean"}},"required":["turn_index","tool_name","args","mocked"],"description":"One tool invocation that occurred during a simulation run.\n`mocked` is true when the call was intercepted by the run's\nmock config; false when the real tool was called or when the\ntool is a system tool.","title":"SimulationToolCall"},"tts:SimulationResultSentiment":{"type":"string","enum":["positive","neutral","negative"],"description":"Overall sentiment classification.","title":"SimulationResultSentiment"},"tts:SimulationCriterionResultStatus":{"type":"string","enum":["success","failure","unknown"],"description":"Three-state outcome. `unknown` means the criterion did not\napply on this run (the topic never came up); `failure`\nmeans it did apply and the agent did not satisfy it.","title":"SimulationCriterionResultStatus"},"tts:SimulationCriterionResult":{"type":"object","properties":{"criterion_id":{"type":"string"},"name":{"type":"string"},"status":{"$ref":"#/components/schemas/tts:SimulationCriterionResultStatus","description":"Three-state outcome. `unknown` means the criterion did not\napply on this run (the topic never came up); `failure`\nmeans it did apply and the agent did not satisfy it."},"score":{"type":"number","format":"double","description":"0.0..1.0 continuous estimate of how well the criterion was met."},"rationale":{"type":"string"}},"required":["criterion_id","name","status","rationale"],"description":"One scored entry of an agent's configured evaluation criterion\nagainst a simulation transcript. Mirrors the per-criterion row\nthe post-call evaluator persists, so test runs and live\nconversations carry identical per-criterion shapes.","title":"SimulationCriterionResult"},"tts:DataAssertionResultMode":{"type":"string","enum":["exact","regex","llm"],"title":"DataAssertionResultMode"},"tts:DataAssertionResult":{"type":"object","properties":{"key":{"type":"string"},"mode":{"$ref":"#/components/schemas/tts:DataAssertionResultMode"},"actual_json":{"type":"string","description":"The extracted value rendered as JSON (`null` when the key was missing from the data map)."},"passed":{"type":"boolean"},"rationale":{"type":"string","description":"Empty on pass; reason for failure otherwise."}},"required":["key","mode","actual_json","passed"],"description":"Outcome of one `data_assertions` entry: did the value the\nevaluator extracted under `key` pass the configured exact /\nregex / llm check.","title":"DataAssertionResult"},"tts:SimulationResult":{"type":"object","properties":{"transcript":{"type":"array","items":{"$ref":"#/components/schemas/tts:SimulationMessage"},"description":"Full synthetic conversation in order."},"tool_calls":{"type":"array","items":{"$ref":"#/components/schemas/tts:SimulationToolCall"},"description":"Every tool invocation across all turns."},"turns_used":{"type":"integer","description":"Number of agent turns that ran before the simulation ended."},"passed":{"type":"boolean"},"rationale":{"type":"string","description":"Top-level verdict explanation (run summary on pass; first failing criterion or assertion on fail)."},"duration_ms":{"type":"integer","format":"int64"},"summary":{"type":"string","description":"One-sentence narrative summary of what happened in the conversation."},"sentiment":{"$ref":"#/components/schemas/tts:SimulationResultSentiment","description":"Overall sentiment classification."},"criteria":{"type":"array","items":{"$ref":"#/components/schemas/tts:SimulationCriterionResult"},"description":"One result row per configured EvaluationCriterion on the\nagent. Same shape as the per-criterion rows persisted on\nthe post-call evaluations table."},"data":{"type":"object","additionalProperties":{"description":"Any type"},"description":"LLM-extracted values for the agent's configured\ndata-collection fields. Keys mirror the agent's\ndata_collection field keys; values are typed per the\ndeclared field type."},"data_assertions":{"type":"array","items":{"$ref":"#/components/schemas/tts:DataAssertionResult"},"description":"One result row per `data_assertions` entry on the simulation config."}},"required":["transcript","turns_used","passed","rationale","duration_ms"],"description":"Result details for a `simulation` test run. AIS-3446 unifies\nscoring with the post-call evaluator: the synthetic transcript\nis scored against the agent's configured evaluation criteria\nand data-collection fields, then per-test `data_assertions`\ncheck the extracted values. The top-level `passed` is derived\n\u2014 every criterion must resolve to `success` or `unknown` and\nevery assertion must pass.","title":"SimulationResult"},"tts:TestRunResult":{"type":"object","properties":{"test_type":{"$ref":"#/components/schemas/tts:TestType"},"passed":{"type":"boolean"},"rationale":{"type":"string","description":"Top-level verdict explanation duplicated from the inner result for quick rendering."},"duration_ms":{"type":"integer","format":"int64"},"reply":{"oneOf":[{"$ref":"#/components/schemas/tts:ReplyResult"},{"type":"null"}]},"tool_call":{"oneOf":[{"$ref":"#/components/schemas/tts:ToolCallResult"},{"type":"null"}]},"simulation":{"oneOf":[{"$ref":"#/components/schemas/tts:SimulationResult"},{"type":"null"}]}},"required":["test_type","passed","rationale","duration_ms"],"description":"Union-like result of a completed test run. Exactly one of\n`reply`, `tool_call`, or `simulation` is populated, matching\nthe `test_type`.","title":"TestRunResult"},"tts:AgentTestRun":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`run_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"test_id":{"type":"string","description":"Prefixed wire identifier (`test_<26 char Crockford base32>`)\nof the parent test. ADR 0015 FK consistency.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the agent this run executed against. ADR 0015 FK\nconsistency.\n"},"status":{"$ref":"#/components/schemas/tts:TestRunStatus"},"started_at":{"type":["string","null"],"format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"},"result":{"oneOf":[{"$ref":"#/components/schemas/tts:TestRunResult"},{"type":"null"}],"description":"Populated on terminal status only."},"error":{"type":"string","description":"Human-readable error message when status is `error`."},"created_at":{"type":"string","format":"date-time"}},"required":["id","test_id","agent_id","status","created_at"],"description":"One execution of a test. `result` is populated when `status`\nreaches a terminal state (`passed`, `failed`, or `error`).\nSee `TestRunResult` for the shape.","title":"AgentTestRun"},"tts:AgentTestWithLastRun":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`test_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the owning agent. ADR 0015 FK consistency.\n"},"name":{"type":"string"},"description":{"type":"string"},"type":{"$ref":"#/components/schemas/tts:TestType"},"config":{"$ref":"#/components/schemas/tts:AgentTestConfig","description":"Type-specific configuration document."},"tool_mock_config":{"$ref":"#/components/schemas/tts:ToolMockConfig","description":"Optional tool-mocking config applied during runs of this test."},"variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-test dynamic-variable overrides. Keys substitute `{{key}}`\nplaceholders inside the test config at run-start. Unknown keys\nrender as empty string, matching session dispatch behaviour.\n"},"folder_id":{"type":["string","null"],"description":"When set, prefixed wire identifier\n(`folder_<26 char Crockford base32>`) of the containing folder.\nNull means root (unfiled). ADR 0015 FK consistency.\n"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"last_run":{"oneOf":[{"$ref":"#/components/schemas/tts:AgentTestRun"},{"type":"null"}],"description":"The most recent run, or null if the test has never been run."},"attached_agent_ids":{"type":"array","items":{"type":"string"},"description":"Every agent this test runs against. Always includes the owner agent."}},"required":["id","agent_id","name","description","type","config","created_at","updated_at"],"description":"List-view projection of a test that includes the most recent run\nso the console can display pass/fail badges without an extra\nround-trip. On the global `/v1/agents/tests` surface, also carries\n`attached_agent_ids` so the row can render agent chips without a\nfollow-up request.","title":"AgentTestWithLastRun"},"tts:ListAgentTestsResponse":{"type":"object","properties":{"tests":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestWithLastRun"}}},"required":["tests"],"title":"ListAgentTestsResponse"},"tts:CreateAgentTestRequestConfig":{"oneOf":[{"$ref":"#/components/schemas/tts:ReplyConfig"},{"$ref":"#/components/schemas/tts:ToolCallConfig"},{"$ref":"#/components/schemas/tts:SimulationConfig"}],"description":"Type-specific configuration. Must match the shape for the given `type`.","title":"CreateAgentTestRequestConfig"},"tts:CreateAgentTestRequest":{"type":"object","properties":{"name":{"type":"string","description":"Short human-readable label for the test."},"description":{"type":"string","description":"Optional longer description of what this test verifies."},"type":{"$ref":"#/components/schemas/tts:TestType"},"config":{"$ref":"#/components/schemas/tts:CreateAgentTestRequestConfig","description":"Type-specific configuration. Must match the shape for the given `type`."},"tool_mock_config":{"$ref":"#/components/schemas/tts:ToolMockConfig","description":"Optional tool-mocking config applied during every run of this test."},"variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-test variable values substituted into string fields of the\nconfig at run-start. Keys use the same rules as agent-level\n`DynamicVariable` keys.\n"},"folder_id":{"type":["string","null"],"description":"Prefixed wire identifier (`folder_<26 char Crockford base32>`)\nof the folder to place the test in. Omit / null for root.\n"},"attached_agent_ids":{"type":"array","items":{"type":"string"},"description":"Optional list of additional agents this test should also run\nagainst. The owner agent (path param) is always attached\nimplicitly.\n"}},"required":["name","type","config"],"description":"Payload for `POST /v1/agents/{id}/tests`.","title":"CreateAgentTestRequest"},"tts:AgentTest":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`test_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the owning agent. ADR 0015 FK consistency.\n"},"name":{"type":"string"},"description":{"type":"string"},"type":{"$ref":"#/components/schemas/tts:TestType"},"config":{"$ref":"#/components/schemas/tts:AgentTestConfig","description":"Type-specific configuration document."},"tool_mock_config":{"$ref":"#/components/schemas/tts:ToolMockConfig","description":"Optional tool-mocking config applied during runs of this test."},"variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-test dynamic-variable overrides. Keys substitute `{{key}}`\nplaceholders inside the test config at run-start. Unknown keys\nrender as empty string, matching session dispatch behaviour.\n"},"folder_id":{"type":["string","null"],"description":"When set, prefixed wire identifier\n(`folder_<26 char Crockford base32>`) of the containing folder.\nNull means root (unfiled). ADR 0015 FK consistency.\n"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","agent_id","name","description","type","config","created_at","updated_at"],"description":"A configured test against a voice agent. `config` is a\ntype-specific document - see `ReplyConfig`, `ToolCallConfig`,\nand `SimulationConfig` for the per-type shapes (discriminated by `type`).","title":"AgentTest"},"tts:TestRunConfigOverride":{"type":"object","properties":{"prompt":{"type":"string","description":"Replaces the agent's system prompt for every test in the run."},"model":{"type":"string","description":"Overrides the LLM model for every test in the run. The model\nid rides on the agent's configured provider \u2014 a\ncross-provider switch is not supported."},"tool_ids":{"type":"array","items":{"type":"string"},"description":"Replaces the agent's attached external tools for the run with\nexactly this set. Each entry is a prefixed `tool_`\nid; `builtin_` ids are rejected. An empty array runs with no\ntools; omit the field to keep the agent's attachments."}},"description":"A run-level config override applied to every test in a Run All.\nLayered on top of the agent's stored config for the duration of\nthe suite run, so the whole suite can be validated against a\nproposed prompt / model / toolbelt without editing any test. An\nabsent field leaves the agent's value untouched; a run-level\noverride wins over a deprecated per-test `system_prompt_override`\n/ `model_override`.","title":"TestRunConfigOverride"},"tts:RunAllTestsRequest":{"type":"object","properties":{"config_override":{"$ref":"#/components/schemas/tts:TestRunConfigOverride"},"flow_version_id":{"type":"string","description":"Targets a specific flow version (an `agent_versions` row)\ninstead of the agent's active flow \u2014 version-targeted\nregression. Must be a flow version of the agent under test.\nRaw UUID; flow versions carry no prefixed wire id."}},"description":"Optional body of `POST /v1/agents/{id}/tests/runs`. Omit it\nentirely to run every test against the agent's live config and\nactive flow.","title":"RunAllTestsRequest"},"tts:SuiteRunTrigger":{"type":"string","enum":["run_all","batch","resubmit"],"description":"Which entry point created a suite run.\n- `run_all` - POST /v1/agents/{id}/tests/runs.\n- `batch` - POST /v1/agents/tests/runs/batch.\n- `resubmit` - POST /v1/agents/tests/suite-runs/{id}/resubmit.\n","title":"SuiteRunTrigger"},"tts:AgentTestSuiteRun":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`srun_<26 char Crockford base32>`)."},"agent_id":{"type":["string","null"],"description":"Prefixed `agent_` id of the agent whose suite\nwas run. Set for the `run_all` trigger; null for `batch`,\nwhich can span many agents.\n"},"trigger":{"$ref":"#/components/schemas/tts:SuiteRunTrigger"},"parent_suite_run_id":{"type":["string","null"],"description":"Set on a `resubmit`: the prefixed `srun_` id of\nthe suite run whose failed/errored tests this one re-ran.\nNull for `run_all` and `batch`.\n"},"status":{"$ref":"#/components/schemas/tts:TestRunStatus"},"total_runs":{"type":"integer","description":"Number of child runs in the suite."},"passed_count":{"type":"integer"},"failed_count":{"type":"integer"},"errored_count":{"type":"integer"},"pending_count":{"type":"integer","description":"Child runs still queued or running."},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time","description":"Newest child-run completion; null until every child run is terminal."},"config_override":{"oneOf":[{"$ref":"#/components/schemas/tts:TestRunConfigOverride"},{"type":"null"}],"description":"The run-level config override (AIS-3443) this suite was run\nwith, or null for an ordinary Run All / batch."},"flow_version_id":{"type":["string","null"],"description":"The flow version (`agent_versions` row) this suite targeted,\nor null for the agent's active / synthesized flow."},"flow_version_number":{"type":["integer","null"],"description":"Human-facing version number of `flow_version_id`; null when no version was targeted."}},"required":["id","trigger","status","total_runs","passed_count","failed_count","errored_count","pending_count","created_at"],"description":"A suite run (test invocation): the grouping object over every\ntest run dispatched by one Run All, batch, or resubmit call.\n`status` and the count fields are derived from the child runs.\n`status` is `running` while any child run is still queued or\nrunning, then `passed` (all passed), `failed` (at least one\nfailed), or `error` (at least one errored, none failed).","title":"AgentTestSuiteRun"},"tts:RunAgentTestsResponse":{"type":"object","properties":{"runs":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestRun"}},"suite_run":{"oneOf":[{"$ref":"#/components/schemas/tts:AgentTestSuiteRun"},{"type":"null"}],"description":"The suite run grouping the queued runs."}},"required":["runs"],"description":"Response from `POST /v1/agents/{id}/tests/runs` and the suite-run\nresubmit endpoint. Contains every newly-queued run so the client\ncan poll each for completion, plus the `suite_run` that groups\nthem. `suite_run` is null only when a Run All found no tests.","title":"RunAgentTestsResponse"},"tts:ToolKind":{"type":"string","enum":["system","webhook","client","mcp"],"description":"Where the tool executes.\n- `system`: worker-resident built-in (e.g. end_call, play_audio)\n- `webhook`: worker signs a payload and POSTs it to your URL\n- `client`: worker dispatches to the caller's browser/SDK via data channel\n- `mcp`: worker connects to a customer-hosted MCP server and proxies tool calls (AIS-3056)\n","title":"ToolKind"},"tts:ToolParamType":{"type":"string","enum":["string","number","integer","boolean"],"description":"Permitted JSON-Schema primitive types for tool params.","title":"ToolParamType"},"tts:ToolParam":{"type":"object","properties":{"name":{"type":"string"},"type":{"$ref":"#/components/schemas/tts:ToolParamType"},"description":{"type":"string"},"required":{"type":"boolean"},"enum":{"type":"array","items":{"type":"string"}}},"required":["name","type","description","required"],"description":"One argument the LLM can pass when calling the tool. Mirrors the JSON-Schema subset standard function-calling schemas support.","title":"ToolParam"},"tts:SystemToolConfig":{"type":"object","properties":{"builtin":{"$ref":"#/components/schemas/tts:SystemBuiltin"},"params":{"type":"array","items":{"$ref":"#/components/schemas/tts:ToolParam"}},"builtin_config":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-builtin extras (e.g. allowed_numbers for transfer_to_number)."}},"required":["builtin"],"description":"Config shape for `kind=system`. The `builtin` value names the\nworker-resident capability; the catalogue served by\n`GET /v1/agents/tools/system-builtins` is the runtime source of truth\nfor valid names plus their console-facing labels.\n","title":"SystemToolConfig"},"tts:WebhookToolConfigMethod":{"type":"string","enum":["POST","GET"],"title":"WebhookToolConfigMethod"},"tts:WebhookToolConfig":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"method":{"$ref":"#/components/schemas/tts:WebhookToolConfigMethod"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Static headers sent with every call. `Authorization` and `X-Speechify-Signature` are reserved."},"timeout_ms":{"type":"integer","description":"Per-call timeout in milliseconds. Defaults to 10000 server-side when omitted."},"params":{"type":"array","items":{"$ref":"#/components/schemas/tts:ToolParam"}},"fire_and_forget":{"type":"boolean","description":"When true the worker dispatches the HTTP request and returns\nimmediately to the LLM with a synthetic \"queued\" result\ninstead of waiting for the response body. The customer's\nendpoint is expected to enqueue the work and return any\nnon-error status quickly; errors raised after dispatch are\nlogged but never surfaced to the LLM. Use for long-running\ncustomer-side work (job triggers, async ticket creation,\netc.) where blocking the call on the response would hurt\nthe conversation. Defaults to false.\n"}},"required":["url"],"description":"Config shape for `kind=webhook`.","title":"WebhookToolConfig"},"tts:ClientToolConfig":{"type":"object","properties":{"params":{"type":"array","items":{"$ref":"#/components/schemas/tts:ToolParam"}},"timeout_ms":{"type":"integer","description":"Per-call timeout in milliseconds. Defaults to 10000 server-side when omitted."}},"description":"Config shape for `kind=client`. Execution happens in the caller's browser / SDK.","title":"ClientToolConfig"},"tts:MCPTransport":{"type":"string","enum":["http_streamable","sse"],"description":"MCP transport. `http_streamable` is the default; `sse` is the\nlegacy fallback for servers that haven't migrated yet.\n","title":"MCPTransport"},"tts:MCPAuth":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["none"],"description":"Discriminator value: none"}},"required":["type"],"description":"none variant"},{"type":"object","properties":{"type":{"type":"string","enum":["bearer"],"description":"Discriminator value: bearer"},"token":{"type":"string","description":"Bearer token. Write-only \u2014 never echoed back on reads."},"token_set":{"type":"boolean","description":"True when a bearer token is configured. Read-only."}},"required":["type"],"description":"bearer variant"},{"type":"object","properties":{"type":{"type":"string","enum":["oauth2_client_credentials"],"description":"Discriminator value: oauth2_client_credentials"},"token_url":{"type":"string","format":"uri"},"client_id":{"type":"string"},"client_secret":{"type":"string","description":"OAuth2 client_secret. Write-only \u2014 never echoed back on reads."},"client_secret_set":{"type":"boolean","description":"True when a client_secret is configured. Read-only."},"scope":{"type":"string","description":"Optional scope claim sent on the token request."}},"required":["type","token_url","client_id"],"description":"oauth2_client_credentials variant"}],"discriminator":{"propertyName":"type"},"description":"Discriminated union over `type`.","title":"MCPAuth"},"tts:MCPToolConfig":{"type":"object","properties":{"endpoint":{"type":"string","format":"uri"},"transport":{"$ref":"#/components/schemas/tts:MCPTransport"},"auth":{"$ref":"#/components/schemas/tts:MCPAuth"}},"required":["endpoint","auth"],"description":"Config shape for `kind=mcp` (AIS-3056). The worker opens the\nconfigured transport at session start, runs `initialize` +\n`list_tools`, and registers each discovered remote tool as a\nlivekit-agents function_tool proxying through the long-lived\nClientSession.\n","title":"MCPToolConfig"},"tts:ToolConfig":{"oneOf":[{"$ref":"#/components/schemas/tts:SystemToolConfig"},{"$ref":"#/components/schemas/tts:WebhookToolConfig"},{"$ref":"#/components/schemas/tts:ClientToolConfig"},{"$ref":"#/components/schemas/tts:MCPToolConfig"}],"description":"One of `SystemToolConfig`, `WebhookToolConfig`, `ClientToolConfig`, or `MCPToolConfig` depending on `kind`.","title":"ToolConfig"},"tts:Tool":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`tool_<26 char Crockford base32>`).\nADR 0015 Cluster 1 hard-break.\n"},"name":{"type":"string"},"description":{"type":"string"},"kind":{"$ref":"#/components/schemas/tts:ToolKind"},"config":{"$ref":"#/components/schemas/tts:ToolConfig","description":"One of `SystemToolConfig`, `WebhookToolConfig`, `ClientToolConfig`, or `MCPToolConfig` depending on `kind`."},"webhook_secret":{"type":"string","description":"HMAC signing secret for `kind=webhook`. Returned in full **only** on the create\nresponse; all subsequent reads return a masked placeholder. Store it on first\ncreate \u2014 there is no way to retrieve it later.\n"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","description","kind","config","created_at","updated_at"],"title":"Tool"},"tts:AttachedToolsResponse":{"type":"object","properties":{"tools":{"type":"array","items":{"$ref":"#/components/schemas/tts:Tool"}}},"required":["tools"],"description":"Bare list of the tools attached to an agent. Not paginated \u2014\nan agent's tool attachment count is bounded by configuration,\nnot by data scale. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the \"pagination only where needed\" rule.\n","title":"AttachedToolsResponse"},"tts:ListConversationsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"conversations":{"type":"array","items":{"$ref":"#/components/schemas/tts:Conversation"}}},"required":["next_cursor","has_more","conversations"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListConversationsResponse"},"tts:MessageRole":{"type":"string","enum":["user","assistant","system","tool"],"title":"MessageRole"},"tts:Message":{"type":"object","properties":{"id":{"type":"string"},"conversation_id":{"type":"string","description":"Prefixed wire identifier (`conv_<26 char Crockford base32>`)\nof the parent conversation. ADR 0015 FK consistency.\n"},"role":{"$ref":"#/components/schemas/tts:MessageRole"},"content":{"type":"string"},"tool_name":{"type":["string","null"]},"tool_args":{"type":["object","null"],"additionalProperties":{"description":"Any type"}},"tool_result":{"description":"Arbitrary JSON value returned by the tool (object, array, string, or primitive)."},"started_at":{"type":"string","format":"date-time"},"ended_at":{"type":["string","null"],"format":"date-time"}},"required":["id","conversation_id","role","content","started_at"],"title":"Message"},"tts:ListMessagesResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"messages":{"type":"array","items":{"$ref":"#/components/schemas/tts:Message"}}},"required":["next_cursor","has_more","messages"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListMessagesResponse"},"tts:EvaluationKind":{"type":"string","enum":["criterion","summary","data"],"title":"EvaluationKind"},"tts:EvaluationStatus":{"type":"string","enum":["success","failure","unknown"],"description":"Three-state criterion result. `unknown` means the criterion did not apply to this call.","title":"EvaluationStatus"},"tts:Evaluation":{"type":"object","properties":{"id":{"type":"string"},"conversation_id":{"type":"string","description":"Prefixed wire identifier (`conv_<26 char Crockford base32>`)\nof the conversation this evaluation is attached to. ADR 0015\nFK consistency.\n"},"kind":{"$ref":"#/components/schemas/tts:EvaluationKind"},"criterion_id":{"type":["string","null"]},"name":{"type":"string"},"status":{"oneOf":[{"$ref":"#/components/schemas/tts:EvaluationStatus"},{"type":"null"}],"description":"Three-state criterion result. `unknown` means the criterion did not apply to this call."},"passed":{"type":["boolean","null"]},"score":{"type":["number","null"],"format":"double"},"rationale":{"type":"string"},"data":{"description":"Structured data-collection payload (present only on `kind=data` rows)."},"created_at":{"type":"string","format":"date-time"}},"required":["id","conversation_id","kind","name","rationale","created_at"],"description":"Three flavours coexist, discriminated by `kind`:\n- `criterion` rows carry `status` + `passed` + `score` + `rationale` for one criterion\n- `summary` row carries overall sentiment + rationale in `rationale`\n- `data` row carries the structured data-collection payload in `data`\n\n`status` is the canonical three-state result. `passed` is a\nderived boolean kept for backwards compatibility with earlier\nwebhook consumers: success\u2192true, failure\u2192false, unknown\u2192null.\n","title":"Evaluation"},"tts:ListEvaluationsResponse":{"type":"object","properties":{"evaluations":{"type":"array","items":{"$ref":"#/components/schemas/tts:Evaluation"}}},"required":["evaluations"],"title":"ListEvaluationsResponse"},"tts:ConversationStats":{"type":"object","properties":{"total":{"type":"integer","format":"int64"},"completed":{"type":"integer","format":"int64"},"failed":{"type":"integer","format":"int64"},"active":{"type":"integer","format":"int64"},"pending":{"type":"integer","format":"int64"},"avg_duration_ms":{"type":["number","null"],"format":"double"},"avg_cost_cents":{"type":["number","null"],"format":"double"}},"required":["total","completed","failed","active","pending","avg_duration_ms","avg_cost_cents"],"description":"Counts + averages over the caller's conversations matching the supplied filters. AVG fields are null when no rows match the FILTER predicate.","title":"ConversationStats"},"tts:RecentCallee":{"type":"object","properties":{"phone":{"type":"string","description":"E.164 phone number that was dialled."},"last_called_at":{"type":"string","format":"date-time","description":"Timestamp of the most recent outbound call to this number."}},"required":["phone","last_called_at"],"description":"One distinct phone number this workspace has dialled, with the timestamp of the most recent outbound call to it.","title":"RecentCallee"},"tts:ListRecentCalleesResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"callees":{"type":"array","items":{"$ref":"#/components/schemas/tts:RecentCallee"}}},"required":["next_cursor","has_more","callees"],"description":"Payload for GET /v1/agents/conversations/recent-callees.","title":"ListRecentCalleesResponse"},"tts:WebhookDeliveryStatus":{"type":"string","enum":["pending","delivered","failed"],"description":"Lifecycle of a post-call webhook delivery row. The sender\nupdates the same row across retries so the UI always sees the\nlatest outcome.\n","title":"WebhookDeliveryStatus"},"tts:WebhookDelivery":{"type":"object","properties":{"id":{"type":"string"},"conversation_id":{"type":"string","description":"Prefixed wire identifier (`conv_<26 char Crockford base32>`)\nof the conversation that triggered this delivery. ADR 0015\nFK consistency.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the agent. ADR 0015 FK consistency.\n"},"url":{"type":"string"},"event":{"type":"string"},"status":{"$ref":"#/components/schemas/tts:WebhookDeliveryStatus"},"attempt_count":{"type":"integer"},"last_attempt_at":{"type":"string","format":"date-time"},"last_status_code":{"type":"integer"},"last_error":{"type":"string"},"created_at":{"type":"string","format":"date-time"}},"required":["id","conversation_id","agent_id","url","event","status","attempt_count","created_at"],"description":"Post-call webhook delivery log row. One row per\n`(conversation, webhook-url)`; updated in place across retry\nattempts.\n","title":"WebhookDelivery"},"tts:ListWebhookDeliveriesResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/tts:WebhookDelivery"}}},"required":["next_cursor","has_more","deliveries"],"description":"Payload for `GET /v1/agents/conversations/{id}/webhook-deliveries`.","title":"ListWebhookDeliveriesResponse"},"tts:RetrievalLogResult":{"type":"object","properties":{"chunk_id":{"type":"string"},"document_id":{"type":"string"},"kb_id":{"type":"string","description":"Prefixed wire identifier (`kb_<26 char Crockford base32>`)\nof the knowledge base the matched chunk lives in. ADR 0015\nFK consistency.\n"},"filename":{"type":"string"},"chunk_index":{"type":"integer"},"content":{"type":"string"},"score":{"type":"number","format":"double"}},"required":["chunk_id","document_id","kb_id","filename","chunk_index","content","score"],"description":"One ranked chunk inside a retrieval log row. Mirrors\n`RetrievalLogResult` in apps/server/internal/kb/types.go \u2014\ndenormalised so deleting a chunk or document after the call\ndoesn't render historical logs unreadable.\n","title":"RetrievalLogResult"},"tts:RetrievalLogEntry":{"type":"object","properties":{"id":{"type":"string"},"conversation_id":{"type":"string","description":"Prefixed wire identifier (`conv_<26 char Crockford base32>`)\nof the conversation. ADR 0015 FK consistency.\n"},"query":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/tts:RetrievalLogResult"}},"top_k":{"type":"integer"},"hit_count":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}},"required":["id","conversation_id","query","results","top_k","hit_count","created_at"],"description":"One `search_knowledge` invocation recorded against a\nconversation. Powers the Retrieval panel on the conversation\ndetail view.\n","title":"RetrievalLogEntry"},"tts:ListRetrievalLogsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"entries":{"type":"array","items":{"$ref":"#/components/schemas/tts:RetrievalLogEntry"}}},"required":["next_cursor","has_more","entries"],"description":"Payload for `GET /v1/agents/conversations/{id}/retrieval-log`.","title":"ListRetrievalLogsResponse"},"tts:CreateKnowledgeBaseRequest":{"type":"object","properties":{"name":{"type":"string","description":"Human-readable label."},"description":{"type":"string","description":"Optional description."}},"required":["name"],"title":"CreateKnowledgeBaseRequest"},"tts:ListKnowledgeBasesResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"knowledge_bases":{"type":"array","items":{"$ref":"#/components/schemas/tts:KnowledgeBase"}}},"required":["next_cursor","has_more","knowledge_bases"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListKnowledgeBasesResponse"},"tts:UpdateKnowledgeBaseRequest":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"}},"title":"UpdateKnowledgeBaseRequest"},"tts:KnowledgeBaseDocumentSourceKind":{"type":"string","enum":["file","url","text"],"description":"How the document entered the KB. `file` is the upload path,\n`text` is inline pasted content, `url` is fetched via\nFirecrawl. Sitemap and crawl imports also produce `url` rows.\n","title":"KnowledgeBaseDocumentSourceKind"},"tts:KnowledgeBaseDocumentStatus":{"type":"string","enum":["fetching","embedding","ready","failed"],"description":"Document lifecycle. `fetching` is the pre-scrape state used\nonly by url-sourced rows; file and text docs skip straight\nto `embedding` because their content is available\nsynchronously. Terminal states are `ready` and `failed`.\n","title":"KnowledgeBaseDocumentStatus"},"tts:KnowledgeBaseDocument":{"type":"object","properties":{"id":{"type":"string"},"kb_id":{"type":"string","description":"Prefixed wire identifier (`kb_<26 char Crockford base32>`) of\nthe knowledge base the document belongs to. ADR 0015 FK\nconsistency.\n"},"source_kind":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocumentSourceKind"},"source_url":{"type":"string","description":"Source URL for url-sourced documents (and the sitemap /\ncrawl imports that produce them). Empty string for file\nand text rows.\n"},"folder_id":{"type":["string","null"],"description":"Folder this document lives in. Null for root-level\n(unfiled) documents. Mutated via the move endpoint.\n"},"filename":{"type":"string"},"content_type":{"type":"string"},"byte_size":{"type":"integer","format":"int64"},"char_count":{"type":"integer"},"chunk_count":{"type":"integer"},"status":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocumentStatus"},"error":{"type":"string","description":"Populated when status is failed."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","kb_id","source_kind","folder_id","filename","content_type","byte_size","char_count","chunk_count","status","created_at","updated_at"],"title":"KnowledgeBaseDocument"},"tts:ListKnowledgeBaseDocumentsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"documents":{"type":"array","items":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocument"}}},"required":["next_cursor","has_more","documents"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListKnowledgeBaseDocumentsResponse"},"tts:DependentAgent":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"description":"Minimal agent pointer (id + name) used by the document\ndetail view to render a clickable link to each agent that\nhas the document's KB attached.\n","title":"DependentAgent"},"tts:RefreshConfig":{"type":"object","properties":{"enabled":{"type":"boolean"},"interval_days":{"type":"integer"},"auto_remove_enabled":{"type":"boolean"},"last_refreshed_at":{"type":["string","null"],"format":"date-time"},"consecutive_fetch_failures":{"type":"integer"}},"required":["enabled","interval_days","auto_remove_enabled","last_refreshed_at","consecutive_fetch_failures"],"description":"Per-document auto-refresh state (AIS-2656). Only populated\nfor url-sourced documents; file and text rows omit this and\nthe console's auto-refresh panel hides accordingly.\n","title":"RefreshConfig"},"tts:KnowledgeBaseDocumentDetail":{"type":"object","properties":{"id":{"type":"string"},"kb_id":{"type":"string","description":"Prefixed wire identifier (`kb_<26 char Crockford base32>`) of\nthe knowledge base the document belongs to. ADR 0015 FK\nconsistency.\n"},"source_kind":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocumentSourceKind"},"source_url":{"type":"string","description":"Source URL for url-sourced documents (and the sitemap /\ncrawl imports that produce them). Empty string for file\nand text rows.\n"},"folder_id":{"type":["string","null"],"description":"Folder this document lives in. Null for root-level\n(unfiled) documents. Mutated via the move endpoint.\n"},"filename":{"type":"string"},"content_type":{"type":"string"},"byte_size":{"type":"integer","format":"int64"},"char_count":{"type":"integer"},"chunk_count":{"type":"integer"},"status":{"$ref":"#/components/schemas/tts:KnowledgeBaseDocumentStatus"},"error":{"type":"string","description":"Populated when status is failed."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"content_preview":{"type":"string"},"preview_truncated":{"type":"boolean"},"dependent_agents":{"type":"array","items":{"$ref":"#/components/schemas/tts:DependentAgent"}},"refresh":{"$ref":"#/components/schemas/tts:RefreshConfig"}},"required":["id","kb_id","source_kind","folder_id","filename","content_type","byte_size","char_count","chunk_count","status","created_at","updated_at","content_preview","preview_truncated","dependent_agents"],"description":"Payload of GET /v1/knowledge-bases/documents/{docId}. Extends\nthe list-view document with a bounded content preview, the\nlist of dependent agents, and (for url-sourced docs) the\nauto-refresh state.\n","title":"KnowledgeBaseDocumentDetail"},"tts:KnowledgeBaseChunk":{"type":"object","properties":{"id":{"type":"string"},"document_id":{"type":"string"},"kb_id":{"type":"string","description":"Prefixed wire identifier (`kb_<26 char Crockford base32>`) of\nthe knowledge base the chunk belongs to. ADR 0015 FK\nconsistency.\n"},"chunk_index":{"type":"integer"},"content":{"type":"string"}},"required":["id","document_id","kb_id","chunk_index","content"],"title":"KnowledgeBaseChunk"},"tts:ListKnowledgeBaseChunksResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"chunks":{"type":"array","items":{"$ref":"#/components/schemas/tts:KnowledgeBaseChunk"}}},"required":["next_cursor","has_more","chunks"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListKnowledgeBaseChunksResponse"},"tts:SearchKnowledgeBasesRequest":{"type":"object","properties":{"query":{"type":"string","description":"Natural-language search query."},"kb_ids":{"type":"array","items":{"type":"string"},"description":"Knowledge bases to search across. Results scoped to caller-owned entries; unknown IDs are silently ignored."},"top_k":{"type":"integer","default":5,"description":"Max hits to return (default 5, capped at 50)."}},"required":["query","kb_ids"],"title":"SearchKnowledgeBasesRequest"},"tts:KnowledgeBaseSearchHit":{"type":"object","properties":{"chunk_id":{"type":"string"},"document_id":{"type":"string"},"kb_id":{"type":"string"},"filename":{"type":"string"},"chunk_index":{"type":"integer"},"content":{"type":"string"},"score":{"type":"number","format":"double","description":"Cosine similarity (higher = more relevant)."}},"required":["chunk_id","document_id","kb_id","filename","chunk_index","content","score"],"title":"KnowledgeBaseSearchHit"},"tts:SearchKnowledgeBasesResponse":{"type":"object","properties":{"hits":{"type":"array","items":{"$ref":"#/components/schemas/tts:KnowledgeBaseSearchHit"}}},"required":["hits"],"title":"SearchKnowledgeBasesResponse"},"tts:CreateTextDocumentRequest":{"type":"object","properties":{"name":{"type":"string"},"content":{"type":"string"},"folder_id":{"type":["string","null"],"description":"Folder to drop the document into. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null/omitted = root.\n"}},"required":["name","content"],"description":"Body for POST /v1/knowledge-bases/{id}/documents/text.","title":"CreateTextDocumentRequest"},"tts:CreateURLDocumentRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"folder_id":{"type":["string","null"],"description":"Folder to drop the document into. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null/omitted = root.\n"}},"required":["url"],"description":"Body for POST /v1/knowledge-bases/{id}/documents/url.","title":"CreateURLDocumentRequest"},"tts:CreateSitemapImportRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"folder_id":{"type":["string","null"],"description":"Folder to import the documents into. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null/omitted = root.\n"}},"required":["url"],"title":"CreateSitemapImportRequest"},"tts:ImportJobKind":{"type":"string","enum":["sitemap","crawl","refresh","urls"],"title":"ImportJobKind"},"tts:ImportJobStatus":{"type":"string","enum":["pending","running","completed","failed","cancelled"],"description":"`pending` is the brief window between insert and the worker\npicking up; `running` is the bulk of the job's life;\n`completed` / `failed` / `cancelled` are terminal.\n","title":"ImportJobStatus"},"tts:ImportJob":{"type":"object","properties":{"id":{"type":"string"},"kb_id":{"type":"string"},"kind":{"$ref":"#/components/schemas/tts:ImportJobKind"},"status":{"$ref":"#/components/schemas/tts:ImportJobStatus"},"requested_count":{"type":"integer"},"completed_count":{"type":"integer"},"failed_count":{"type":"integer"},"params":{"type":"object","additionalProperties":{"description":"Any type"},"description":"JSON blob whose shape depends on `kind` \u2014 typically `url`,\n`max_pages`, `max_depth`. The console reads it for display\nonly.\n"},"error":{"type":"string"},"upstream_job_id":{"type":"string"},"created_by_uid":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"started_at":{"type":["string","null"],"format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"}},"required":["id","kb_id","kind","status","requested_count","completed_count","failed_count","params","created_by_uid","created_at","updated_at","started_at","finished_at"],"description":"Async URL import job (AIS-2655 sitemap, AIS-2657 crawl, plus\nthe auto-refresh path). The console polls\n`GET /v1/agents/knowledge-bases/{id}/imports` while the job is\nnon-terminal.\n","title":"ImportJob"},"tts:ImportJobResponse":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/tts:ImportJob"}},"required":["job"],"description":"Wrapper returned by the async import endpoints (sitemap, crawl, multi-URL).","title":"ImportJobResponse"},"tts:CreateCrawlImportRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"max_pages":{"type":"integer"},"max_depth":{"type":"integer"},"folder_id":{"type":["string","null"],"description":"Folder to import the documents into. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null/omitted = root.\n"}},"required":["url"],"title":"CreateCrawlImportRequest"},"tts:CreateURLBatchImportRequest":{"type":"object","properties":{"urls":{"type":"array","items":{"type":"string","format":"uri"}},"folder_id":{"type":["string","null"],"description":"Folder to import the documents into. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null/omitted = root.\n"}},"required":["urls"],"description":"Body for POST /v1/knowledge-bases/{id}/documents/urls. Submit\n1..N URLs in a single async import. The server dedupes and\nvalidates each entry before queueing. The per-import cap is\noperator-tunable (default 250) via kbUrlBatchMaxUrls; the\nserver returns 400 when the resolved list exceeds the cap, so\nno maxItems is encoded in the schema to avoid SDK-side false\nrejections when an operator raises the limit.\n","title":"CreateURLBatchImportRequest"},"tts:ListImportJobsResponse":{"type":"object","properties":{"jobs":{"type":"array","items":{"$ref":"#/components/schemas/tts:ImportJob"}}},"required":["jobs"],"title":"ListImportJobsResponse"},"tts:BatchDeleteDocumentsRequest":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"}}},"required":["ids"],"description":"Body for DELETE /v1/knowledge-bases/{id}/documents/batch. All\nids must belong to the supplied KB; capped at 200 ids per\ncall.\n","title":"BatchDeleteDocumentsRequest"},"tts:BatchMoveDocumentsRequest":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"}},"folder_id":{"type":["string","null"],"description":"Destination folder. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null moves every\ndocument to the knowledge base root.\n"}},"required":["ids","folder_id"],"description":"Body for PATCH /v1/knowledge-bases/{id}/documents/batch/move.\nCapped at 200 ids per call. Pass `folder_id: null` to move to\nroot.\n","title":"BatchMoveDocumentsRequest"},"tts:UpdateRefreshConfigRequest":{"type":"object","properties":{"enabled":{"type":"boolean"},"interval_days":{"type":"integer"},"auto_remove_enabled":{"type":"boolean"}},"description":"PATCH body \u2014 every field optional.","title":"UpdateRefreshConfigRequest"},"tts:RefreshHistoryEntryStatus":{"type":"string","enum":["running","changed","unchanged","failed","removed"],"title":"RefreshHistoryEntryStatus"},"tts:RefreshHistoryEntry":{"type":"object","properties":{"id":{"type":"string"},"document_id":{"type":"string"},"started_at":{"type":"string","format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"},"status":{"$ref":"#/components/schemas/tts:RefreshHistoryEntryStatus"},"error":{"type":"string"},"previous_hash":{"type":"string"},"new_hash":{"type":"string"}},"required":["id","document_id","started_at","finished_at","status"],"description":"One auto-refresh attempt. `running` only appears mid-tick;\nterminal values are the ones the drawer renders.\n","title":"RefreshHistoryEntry"},"tts:ListRefreshHistoryResponse":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/tts:RefreshHistoryEntry"}}},"required":["entries"],"title":"ListRefreshHistoryResponse"},"tts:KnowledgeBaseFolder":{"type":"object","properties":{"id":{"type":"string"},"kb_id":{"type":"string","description":"Prefixed wire identifier (`kb_<26 char Crockford base32>`) of\nthe owning knowledge base. ADR 0015 FK consistency.\n"},"parent_folder_id":{"type":["string","null"]},"name":{"type":"string"},"document_count":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","kb_id","parent_folder_id","name","document_count","created_at","updated_at"],"description":"Folder inside a knowledge base. Root-level folders have\n`parent_folder_id: null`. `document_count` is populated only\non the list endpoint.\n","title":"KnowledgeBaseFolder"},"tts:ListKnowledgeBaseFoldersResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"folders":{"type":"array","items":{"$ref":"#/components/schemas/tts:KnowledgeBaseFolder"}}},"required":["next_cursor","has_more","folders"],"description":"Flat list of folders for a knowledge base. The console builds\nthe folder tree from `parent_folder_id` references, so callers\nshould walk every page before rendering.\n","title":"ListKnowledgeBaseFoldersResponse"},"tts:CreateFolderRequest":{"type":"object","properties":{"name":{"type":"string"},"parent_folder_id":{"type":["string","null"],"description":"Parent folder. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`); null/omitted creates a\nroot-level folder.\n"}},"required":["name"],"title":"CreateFolderRequest"},"tts:UpdateFolderRequest":{"type":"object","properties":{"name":{"type":"string"},"parent_folder_id":{"type":"string","description":"Folder to reparent under. Prefixed wire identifier\n(`kfolder_<26 char Crockford base32>`).\n"},"clear_parent_folder_id":{"type":"boolean","description":"When `true`, moves the folder to root (clears\n`parent_folder_id`). Wins over `parent_folder_id` when both\nare sent."}},"description":"PATCH body. All fields optional; omit to leave unchanged. Set\n`parent_folder_id` to reparent into that folder; send\n`clear_parent_folder_id: true` to move the folder to root. The\nclear flag is the explicit signal because JSON `null` is\nindistinguishable from absent for pointer fields in Go's\nencoding/json.\n","title":"UpdateFolderRequest"},"tts:ListTestsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"tests":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestWithLastRun"}}},"required":["next_cursor","has_more","tests"],"description":"Workspace-wide paginated list of tests. Walk pages while\n`has_more` is true; pass `next_cursor` back as the request\n`cursor` parameter.","title":"ListTestsResponse"},"tts:TestStatsBucket":{"type":"object","properties":{"day":{"type":"string","description":"ISO date (YYYY-MM-DD)."},"passed":{"type":"integer"},"failed":{"type":"integer"},"errored":{"type":"integer"}},"required":["day","passed","failed","errored"],"description":"One daily point on the aggregate pass-rate chart.","title":"TestStatsBucket"},"tts:TestStats":{"type":"object","properties":{"window_days":{"type":"integer"},"buckets":{"type":"array","items":{"$ref":"#/components/schemas/tts:TestStatsBucket"}},"total_runs":{"type":"integer"},"passed_runs":{"type":"integer"},"failed_runs":{"type":"integer"},"errored_runs":{"type":"integer"},"avg_duration_ms":{"type":"integer"},"by_type":{"type":"object","additionalProperties":{"type":"integer"}}},"required":["window_days","buckets","total_runs","passed_runs","failed_runs","errored_runs","avg_duration_ms"],"description":"Aggregate run metrics over the requested window. `buckets` is\ndense - one entry per day in the window, zero-filled, so a chart\nnever has gaps. `by_type` counts runs per test type across the\nwhole window.","title":"TestStats"},"tts:UpdateAgentTestRequestConfig":{"oneOf":[{"$ref":"#/components/schemas/tts:ReplyConfig"},{"$ref":"#/components/schemas/tts:ToolCallConfig"},{"$ref":"#/components/schemas/tts:SimulationConfig"}],"description":"Replaces the test config when present.","title":"UpdateAgentTestRequestConfig"},"tts:UpdateAgentTestRequest":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"config":{"$ref":"#/components/schemas/tts:UpdateAgentTestRequestConfig","description":"Replaces the test config when present."},"tool_mock_config":{"$ref":"#/components/schemas/tts:ToolMockConfig","description":"Replaces the tool-mock config when present."},"folder_id":{"type":"string","description":"Prefixed wire identifier (`folder_<26 char Crockford base32>`)\nof the folder to move the test into.\n"},"clear_folder_id":{"type":"boolean","description":"When `true`, moves the test back to root (clears\n`folder_id`). Wins over `folder_id` when both are sent."}},"description":"Payload for `PATCH /v1/agents/tests/{id}`. All fields are optional;\nomitting a field leaves it unchanged. Set `folder_id` to a target\nfolder id to move the test into that folder; send\n`clear_folder_id: true` (folder_id omitted or ignored) to move\nthe test back to root. The clear flag is the explicit signal\nbecause JSON `null` is indistinguishable from absent for\npointer fields in Go's encoding/json.","title":"UpdateAgentTestRequest"},"tts:AgentTestAttachment":{"type":"object","properties":{"test_id":{"type":"string","description":"Prefixed wire identifier (`test_<26 char Crockford base32>`)\nof the attached test. ADR 0015 FK consistency.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the attached agent. ADR 0015 FK consistency.\n"},"created_at":{"type":"string","format":"date-time"}},"required":["test_id","agent_id","created_at"],"description":"One (test, agent) pair. Poll the `attached_agent_ids` field on `AgentTestWithLastRun` or hit `/v1/agents/tests/{id}/attachments` for the authoritative set.","title":"AgentTestAttachment"},"tts:ListAgentTestAttachmentsResponse":{"type":"object","properties":{"attachments":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestAttachment"}}},"required":["attachments"],"title":"ListAgentTestAttachmentsResponse"},"tts:AgentTestFolder":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`folder_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"parent_folder_id":{"type":["string","null"],"description":"When set, prefixed wire identifier\n(`folder_<26 char Crockford base32>`) of the parent folder.\nNull means root. ADR 0015 FK consistency.\n"},"name":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","created_at","updated_at"],"description":"One organisational node in the per-owner tests tree.","title":"AgentTestFolder"},"tts:ListAgentTestFoldersResponse":{"type":"object","properties":{"folders":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestFolder"}}},"required":["folders"],"title":"ListAgentTestFoldersResponse"},"tts:CreateAgentTestFolderRequest":{"type":"object","properties":{"name":{"type":"string"},"parent_folder_id":{"type":["string","null"],"description":"Prefixed wire identifier (`folder_<26 char Crockford base32>`)\nof the parent folder. Omit / null for a root-level folder.\n"}},"required":["name"],"title":"CreateAgentTestFolderRequest"},"tts:UpdateAgentTestFolderRequest":{"type":"object","properties":{"name":{"type":"string"},"parent_folder_id":{"type":"string","description":"Prefixed wire identifier (`folder_<26 char Crockford base32>`)\nof the folder to reparent this folder under.\n"},"clear_parent_folder_id":{"type":"boolean","description":"When `true`, reparents this folder to root (clears\n`parent_folder_id`). Wins over `parent_folder_id` when\nboth are sent."}},"description":"PATCH body. All fields optional; omit to leave unchanged. Set\n`parent_folder_id` to a target folder id to reparent into that\nfolder; send `clear_parent_folder_id: true` to reparent to\nroot. The clear flag is the explicit signal because JSON `null`\nis indistinguishable from absent for pointer fields in Go's\nencoding/json.","title":"UpdateAgentTestFolderRequest"},"tts:ListAgentTestRunsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"runs":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestRun"}}},"required":["next_cursor","has_more","runs"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListAgentTestRunsResponse"},"tts:BatchRunEntry":{"type":"object","properties":{"test_id":{"type":"string","description":"Prefixed wire identifier (`test_<26 char Crockford base32>`)\nof the test to run.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the agent to run the test against. Omit to fan out to\nevery agent the test is attached to.\n"}},"required":["test_id"],"description":"One entry in a batch-run request. Omit `agent_id` to fan out to\nevery agent the test is attached to.","title":"BatchRunEntry"},"tts:RunBatchRequest":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/tts:BatchRunEntry"}}},"required":["entries"],"description":"Batch-run payload. Total expanded runs across all entries are\ncapped at 100 per call.","title":"RunBatchRequest"},"tts:RunBatchResponse":{"type":"object","properties":{"runs":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestRun"}},"suite_run":{"oneOf":[{"$ref":"#/components/schemas/tts:AgentTestSuiteRun"},{"type":"null"}],"description":"The suite run grouping the queued runs."}},"required":["runs"],"title":"RunBatchResponse"},"tts:ListSuiteRunsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"suite_runs":{"type":"array","items":{"$ref":"#/components/schemas/tts:AgentTestSuiteRun"}}},"required":["next_cursor","has_more","suite_runs"],"description":"One page of suite runs, newest first. Walk pages while\n`has_more` is true; pass `next_cursor` back as the request\n`cursor` parameter.","title":"ListSuiteRunsResponse"},"tts:SuiteChildRun":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`run_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"test_id":{"type":"string","description":"Prefixed wire identifier (`test_<26 char Crockford base32>`)\nof the parent test. ADR 0015 FK consistency.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the agent this run executed against. ADR 0015 FK\nconsistency.\n"},"status":{"$ref":"#/components/schemas/tts:TestRunStatus"},"started_at":{"type":["string","null"],"format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"},"result":{"oneOf":[{"$ref":"#/components/schemas/tts:TestRunResult"},{"type":"null"}],"description":"Populated on terminal status only."},"error":{"type":"string","description":"Human-readable error message when status is `error`."},"created_at":{"type":"string","format":"date-time"},"test_name":{"type":"string","description":"Name of the test this run executed."}},"required":["id","test_id","agent_id","status","created_at","test_name"],"description":"One child run inside a suite run, carrying the parent test's\nname so the grouped result view can label each row.","title":"SuiteChildRun"},"tts:AgentTestSuiteRunWithRuns":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`srun_<26 char Crockford base32>`)."},"agent_id":{"type":["string","null"],"description":"Prefixed `agent_` id of the agent whose suite\nwas run. Set for the `run_all` trigger; null for `batch`,\nwhich can span many agents.\n"},"trigger":{"$ref":"#/components/schemas/tts:SuiteRunTrigger"},"parent_suite_run_id":{"type":["string","null"],"description":"Set on a `resubmit`: the prefixed `srun_` id of\nthe suite run whose failed/errored tests this one re-ran.\nNull for `run_all` and `batch`.\n"},"status":{"$ref":"#/components/schemas/tts:TestRunStatus"},"total_runs":{"type":"integer","description":"Number of child runs in the suite."},"passed_count":{"type":"integer"},"failed_count":{"type":"integer"},"errored_count":{"type":"integer"},"pending_count":{"type":"integer","description":"Child runs still queued or running."},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time","description":"Newest child-run completion; null until every child run is terminal."},"config_override":{"oneOf":[{"$ref":"#/components/schemas/tts:TestRunConfigOverride"},{"type":"null"}],"description":"The run-level config override (AIS-3443) this suite was run\nwith, or null for an ordinary Run All / batch."},"flow_version_id":{"type":["string","null"],"description":"The flow version (`agent_versions` row) this suite targeted,\nor null for the agent's active / synthesized flow."},"flow_version_number":{"type":["integer","null"],"description":"Human-facing version number of `flow_version_id`; null when no version was targeted."},"runs":{"type":"array","items":{"$ref":"#/components/schemas/tts:SuiteChildRun"}}},"required":["id","trigger","status","total_runs","passed_count","failed_count","errored_count","pending_count","created_at","runs"],"description":"A suite run plus every child run, for the grouped detail view.","title":"AgentTestSuiteRunWithRuns"},"tts:CreateToolRequestConfig":{"oneOf":[{"$ref":"#/components/schemas/tts:SystemToolConfig"},{"$ref":"#/components/schemas/tts:WebhookToolConfig"},{"$ref":"#/components/schemas/tts:ClientToolConfig"},{"$ref":"#/components/schemas/tts:MCPToolConfig"}],"title":"CreateToolRequestConfig"},"tts:CreateToolRequest":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"kind":{"$ref":"#/components/schemas/tts:ToolKind"},"config":{"$ref":"#/components/schemas/tts:CreateToolRequestConfig"}},"required":["name","description","kind","config"],"title":"CreateToolRequest"},"tts:ListToolsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"tools":{"type":"array","items":{"$ref":"#/components/schemas/tts:Tool"}}},"required":["next_cursor","has_more","tools"],"description":"Payload for `GET /v1/agents/tools` \u2014 the workspace-level tool\ncatalog. Cursor-paginated; the per-agent attached-tools endpoint\nuses a different (bare) shape \u2014 see AttachedToolsResponse.\n","title":"ListToolsResponse"},"tts:UpdateToolRequestConfig":{"oneOf":[{"$ref":"#/components/schemas/tts:SystemToolConfig"},{"$ref":"#/components/schemas/tts:WebhookToolConfig"},{"$ref":"#/components/schemas/tts:ClientToolConfig"},{"$ref":"#/components/schemas/tts:MCPToolConfig"}],"title":"UpdateToolRequestConfig"},"tts:UpdateToolRequest":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"config":{"$ref":"#/components/schemas/tts:UpdateToolRequestConfig"}},"description":"All fields optional. `kind` is immutable \u2014 create a new tool to change it.","title":"UpdateToolRequest"},"tts:SystemBuiltinInfo":{"type":"object","properties":{"name":{"$ref":"#/components/schemas/tts:SystemBuiltin"},"label":{"type":"string","description":"Console-facing display label for the builtin."},"description":{"type":"string","description":"Console-facing one-line summary of what the builtin does."}},"required":["name","label","description"],"description":"One entry in the system-builtin catalogue.","title":"SystemBuiltinInfo"},"tts:ListSystemBuiltinsResponse":{"type":"object","properties":{"builtins":{"type":"array","items":{"$ref":"#/components/schemas/tts:SystemBuiltinInfo"}}},"required":["builtins"],"title":"ListSystemBuiltinsResponse"},"tts:ToolAttachedAgent":{"type":"object","properties":{"id":{"type":"string","description":"Opaque agent ID."},"name":{"type":"string","description":"Human-readable agent name."}},"required":["id","name"],"description":"Minimal agent identity returned alongside a tool so the console\ncan render \"this tool is attached to: X, Y\" copy before a\ndestructive action runs (AIS-3347).\n","title":"ToolAttachedAgent"},"tts:ListToolAttachedAgentsResponse":{"type":"object","properties":{"agents":{"type":"array","items":{"$ref":"#/components/schemas/tts:ToolAttachedAgent"}}},"required":["agents"],"description":"Response shape for GET /v1/agents/tools/{id}/attached-agents.\nAgents are tenant-scoped and ordered by name ASC.\n","title":"ListToolAttachedAgentsResponse"},"tts:TestMCPConnectionRequest":{"type":"object","properties":{"config":{"$ref":"#/components/schemas/tts:MCPToolConfig"},"tool_id":{"type":"string","description":"Optional `tool_` id of the existing tool to hydrate\nstored secrets from. Raw UUIDs and other-resource prefixes are\nrejected.\n"}},"required":["config"],"description":"Body for `POST /v1/agents/tools/test-mcp-connection`. `config` is the\nsame MCPToolConfig shape `POST /v1/agents/tools` would persist; nothing\nis persisted by the probe itself. `tool_id` is only meaningful\nin the edit-form flow \u2014 when set, the server hydrates stored\nbearer / oauth2 secrets from the encrypted column before\nprobing, so customers can hit \"Test Connection\" on an existing\ntool without re-typing the secret.\n","title":"TestMCPConnectionRequest"},"tts:MCPProbeTool":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"}},"required":["name"],"description":"One discovered tool in a probe result.","title":"MCPProbeTool"},"tts:McpProbeErrorDetailsStage":{"type":"string","enum":["validation","oauth2_token","mcp_connect","mcp_initialize","mcp_notify","mcp_list_tools"],"title":"McpProbeErrorDetailsStage"},"tts:MCPProbeErrorDetails":{"type":"object","properties":{"stage":{"$ref":"#/components/schemas/tts:McpProbeErrorDetailsStage"},"http_status":{"type":"integer"},"oauth2_error":{"type":"string"},"oauth2_error_description":{"type":"string"},"upstream_body":{"type":"string"},"field_hint":{"type":"string"}},"description":"Structured upstream signal for an MCP probe failure. All fields\nare optional; the console renders what's present. `stage` names\nthe phase the probe was in (`validation`, `oauth2_token`,\n`mcp_connect`, `mcp_initialize`, `mcp_notify`, `mcp_list_tools`).\n`oauth2_error` / `oauth2_error_description` mirror RFC 6749 \u00a75.2\nwhen the customer's auth server returned the standard error\nshape. `http_status` is the upstream status code for transport\nfailures. `upstream_body` is a truncated prefix (max ~1 KiB) of\nthe upstream response body when the failure isn't structured.\n`field_hint` names a form field (`endpoint`, `transport`,\n`token`, `token_url`, `client_id`, `client_secret`, `scope`)\nthe console should highlight so the customer knows what to fix.\n","title":"MCPProbeErrorDetails"},"tts:MCPProbeResult":{"type":"object","properties":{"tools":{"type":["array","null"],"items":{"$ref":"#/components/schemas/tts:MCPProbeTool"}},"error":{"type":"string"},"details":{"$ref":"#/components/schemas/tts:MCPProbeErrorDetails"}},"required":["tools"],"description":"Result of an MCP probe. On success, `tools` is the discovered\ncatalogue and `error` is absent. On failure, `tools` is `null`\nand `error` carries a human-readable reason the console renders\ninline next to the form. `details` is optional structured\nsignal from the upstream (OAuth2 RFC 6749 fields, HTTP status,\ntruncated upstream body, form field hint) the console uses to\nexpand the inline banner and highlight the offending input.\nOlder consoles ignore `details` and fall back to `error`. Both\nvalidation and network failures land in `error` rather than\nnon-2xx responses, so consumers must check `error` before\nreading `tools`.\n","title":"MCPProbeResult"},"tts:TestWebhookConnectionRequest":{"type":"object","properties":{"config":{"$ref":"#/components/schemas/tts:WebhookToolConfig"},"tool_id":{"type":"string","description":"Optional `tool_` id of the existing tool to sign\nthe probe with. Raw UUIDs and other-resource prefixes are\nrejected.\n"}},"required":["config"],"description":"Body for `POST /v1/agents/tools/test-webhook-connection`.\n`config` is the same WebhookToolConfig shape `POST /v1/agents/tools`\nwould persist; nothing is persisted by the probe. `tool_id` is\nonly meaningful in the edit-form flow \u2014 when set, the server\nsigns the probe request with the tool's stored HMAC secret so\nthe test exercises the real signature path.\n","title":"TestWebhookConnectionRequest"},"tts:WebhookProbeResult":{"type":"object","properties":{"ok":{"type":"boolean"},"status_code":{"type":"integer","description":"HTTP status the endpoint returned. Absent on a transport failure."},"latency_ms":{"type":"integer","format":"int64","description":"Wall-clock round-trip time in milliseconds."},"response_body":{"type":"string","description":"Truncated prefix (max ~2 KiB) of the endpoint's response body."},"signed":{"type":"boolean","description":"Whether the probe request carried an HMAC signature header."},"error":{"type":"string","description":"Human-readable transport-level failure reason. Absent when any response was received."}},"required":["ok","signed"],"description":"Result of a webhook probe. `ok` is true only when the endpoint\nreturned a 2xx. A non-2xx response still populates `status_code`\nand `response_body` with `ok=false` \u2014 the request reached the\nendpoint, the endpoint just declined it. `error` is set only for\ntransport-level failures (DNS, connect, TLS, timeout, blocked\naddress range) where no response was received; `status_code` is\nabsent in that case. `signed` reports whether the probe carried\nan `X-Speechify-Signature` header \u2014 false on the create-form\nflow, which has no stored secret yet. Both success and failure\nuse the 200 envelope so the console renders them inline.\n","title":"WebhookProbeResult"},"tts:Caller":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`caller_<26 char Crockford base32>`).\nADR 0015 Cluster 2 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 2.\n"},"tenant_id":{"type":"string","description":"Prefixed wire identifier (`ws_<26 char Crockford base32>`) of\nthe owning workspace. ADR 0015 FK consistency.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the agent the caller is scoped under. ADR 0015 FK\nconsistency.\n"},"identity":{"type":"string","description":"The raw identifier the caller arrived with (E.164 phone for SIP, LiveKit\nparticipant id for web). Stable for the life of the caller row.\n"},"display_name":{"type":["string","null"],"description":"Operator-editable display name, nullable."},"external_ref":{"type":["string","null"],"description":"Optional handle into the customer's own CRM, nullable."},"metadata":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Customer-supplied JSON metadata blob."},"first_seen_at":{"type":"string","format":"date-time","description":"Timestamp of the earliest observed conversation / memory for this caller."},"last_seen_at":{"type":"string","format":"date-time","description":"Timestamp of the most recent observation. Drives the default list ordering."},"conversation_count":{"type":"integer","description":"Number of conversation rows currently pointing at this caller."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","tenant_id","agent_id","identity","metadata","first_seen_at","last_seen_at","conversation_count","created_at","updated_at"],"description":"First-class Caller entity (Phase 2 of ADR 0011). Identified by\nthe (tenant, agent, identity) triple. Memories and conversations\nFK at it via `caller_id`.\n","title":"Caller"},"tts:ListCallersResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"callers":{"type":"array","items":{"$ref":"#/components/schemas/tts:Caller"}}},"required":["next_cursor","has_more","callers"],"description":"Payload for GET /v1/agents/callers.","title":"ListCallersResponse"},"tts:GetCallerResponse":{"type":"object","properties":{"caller":{"$ref":"#/components/schemas/tts:Caller"}},"required":["caller"],"description":"Single-resource envelope used by GET / PATCH /v1/agents/callers/{id}.","title":"GetCallerResponse"},"tts:DeleteCallerResponse":{"type":"object","properties":{"caller_purged":{"type":"integer","description":"1 on the first delete; 0 on idempotent re-delete."},"memories_purged":{"type":"integer","description":"Number of user_memories rows cascade-soft-deleted under this caller."}},"required":["caller_purged","memories_purged"],"description":"Audit envelope returned by DELETE /v1/agents/callers/{id}. Surfaces\nthe cascade row counts so a privacy operator has direct evidence\nof the purge without re-querying.\n","title":"DeleteCallerResponse"},"tts:UpdateCallerRequest":{"type":"object","properties":{"display_name":{"type":["string","null"],"description":"Operator-editable display name. Empty string clears the column."},"external_ref":{"type":["string","null"],"description":"Optional handle into the customer's own CRM. Empty string clears the column."},"metadata":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Replacement metadata JSONB. Must not be `null`."}},"description":"PATCH payload. Omitted fields are unchanged; present fields\noverwrite. Empty string clears nullable text columns; `metadata`\nreplaces the JSONB blob in full when supplied.\n","title":"UpdateCallerRequest"},"tts:CallerMemoryItem":{"type":"object","properties":{"id":{"type":"string"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the owning agent. ADR 0015 FK consistency.\n"},"caller_identity":{"type":"string"},"fact":{"type":"string"},"source_conversation_id":{"type":["string","null"],"description":"When set, the prefixed wire identifier\n(`conv_<26 char Crockford base32>`) of the conversation this\nmemory was extracted from. ADR 0015 FK consistency.\n"},"confidence":{"type":"number","format":"double"},"created_at":{"type":"string","format":"date-time"}},"required":["id","agent_id","caller_identity","fact","confidence","created_at"],"description":"Memory projection returned by the per-caller memories list. Mirrors\nthe legacy `/v1/agents/{id}/memories` shape so console code can\nre-use existing renderers.\n","title":"CallerMemoryItem"},"tts:ListCallerMemoriesResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"memories":{"type":"array","items":{"$ref":"#/components/schemas/tts:CallerMemoryItem"}}},"required":["next_cursor","has_more","memories"],"description":"Payload for GET /v1/agents/callers/{id}/memories.","title":"ListCallerMemoriesResponse"},"tts:ListCallerConversationsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"conversations":{"type":"array","items":{"$ref":"#/components/schemas/tts:Conversation"}}},"required":["next_cursor","has_more","conversations"],"description":"Payload for GET /v1/agents/callers/{id}/conversations.","title":"ListCallerConversationsResponse"},"tts:AudioAsset":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`audio_<26 char Crockford base32>`).\nADR 0015 Cluster 2 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 2.\n"},"original_filename":{"type":"string","description":"The filename supplied at upload time, kept for display."},"content_type":{"type":"string","description":"Always `audio/wav`. Pinned server-side after WAV validation\nrather than trusting the upload's multipart Content-Type\nheader.\n"},"size_bytes":{"type":"integer","description":"Stored byte length. Capped at 4 MiB at upload time."},"duration_ms":{"type":"integer","description":"Clip duration in milliseconds. Capped at 30000 (30s) at upload time."},"sample_rate_hz":{"type":"integer","description":"WAV sample rate. Always 48000 (matches the LiveKit room rate)."},"channels":{"type":"integer","description":"Channel count. Always 1 (mono)."},"bit_depth":{"type":"integer","description":"PCM sample bit depth. Always 16."},"created_at":{"type":"string","format":"date-time"}},"required":["id","original_filename","content_type","size_bytes","duration_ms","sample_rate_hz","channels","bit_depth","created_at"],"description":"Metadata for a pre-recorded WAV clip stored in the workspace's\naudio-asset bucket. Bytes are immutable once uploaded \u2014 to\nreplace a clip, upload a new asset and update any references.\n","title":"AudioAsset"},"tts:ListAudioAssetsResponse":{"type":"object","properties":{"assets":{"type":"array","items":{"$ref":"#/components/schemas/tts:AudioAsset"}}},"required":["assets"],"title":"ListAudioAssetsResponse"},"tts:UploadAudioAssetResponse":{"type":"object","properties":{"asset":{"$ref":"#/components/schemas/tts:AudioAsset"}},"required":["asset"],"title":"UploadAudioAssetResponse"},"tts:FlowVersion":{"type":"object","properties":{"id":{"type":"string","description":"Flow version id. A raw UUID, not a prefixed external id."},"agent_id":{"type":"string"},"version":{"type":"integer","description":"Monotonic revision number within the agent."},"parent_version_id":{"type":["string","null"]},"is_active":{"type":"boolean"},"is_draft":{"type":"boolean"},"name":{"type":"string"},"notes":{"type":"string"},"published_by":{"type":"string"},"published_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","agent_id","version","is_active","is_draft"],"description":"One published or draft revision of an agent's flow graph.","title":"FlowVersion"},"tts:FlowGraphNodesItems":{"type":"object","properties":{},"title":"FlowGraphNodesItems"},"tts:FlowGraphEdgesItems":{"type":"object","properties":{},"title":"FlowGraphEdgesItems"},"tts:FlowGraphVariablesItems":{"type":"object","properties":{},"title":"FlowGraphVariablesItems"},"tts:FlowGraph":{"type":"object","properties":{"version":{"$ref":"#/components/schemas/tts:FlowVersion"},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowGraphNodesItems"}},"edges":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowGraphEdgesItems"}},"variables":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowGraphVariablesItems"}}},"required":["version","nodes","edges"],"description":"A flow graph: an ordered set of typed nodes connected by edges,\nplus flow variables. The node, edge, and variable shapes are\ngoverned by the live JSON Schema at GET /v1/agents/flow/schema\nand are intentionally opaque here so this spec cannot drift\nfrom that authoritative definition.\n","title":"FlowGraph"},"tts:GetFlowResponse":{"type":"object","properties":{"draft":{"$ref":"#/components/schemas/tts:FlowGraph"},"active":{"$ref":"#/components/schemas/tts:FlowGraph"},"history":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowVersion"}}},"required":["history"],"description":"Response for GET /v1/agents/{id}/flow.","title":"GetFlowResponse"},"tts:PutFlowRequestNodesItems":{"type":"object","properties":{},"title":"PutFlowRequestNodesItems"},"tts:PutFlowRequestEdgesItems":{"type":"object","properties":{},"title":"PutFlowRequestEdgesItems"},"tts:PutFlowRequestVariablesItems":{"type":"object","properties":{},"title":"PutFlowRequestVariablesItems"},"tts:PutFlowRequest":{"type":"object","properties":{"name":{"type":"string"},"notes":{"type":"string"},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/tts:PutFlowRequestNodesItems"}},"edges":{"type":"array","items":{"$ref":"#/components/schemas/tts:PutFlowRequestEdgesItems"}},"variables":{"type":"array","items":{"$ref":"#/components/schemas/tts:PutFlowRequestVariablesItems"}}},"required":["nodes","edges"],"description":"Request body for PUT /v1/agents/{id}/flow. Replaces the draft graph.","title":"PutFlowRequest"},"tts:PublishFlowRequest":{"type":"object","properties":{"notes":{"type":"string","description":"Optional changelog note recorded on the published version."}},"description":"Optional body for POST /v1/agents/{id}/flow/publish.","title":"PublishFlowRequest"},"tts:RollbackFlowRequest":{"type":"object","properties":{"version_id":{"type":"string","description":"The flow version to roll back to."}},"required":["version_id"],"title":"RollbackFlowRequest"},"tts:ListFlowVersionsResponse":{"type":"object","properties":{"versions":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowVersion"}}},"required":["versions"],"title":"ListFlowVersionsResponse"},"tts:GetFlowVersionResponse":{"type":"object","properties":{"graph":{"$ref":"#/components/schemas/tts:FlowGraph"}},"required":["graph"],"title":"GetFlowVersionResponse"},"tts:flow_getSchema_Response_200":{"type":"object","properties":{},"title":"flow_getSchema_Response_200"},"tts:FlowTemplate":{"type":"object","properties":{"id":{"type":"string","description":"Flow template id. A raw UUID, not a prefixed external id."},"key":{"type":"string","description":"Stable unique key for the template."},"name":{"type":"string"},"description":{"type":"string"},"category":{"type":"string"},"graph":{"$ref":"#/components/schemas/tts:FlowGraph"},"is_seed":{"type":"boolean","description":"True for platform-provided templates."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","key","name","category","graph","is_seed","created_at","updated_at"],"description":"A reusable flow graph that can be cloned onto an agent as a new draft.","title":"FlowTemplate"},"tts:ListFlowTemplatesResponse":{"type":"object","properties":{"templates":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowTemplate"}}},"required":["templates"],"title":"ListFlowTemplatesResponse"},"tts:FlowGraphInputNodesItems":{"type":"object","properties":{},"title":"FlowGraphInputNodesItems"},"tts:FlowGraphInputEdgesItems":{"type":"object","properties":{},"title":"FlowGraphInputEdgesItems"},"tts:FlowGraphInputVariablesItems":{"type":"object","properties":{},"title":"FlowGraphInputVariablesItems"},"tts:FlowGraphInput":{"type":"object","properties":{"nodes":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowGraphInputNodesItems"}},"edges":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowGraphInputEdgesItems"}},"variables":{"type":"array","items":{"$ref":"#/components/schemas/tts:FlowGraphInputVariablesItems"}}},"required":["nodes","edges"],"description":"Request-side flow graph: nodes, edges, and variables only.\nUnlike the response-side FlowGraph it carries no `version`\nblock - the server owns version metadata.\n","title":"FlowGraphInput"},"tts:CreateFlowTemplateRequest":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","description":"Defaults to \"custom\" when omitted."},"graph":{"$ref":"#/components/schemas/tts:FlowGraphInput"}},"required":["key","name","graph"],"description":"Request body for creating (POST) or replacing (PATCH) a flow\ntemplate. PATCH replaces the whole template, it is not a\nfield-by-field patch.\n","title":"CreateFlowTemplateRequest"},"tts:CloneFlowTemplateRequest":{"type":"object","properties":{"agent_id":{"type":"string","description":"The agent that receives the cloned graph as a new draft."}},"required":["agent_id"],"title":"CloneFlowTemplateRequest"},"tts:ShadowConversationResponse":{"type":"object","properties":{"conversation_id":{"type":"string"},"room_name":{"type":"string"},"livekit_url":{"type":"string","description":"wss://\u2026 signaling URL for the LiveKit project hosting the room."},"token":{"type":"string","description":"Short-lived LiveKit access token. Grant has CanPublish=false,\nCanPublishData=false, CanSubscribe=true, Hidden=true so the\nobserver can listen but cannot speak and is invisible to the\ncaller and the agent.\n"},"identity":{"type":"string","description":"Opaque participant identity tag (e.g. shadow_). Visible only to admin tooling."},"expires_at":{"type":"string","format":"date-time","description":"When the token stops being accepted by LiveKit. The console should re-mint past this point."}},"required":["conversation_id","room_name","livekit_url","token","identity","expires_at"],"description":"Connection details for an authorized observer (workspace owner or\nadmin) joining an active conversation as a hidden, listen-only\nparticipant. The livekit-client SDK consumes `livekit_url` +\n`token` to attach to the live room and play the agent + caller\naudio tracks.\n","title":"ShadowConversationResponse"},"tts:BatchRecipientRequest":{"type":"object","properties":{"phone":{"type":"string","description":"Recipient phone number in E.164 format."},"dynamic_vars":{"type":"object","additionalProperties":{"type":"string"},"description":"Per-recipient variable overrides injected into the agent prompt."}},"required":["phone"],"description":"One entry in a batch-call request.","title":"BatchRecipientRequest"},"tts:CreateBatchCallRequest":{"type":"object","properties":{"name":{"type":"string","description":"Human-readable batch name."},"agent_id":{"type":"string","description":"Agent that handles each call."},"phone_number_id":{"type":"string","description":"Caller-ID override. Falls back to the agent's bound number."},"scheduled_at":{"type":"string","format":"date-time","description":"Schedule the batch for a future time (RFC 3339). Omit to start immediately."},"ringing_timeout_ms":{"type":"integer","description":"Ringing timeout in milliseconds applied to every call in the\nbatch (how long each recipient rings before the dial gives\nup). Range 1000-80000 (1-80s). Omit to use the 30s default.\nThe console collects this in seconds and converts to\nmilliseconds.\n"},"recipients":{"type":"array","items":{"$ref":"#/components/schemas/tts:BatchRecipientRequest"}}},"required":["name","agent_id","recipients"],"description":"Body for `POST /v1/agents/batch-calls`. Also accepts `multipart/form-data`\nwith a CSV file upload (`csv_file` field) where the `phone` column is\nrequired and remaining columns become per-recipient `dynamic_vars`.\n","title":"CreateBatchCallRequest"},"tts:BatchCallStatus":{"type":"string","enum":["pending","scheduled","running","completed","failed","cancelled"],"title":"BatchCallStatus"},"tts:BatchCall":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`batch_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"agent_id":{"type":"string","description":"Prefixed wire identifier (`agent_<26 char Crockford base32>`)\nof the agent that will run the batch. ADR 0015 FK consistency.\n"},"phone_number_id":{"type":["string","null"],"description":"Caller-ID override. When set, prefixed wire identifier\n(`phone_<26 char Crockford base32>`) of the phone number to\nuse; falls back to the agent's bound number when null. ADR\n0015 FK consistency.\n"},"name":{"type":"string","description":"Human-readable batch name."},"status":{"$ref":"#/components/schemas/tts:BatchCallStatus"},"total":{"type":"integer","description":"Total number of recipients."},"completed":{"type":"integer","description":"Recipients successfully dialed."},"failed":{"type":"integer","description":"Recipients that failed."},"error":{"type":"string","description":"Populated when the batch itself fails."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"started_at":{"type":["string","null"],"format":"date-time","description":"When the dispatcher started dialing."},"finished_at":{"type":["string","null"],"format":"date-time","description":"When the last recipient was resolved."},"scheduled_at":{"type":["string","null"],"format":"date-time","description":"If set, the batch waits until this time before dialing."},"ringing_timeout_ms":{"type":["integer","null"],"description":"Per-call ringing timeout in milliseconds applied to every\nrecipient in the batch. Null when the batch uses the 30s\ndefault.\n"}},"required":["id","agent_id","name","status","total","completed","failed","created_at","updated_at"],"description":"A batch of outbound calls dispatched to a list of recipients.","title":"BatchCall"},"tts:CreateBatchCallResponse":{"type":"object","properties":{"batch":{"$ref":"#/components/schemas/tts:BatchCall"}},"required":["batch"],"title":"CreateBatchCallResponse"},"tts:ListBatchCallsResponse":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Opaque keyset cursor for the next page. Pass back as the\n`cursor` request parameter. `null` when the caller has\nreached the end of the list (`has_more` is also `false`\nin that case).\n"},"has_more":{"type":"boolean","description":"True when more rows exist beyond this page."},"batches":{"type":"array","items":{"$ref":"#/components/schemas/tts:BatchCall"}}},"required":["next_cursor","has_more","batches"],"description":"Shared pagination metadata composed into every cursor-paginated\nlist response via `allOf`. See [ADR 0013](../docs/adrs/0013-list-pagination-conventions.md)\nfor the convention and the rationale for shipping `has_more`\nalongside `next_cursor` (defense-in-depth across two equivalent\nend-of-pages signals).\n","title":"ListBatchCallsResponse"},"tts:BatchRecipientStatus":{"type":"string","enum":["pending","dialing","completed","failed"],"title":"BatchRecipientStatus"},"tts:BatchRecipient":{"type":"object","properties":{"id":{"type":"string"},"batch_id":{"type":"string","description":"Prefixed wire identifier (`batch_<26 char Crockford base32>`)\nof the parent batch. ADR 0015 FK consistency.\n"},"phone":{"type":"string","description":"Recipient phone number in E.164 format."},"dynamic_vars":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-recipient variable overrides injected into the agent prompt."},"status":{"$ref":"#/components/schemas/tts:BatchRecipientStatus"},"conversation_id":{"type":["string","null"],"description":"Set once the call is placed. Prefixed wire identifier\n(`conv_<26 char Crockford base32>`). ADR 0015 FK consistency.\n"},"error":{"type":"string","description":"Populated when this recipient fails."},"attempted_at":{"type":["string","null"],"format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"}},"required":["id","batch_id","phone","status"],"description":"One recipient row in a batch call.","title":"BatchRecipient"},"tts:GetBatchCallResponse":{"type":"object","properties":{"batch":{"$ref":"#/components/schemas/tts:BatchCall"},"recipients":{"type":"array","items":{"$ref":"#/components/schemas/tts:BatchRecipient"}}},"required":["batch","recipients"],"description":"Batch row plus all recipients for the detail view.","title":"GetBatchCallResponse"},"tts:CreateOutboundCallRequest":{"type":"object","properties":{"agent_id":{"type":"string","description":"ID of the agent that handles the answered call."},"to":{"type":"string","description":"Destination phone number in E.164 format (e.g. `+12025559876`)."},"caller_id_number":{"type":"string","description":"The number shown to the callee as caller ID, in E.164 format.\nDefaults to the first outbound-capable number in the workspace.\nUseful for multi-number campaigns where you want to rotate\ncaller IDs.\n"},"dtmf_prefix":{"type":"string","description":"DTMF digits dialed automatically after the call is answered,\nbefore the agent begins speaking. Use this for IVR navigation\n(e.g. `1ww2` presses 1, waits two seconds, presses 2). `w`\nis a half-second pause; `W` is a one-second pause.\n"},"dynamic_variables":{"type":"object","additionalProperties":{"description":"Any type"},"description":"Per-call variable overrides merged on top of the agent's stored\ndefaults. Keys must not use the reserved `system__` prefix.\nUseful for injecting per-call context (customer name, order ID)\ninto the agent prompt.\n"},"ringing_timeout_ms":{"type":"integer","description":"How long to wait for the callee to answer before abandoning,\nin milliseconds. Defaults to 30000 (30s). Capped at 80000 (80s).\n"},"amd":{"$ref":"#/components/schemas/tts:AMDConfig","description":"Optional per-call override for the AMD routing config. When\nset, wholesale-replaces the agent's stored AMD shape for\nthis single call (PATCH-replace, not merge). Unlocks the\nbatch-campaign pattern: one agent dialling many recipients\nwith per-row tailored voicemail messages via the existing\ndynamic_variables substitution. Validation rules match\nthe agent-update boundary.\n"}},"required":["agent_id","to"],"description":"Body for `POST /v1/agents/outbound-calls`. Requires a Twilio or BYOC\ntrunk; LiveKit-native numbers do not support outbound today.\n","title":"CreateOutboundCallRequest"},"tts:CreateOutboundCallResponse":{"type":"object","properties":{"conversation_id":{"type":"string","description":"ID of the conversation created for this call. Use to poll status."},"room":{"type":"string","description":"LiveKit room name the answered call joins."},"sip_participant_id":{"type":"string","description":"LiveKit participant ID for the outbound SIP call leg."}},"required":["conversation_id","room","sip_participant_id"],"description":"Returned synchronously when LiveKit accepts the SIP INVITE. Poll\n`GET /v1/agents/conversations/{conversation_id}` for status transitions:\n`pending` (ringing) \u2192 `active` (answered) \u2192 `completed`.\n","title":"CreateOutboundCallResponse"},"tts:PhoneNumberSource":{"type":"string","enum":["livekit","twilio","byoc","twilio_purchased","verified_caller_id"],"description":"Where the number came from. Determines the provisioning and\nportability path.\n\n- `livekit` - LiveKit owns the carrier relationship; US inbound only.\n- `twilio` - Customer's own Twilio number bridged via Elastic SIP Trunk.\n- `byoc` - Any SIP provider using a customer-supplied trunk.\n- `twilio_purchased` - Bought through `POST /v1/agents/phone-numbers/purchase` on Speechify's master Twilio account; billed to Speechify.\n- `verified_caller_id` - Customer-verified outbound caller ID on\n their own Twilio account (Twilio's OutgoingCallerIds resource).\n Server-determined at import time: when an `e164` submitted with\n `source=twilio` is not a full DID on the customer's account but\n IS a verified caller ID, the resulting row gets this source.\n Outbound-only, never agent-bindable, rides the customer's\n existing shared Twilio trunk for outbound routing. Requires a\n prior `twilio` full-DID import from the same account; without\n it the import returns 400.\n","title":"PhoneNumberSource"},"tts:TwilioImportSpec":{"type":"object","properties":{"account_sid":{"type":"string","description":"Twilio Account SID (starts with `AC`)."},"auth_token":{"type":"string","description":"Twilio Auth Token. Write-only - never echoed back."}},"required":["account_sid","auth_token"],"description":"Twilio credentials for the one-click import flow. Used only when\n`source=twilio`. The Account SID and Auth Token are used to\nprovision an Elastic SIP Trunk on the customer's Twilio account\npointing at LiveKit's SIP endpoint, then stored for future trunk\nmanagement operations.\n","title":"TwilioImportSpec"},"tts:ImportPhoneNumberRequest":{"type":"object","properties":{"e164":{"type":"string","description":"The phone number in E.164 format. For `source=livekit` this\nis the number you want LiveKit to purchase. For `source=twilio`\nand `source=byoc` it is the number you already own.\n"},"source":{"$ref":"#/components/schemas/tts:PhoneNumberSource"},"label":{"type":"string","description":"Optional human-readable label."},"trunk_id":{"type":"string","description":"For `source=byoc`: the SIP trunk to bind this number to.\nPrefixed wire identifier (`trunk_<26 char Crockford base32>`).\nNot required for `source=livekit` or `source=twilio`.\n"},"agent_id":{"type":"string","description":"Optional agent to bind on import. Prefixed wire identifier\n(`agent_<26 char Crockford base32>`).\n"},"twilio":{"$ref":"#/components/schemas/tts:TwilioImportSpec"}},"required":["e164","source"],"description":"Body for `POST /v1/agents/phone-numbers`. The required fields vary by\n`source` - see the individual source descriptions.\n","title":"ImportPhoneNumberRequest"},"tts:PhoneNumberCapability":{"type":"string","enum":["inbound","outbound"],"description":"What the number can do. LiveKit-native numbers are `inbound` only;\nverified caller IDs are `outbound` only; Twilio and BYOC full-DID\nnumbers (and Speechify-purchased numbers) support both directions.\n","title":"PhoneNumberCapability"},"tts:PhoneNumber":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`phone_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"e164":{"type":"string","description":"The phone number in E.164 format (e.g. `+12025551234`)."},"source":{"$ref":"#/components/schemas/tts:PhoneNumberSource"},"label":{"type":"string","description":"Optional human-readable label set by the customer."},"trunk_id":{"type":"string","description":"ID of the SIP trunk backing this number, if applicable."},"agent_id":{"type":"string","description":"ID of the agent that answers calls to this number. Null when unbound."},"capabilities":{"type":"array","items":{"$ref":"#/components/schemas/tts:PhoneNumberCapability"},"description":"What this number can do."},"livekit_phone_number_id":{"type":"string","description":"LiveKit's own phone number ID (populated for `source=livekit` only)."},"created_at":{"type":"string","format":"date-time","description":"When the number was imported."},"updated_at":{"type":"string","format":"date-time","description":"When the number was last modified."}},"required":["id","e164","source","capabilities","created_at","updated_at"],"description":"A phone number in the workspace inventory. Bound to an agent via\n`agent_id`; unbound numbers are valid but non-functional until\nassigned.\n","title":"PhoneNumber"},"tts:ListPhoneNumbersResponse":{"type":"object","properties":{"numbers":{"type":"array","items":{"$ref":"#/components/schemas/tts:PhoneNumber"},"description":"Phone numbers in the workspace (up to 100)."}},"required":["numbers"],"description":"Response for `GET /v1/agents/phone-numbers`.","title":"ListPhoneNumbersResponse"},"tts:UpdatePhoneNumberRequest":{"type":"object","properties":{"label":{"type":"string","description":"New label. Pass an empty string to clear."},"agent_id":{"type":"string","description":"Agent to bind the number to. Prefixed wire identifier\n(`agent_<26 char Crockford base32>`).\n"},"clear_agent_id":{"type":"boolean","description":"When `true`, unbinds the current agent (clears `agent_id`).\nWins over `agent_id` when both are sent."}},"description":"PATCH body for `PATCH /v1/agents/phone-numbers/{id}`. Only `label`,\n`agent_id`, and `clear_agent_id` are mutable; `source` and `e164`\nare immutable after import. Set `agent_id` to bind a new agent;\nsend `clear_agent_id: true` to unbind. The clear flag is the\nexplicit signal because JSON `null` is indistinguishable from\nabsent for pointer fields in Go's encoding/json.\n","title":"UpdatePhoneNumberRequest"},"tts:AvailablePhoneNumber":{"type":"object","properties":{"e164":{"type":"string","description":"The phone number in E.164 format."},"friendly_name":{"type":"string","description":"Carrier-formatted display variant, e.g. \"(415) 555-2671\"."},"locality":{"type":"string","description":"City the number is associated with, when known."},"region":{"type":"string","description":"Two-letter state code for US numbers."},"iso_country":{"type":"string","description":"ISO-3166 alpha-2 country code."}},"required":["e164","iso_country"],"description":"One hit from `GET /v1/agents/phone-numbers/available`. The number is\nnot held: a concurrent buy by another customer may take it\nbetween this response and a subsequent purchase request.\n","title":"AvailablePhoneNumber"},"tts:SearchAvailablePhoneNumbersResponse":{"type":"object","properties":{"numbers":{"type":"array","items":{"$ref":"#/components/schemas/tts:AvailablePhoneNumber"},"description":"Available numbers (may be empty if no inventory matches)."}},"required":["numbers"],"description":"Response for `GET /v1/agents/phone-numbers/available`.","title":"SearchAvailablePhoneNumbersResponse"},"tts:PurchasePhoneNumberRequest":{"type":"object","properties":{"e164":{"type":"string","description":"The E.164 number to buy. Must currently be in carrier inventory."},"label":{"type":"string","description":"Optional human-readable label."},"agent_id":{"type":"string","description":"Optional agent to bind the number to at purchase time.\nPrefixed wire identifier (`agent_<26 char Crockford base32>`).\n"}},"required":["e164"],"description":"Body for `POST /v1/agents/phone-numbers/purchase`. The `e164` must come\nfrom a recent `SearchAvailablePhoneNumbers` response.\n","title":"PurchasePhoneNumberRequest"},"tts:SIPTrunkKind":{"type":"string","enum":["livekit","twilio","byoc"],"description":"Where the trunk came from. Informs the provisioning path and\nportability story.\n\n- `livekit` - Provisioned by LiveKit's native phone-number API.\n- `twilio` - Backed by a Twilio Elastic SIP Trunk on the customer's account.\n- `byoc` - Any SIP provider with a customer-managed trunk.\n","title":"SIPTrunkKind"},"tts:SIPTrunkDirection":{"type":"string","enum":["inbound","outbound","both"],"description":"Whether the trunk handles inbound calls, outbound calls, or both.\nA `both` trunk has distinct LiveKit inbound and outbound trunk IDs.\n","title":"SIPTrunkDirection"},"tts:SIPTransport":{"type":"string","enum":["auto","udp","tcp","tls"],"description":"SIP transport protocol. `auto` lets LiveKit negotiate. Use `tls`\nfor production where available - note that TLS is incompatible\nwith SIP REFER (cold transfer). Trunks that need `transfer_to_number`\nshould use `udp` or `tcp`.\n","title":"SIPTransport"},"tts:SIPMediaEncryption":{"type":"string","enum":["disable","allow","require"],"description":"SRTP media encryption policy.\n\n- `disable` - Unencrypted media only.\n- `allow` - Negotiate SRTP; fall back to unencrypted. Recommended default.\n- `require` - Reject calls that do not support SRTP.\n","title":"SIPMediaEncryption"},"tts:CreateSipTrunkRequestCredentials":{"type":"object","properties":{},"description":"Provider-specific credential blob (for future extensibility).","title":"CreateSipTrunkRequestCredentials"},"tts:CreateSIPTrunkRequest":{"type":"object","properties":{"name":{"type":"string","description":"Human-readable name for the trunk."},"kind":{"$ref":"#/components/schemas/tts:SIPTrunkKind"},"direction":{"$ref":"#/components/schemas/tts:SIPTrunkDirection"},"sip_address":{"type":"string","description":"SIP endpoint hostname. Required for `kind=byoc`."},"auth_username":{"type":"string","description":"SIP digest auth username."},"auth_password":{"type":"string","description":"SIP digest auth password. Write-only."},"allowed_addresses":{"type":"array","items":{"type":"string"},"description":"IP / CIDR allowlist for inbound connections. Empty means any source is accepted."},"destination_country":{"type":"string","description":"ISO 3166-1 alpha-2 country for the outbound dial plan."},"transport":{"$ref":"#/components/schemas/tts:SIPTransport"},"media_encryption":{"$ref":"#/components/schemas/tts:SIPMediaEncryption"},"credentials":{"$ref":"#/components/schemas/tts:CreateSipTrunkRequestCredentials","description":"Provider-specific credential blob (for future extensibility)."}},"required":["name","kind","direction"],"description":"Body for `POST /v1/agents/sip-trunks`.","title":"CreateSIPTrunkRequest"},"tts:SIPTrunk":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`trunk_<26 char Crockford base32>`).\nADR 0015 Cluster 3 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 3.\n"},"name":{"type":"string","description":"Human-readable name."},"kind":{"$ref":"#/components/schemas/tts:SIPTrunkKind"},"direction":{"$ref":"#/components/schemas/tts:SIPTrunkDirection"},"livekit_inbound_trunk_id":{"type":"string","description":"LiveKit's inbound trunk ID (present when direction is `inbound` or `both`)."},"livekit_outbound_trunk_id":{"type":"string","description":"LiveKit's outbound trunk ID (present when direction is `outbound` or `both`)."},"livekit_dispatch_rule_id":{"type":"string","description":"LiveKit dispatch rule ID that routes inbound calls into rooms."},"sip_address":{"type":"string","description":"SIP endpoint hostname (e.g. `sip.telnyx.com`). Required for `kind=byoc`."},"auth_username":{"type":"string","description":"SIP digest auth username."},"auth_password_set":{"type":"boolean","description":"Whether a SIP digest auth password is configured. The value is never returned."},"allowed_addresses":{"type":"array","items":{"type":"string"},"description":"IP address / CIDR allowlist for inbound SIP connections."},"destination_country":{"type":"string","description":"ISO 3166-1 alpha-2 country code for the outbound dial plan\n(e.g. `US`, `DE`). Required for international outbound on\nsome carriers.\n"},"transport":{"$ref":"#/components/schemas/tts:SIPTransport"},"media_encryption":{"$ref":"#/components/schemas/tts:SIPMediaEncryption"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","kind","direction","allowed_addresses","transport","media_encryption","created_at","updated_at"],"description":"A SIP trunk in the workspace. Trunks back one or more phone numbers\nand hold the carrier credentials LiveKit uses to route calls.\n`auth_password` is never echoed - `auth_password_set` indicates\nwhether one is configured.\n","title":"SIPTrunk"},"tts:ListSIPTrunksResponse":{"type":"object","properties":{"trunks":{"type":"array","items":{"$ref":"#/components/schemas/tts:SIPTrunk"},"description":"SIP trunks in the workspace (up to 20)."}},"required":["trunks"],"description":"Response for `GET /v1/agents/sip-trunks`.","title":"ListSIPTrunksResponse"},"tts:IvrMenuListEntryMenuTree":{"type":"object","properties":{},"title":"IvrMenuListEntryMenuTree"},"tts:IVRMenuListEntry":{"type":"object","properties":{"menu_id":{"type":"string","description":"Prefixed wire identifier (`menu_<26 char Crockford base32>`)."},"fingerprint_id":{"type":"string"},"fingerprint_hash":{"type":"string"},"transcript_sample":{"type":"string"},"schema_version":{"type":"integer"},"menu_tree":{"$ref":"#/components/schemas/tts:IvrMenuListEntryMenuTree"},"confidence_score":{"type":"number","format":"double"},"succeeded_traversals":{"type":"integer"},"total_traversals":{"type":"integer"},"last_validated_at":{"type":"string","format":"date-time"},"last_observed_at":{"type":"string","format":"date-time"},"occurrence_count":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}},"required":["menu_id","fingerprint_id","fingerprint_hash","transcript_sample","schema_version","menu_tree","confidence_score","succeeded_traversals","total_traversals","last_validated_at","last_observed_at","occurrence_count","created_at"],"description":"One row in the list-IVR-menus response. Carries the fingerprint\nhash + sample transcript so the console can render the IVR\nidentity without a second round-trip. `last_observed_at` and\n`occurrence_count` are projected from `ivr_fingerprints` for\nthe \"when did we last see this IVR\" signal.\n","title":"IVRMenuListEntry"},"tts:ListIVRMenusResponse":{"type":"object","properties":{"menus":{"type":"array","items":{"$ref":"#/components/schemas/tts:IVRMenuListEntry"}}},"required":["menus"],"title":"ListIVRMenusResponse"},"tts:IvrMenuMenuTree":{"type":"object","properties":{},"description":"Validated menu_tree per contracts/agents/ivr_menu.schema.json. Opaque to consumers other than the worker.","title":"IvrMenuMenuTree"},"tts:IVRMenu":{"type":"object","properties":{"id":{"type":"string","description":"Prefixed wire identifier (`menu_<26 char Crockford base32>`).\nADR 0015 Cluster 2 hard-break: URL paths accept only this\nprefixed form; legacy UUID path parameters are rejected with\n404 as of Cluster 2.\n"},"fingerprint_id":{"type":"string"},"tenant_id":{"type":["string","null"],"description":"Null on the cross-tenant promoted slot."},"schema_version":{"type":"integer"},"menu_tree":{"$ref":"#/components/schemas/tts:IvrMenuMenuTree","description":"Validated menu_tree per contracts/agents/ivr_menu.schema.json. Opaque to consumers other than the worker."},"confidence_score":{"type":"number","format":"double"},"succeeded_traversals":{"type":"integer"},"total_traversals":{"type":"integer"},"last_validated_at":{"type":"string","format":"date-time"},"invalidated_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","fingerprint_id","schema_version","menu_tree","confidence_score","succeeded_traversals","total_traversals","last_validated_at","created_at","updated_at"],"description":"One memorized IVR menu level (AIS-3267). Identified by the\nSHA-256 fingerprint of the normalized greeting transcript;\nscoped to the caller's workspace (foreign-tenant menus are\nnever returned).\n\n`menu_tree` is the validated JSONB blob the worker consumes:\nprompt text plus the options offered (label + DTMF). Sub-menus\nreached by pressing an option are their own rows, looked up at\ndescent time by a fresh fingerprint - the tree structure is the\nimplicit graph of fingerprint -> fingerprint transitions.\n\n`confidence_score` is `succeeded_traversals / total_traversals`\n(ADR 0009 \u00a73). The worker's plan-then-execute fast path only\nactivates at or above 0.5.\n\n`invalidated_at` is non-null on a soft-deleted row; the API\nfilters these out of list / lookup / get responses so this field\nis informational only.\n","title":"IVRMenu"},"tts:UpdateIVRMenuLabelRequest":{"type":"object","properties":{"dtmf":{"type":"string","description":"DTMF value of the option to relabel (e.g. \"1\", \"*\", \"#\")."},"label":{"type":"string","description":"New label. Capped at 256 chars server-side."}},"required":["dtmf","label"],"description":"Re-label one option in the stored menu_tree. The option is\nmatched by its DTMF value; the label is the human-readable text\nrendered in the console + surfaced to the LLM at navigate time.\n","title":"UpdateIVRMenuLabelRequest"},"tts:InvalidateIVRMenuRequest":{"type":"object","properties":{"reason":{"type":"string","description":"Operator-debug cause string. Bounded to 256 chars."}},"description":"Optional reason captured in structured logs. The column today\nis the timestamp, not the cause; a future audit table may\npersist the reason if customer demand justifies it.\n","title":"InvalidateIVRMenuRequest"}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Enter your API key with the `Bearer` prefix, e.g. 'Bearer sk_...'."}}}}