LeaderboardBack to leaderboard — loading return destination
Opening report…
Loading report overview
M
MCP server
server.example.com/mcp
Tools and resources for your MCP client, with a public quality report and detailed checks.
Protocol
MCP 2025-11-25
Server version
1.0.0
Website
server.example.com
Supports
Tools · Resources
Overall score
90 /100
How is this score calculated?
Server metadata
Loading server metadata
Reviewed90/100
Discoverability
Loading discoverability
Reviewed90/100
Protocol
Loading protocol
Reviewed90/100
Tools
Loading tools
Reviewed90/100
MCP Apps
Loading mcp apps
Reviewed90/100
Tool documentation quality
Loading tool documentation quality
Reviewed90/100
LeaderboardBack to leaderboard — loading return destination
B
Bluejay
api.getbluejay.ai/mcp
Test and monitor voice and chat AI agents. Create agents and digital humans, run simulations against your agent, read transcripts, evaluations and traces of production calls, and manage custom metrics, alerts, uptime monitors and dashboards.
Test and monitor voice and chat AI agents. Create agents and digital humans, run simulations against your agent, read transcripts, evaluations and traces of production calls, and manage custom metrics, alerts, uptime monitors and dashboards.
Bluejay tests and monitors conversational AI agents. An agent is the system under test; a digital human is one test case that calls it; a simulation runs a set of them; a community groups them for reuse.
Read the field descriptions on the digital human tools before authoring one. Behavior belongs in fields, not in `intent` prose, and each field's description says what it owns.
Before creating a batch, read an existing digital human in the same organization to pick up that team's conventions. Nothing rejects a well-formed config that does nothing, so an unmatched trigger and a discarded opener both return 200; in the run confirmation, offer to run one first as a check.
Do the work for the user; most are new to these concepts. Work out the agent or simulation from the conversation and use it. Create everything the task needs with sensible defaults, then say what you made ("Added 3 test cases to <simulation>"). Ask only for what you cannot find or infer. A digital human only runs inside a simulation, so every new one goes into a simulation when you create it (simulation_ids): the one the user named or is working in, else a new one for that agent. Set max_call_duration on every simulation you create (5 minutes unless the task needs longer). For red teaming, call start_red_team_simulation with the agent and confirmed=false, and relay its preview as the one question. If a step fails partway, remove what you just created for it and say so. When you build test cases, also create 2 or 3 pass/fail custom metrics (create_custom_metrics) for the rules that matter in the agent's prompt and tools, and attach them to the simulation. After a run, summarize failures by metric and offer to fix them with start_self_improve_run (confirmed=false first). Re-scoring is free: after a metric changes, re-run evaluate on the latest run without asking. Ask exactly once, at the end, before anything that places calls or spends credits (queue_*_run, red teaming, self-improve), changes the live
Discoverability
2/6 passed2 of 6 passed33/100
Client listings and public setup information.
mcp.json or server-card.json
Either mcp.json or an MCP Server Card declaring this endpoint passes.
The MCP Server Card declares this server's exact endpoint.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Create a new agent in Bluejay so it can be tested with simulations.
Stores the agent and saves system_prompt as its first prompt version (labeled production and
latest). Nothing is created on any voice platform. Each call creates another agent. Returns
the new agent_id (for get_agent, update_agent and the simulation tools), status, and
http_webhook_key when http_webhook was set.
Pass at most one connection field (phone_number, websocket_url, http_webhook,
dynamic_sip_webhook_url, eleven_labs_agent_id, retell_agent_id, sierra_agent_token,
email_address); phone_number may accompany retell_agent_id. connection_type is inferred from
it when omitted. This tool has no fields for VAPI, Bland, Google, Kore, OpenAI, LiveKit or
Pipecat connections; import Vapi assistants with sync_vapi_agents.
For AMELIA_CHAT / AMELIA_VOICE pass amelia_base_url and amelia_domain_code, plus
amelia_flow_name or amelia_agent_name if you want workflow sync; provider then defaults to AMELIA.
For an email agent pass mode="EMAIL", connection_type="EMAIL" and email_address, then run it
with queue_email_simulation_run. That inbox must allowlist Bluejay's sending domain
(bluejaysims.com), or corporate mail (Google Workspace, Microsoft 365) quarantines the test.
For an outbound email agent (your system emails the DH first) also pass agent_type="OUTBOUND"
and outbound_trigger_webhook_url; put {{digital_human.email}} in
outbound_trigger_payload_template to receive the per-test address to email.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Resolve the mismatch between this description and its schema constraints.
name
Display name for the new agent. If the org already has an agent with this name, Bluejay makes it unique.
Clear enough to supply this argument.
system_prompt
The agent's system prompt. Saved as its first prompt version, labeled production and latest (see list_prompt_versions).
Clear enough to supply this argument.
knowledge_base
Reference text for the agent. Must be non-empty, but the add-agent endpoint does not store it: attach knowledge bases to the agent separately.
Resolve the mismatch between this description and its schema constraints.
goals
What the agent should accomplish for callers, one goal per entry, e.g. "Book a cleaning appointment".
Clear enough to supply this argument.
phone_number
The agent's phone number in E.164 form, e.g. +14155550123. For a PHONE agent this number is its connection; with retell_agent_id it is the Retell agent's number.
Clear enough to supply this argument.
email_address
EMAIL agents: the agent's inbox that digital humans email during simulations, e.g. [email protected]. It must allowlist bluejaysims.com.
Clear enough to supply this argument.
email_reply_addresses
EMAIL connection: other addresses the customer agent may reply from. The digital human always writes to email_address; a reply from any listed address is accepted once it authenticates.
Clear enough to supply this argument.
agent_type
Who opens the conversation: INBOUND when the digital human calls or writes to the agent, OUTBOUND when the agent (or your system) contacts the digital human first. New agents default to INBOUND.
Clear enough to supply this argument.
connection_type
How Bluejay reaches the agent in simulations. When omitted it is inferred from the connection field you pass: eleven_labs_agent_id gives ELEVEN_LABS, retell_agent_id RETELL, vapi_assistant_id VAPI, kore_bot_id KORE, openai_base_url OPENAI_CHAT, openai_realtime_url OPENAI_REALTIME, ces_app_id GOOGLE_CES_VOICE, dfcx_agent_id GOOGLE_DFCX_VOICE, bland_pathway_id BLAND_VOICE with bland_agent_id or BLAND_PHONE without, amelia_base_url AMELIA_VOICE, email_address EMAIL, sierra_agent_token SIERRA_VOICE, dynamic_sip_webhook_url SIP, anything else PHONE. Pass it explicitly for any other type.
Clear enough to supply this argument.
mode
The channel the agent works in: VOICE for calls, TEXT for chat or SMS, EMAIL for email. New agents default to VOICE; an EMAIL connection always uses EMAIL.
Clear enough to supply this argument.
keyterms
Words speech-to-text should recognize reliably in this agent's voice simulations, such as product, brand or people names.
Clear enough to supply this argument.
follow_up_sms_sender_numbers
E.164 numbers authorized to send this agent's follow-up SMS, e.g. campaign numbers. A voice agent's own phone_number is added automatically when it can send SMS.
Clear enough to supply this argument.
external_agent_id
Your own system's id for this agent, unique within the workspace. GET /v1/agent-by-external-id/{external_id} and PUT /v1/update-agent-by-external-id find the agent by it.
Clear enough to supply this argument.
folder
Name of the folder to file the agent under; a folder with that name is created in the current workspace if none exists. To move an agent by folder id use move_agent_to_folder.
Clear enough to supply this argument.
http_webhook
HTTP_WEBHOOK text agents: the URL Bluejay sends each digital-human message to. The first time an agent gets one, a signing key is minted and returned as http_webhook_key.
Clear enough to supply this argument.
dynamic_sip_webhook_url
Per-call SIP endpoint webhook. When set (SIP connection), each call fetches its destination SIP URI from this URL at dial time.
Clear enough to supply this argument.
outbound_trigger_webhook_url
Customer-dialed simulations (type OUTBOUND): at dispatch Bluejay POSTs the filled-in outbound_trigger_payload_template here so your system calls or emails the digital human.
Clear enough to supply this argument.
outbound_trigger_payload_template
JSON body for the outbound trigger webhook. {{tokens}} are filled per test, e.g. {{digital_human.phone_number}} or {{digital_human.email}} for the address to contact.
Clear enough to supply this argument.
websocket_url
WEBSOCKET agents: the WebSocket URL Bluejay connects to for the real-time conversation.
Clear enough to supply this argument.
websocket_username
Username Bluejay authenticates to websocket_url with, if it requires credentials.
Clear enough to supply this argument.
websocket_password
Password for WebSocket authentication
Clear enough to supply this argument.
retell_agent_id
Retell agent_id (for RETELL connection type; the retell_key lives in the org's integrations row)
Clear enough to supply this argument.
eleven_labs_agent_id
ElevenLabs agent_id (from list_elevenlabs_agents) to test; makes this an ELEVEN_LABS agent and defaults provider to ELEVENLABS. Uses the org's ElevenLabs API key stored in integrations.
Clear enough to supply this argument.
amelia_base_url
Amelia deployment base URL including context root (e.g. https://tenant.amelia.com/Amelia)
Clear enough to supply this argument.
amelia_domain_code
Amelia domain code the conversation opens against (from /api/init -> domains[].code)
Clear enough to supply this argument.
amelia_flow_name
Which conversation flow in the Amelia domain this agent tracks (required for workflow sync)
Clear enough to supply this argument.
amelia_agent_name
Which cognitive agent in the Amelia domain this agent tracks (takes precedence over amelia_flow_name for workflow sync)
Clear enough to supply this argument.
sierra_agent_token
Sierra agent token: the URL path segment naming the agent in the Sierra Voice Protocol (for SIERRA_VOICE; the org's headless API token lives in the integrations row)
Clear enough to supply this argument.
sierra_release
Sierra release to pin the conversation to: a release target name (e.g. staging, production) or a release hash. Empty string clears the field.
Clear enough to supply this argument.
sierra_agent_parameters
Sierra agentParameters: a map of string key/value pairs the agent receives as request parameters at open (at most 512 entries)
Clear enough to supply this argument.
provider_request_data
Agent variables, e.g. {"account_number": "A-111"}. Every digital human of the agent inherits them at run time to fill {{name}} tokens; a digital human's trait or override of the same name wins. Bland also sends them as request_data. Pass {} to clear.
Clear enough to supply this argument.
provider
Platform the agent's prompt and workflow are authored on; sync_agent_workflow and push_agent_workflow use it to pick the adapter. Defaults to ELEVENLABS with eleven_labs_agent_id, AMELIA for an Amelia connection, otherwise CUSTOM.
Clear enough to supply this argument.
simulations_disabled
Set true to turn simulations off for this agent, false to turn them back on.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "\"200\" on create, \"success\" on delete."
},
"agent_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Bluejay id of the agent. After a create, use it with get_agent, update_agent and the simulation routes."
},
"http_webhook_key": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Signing key to verify Bluejay's webhook requests; only present when http_webhook was set."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "add_agent",
"title": "Add agent",
"description": "Create a new agent in Bluejay so it can be tested with simulations.\n\nStores the agent and saves system_prompt as its first prompt version (labeled production and\nlatest). Nothing is created on any voice platform. Each call creates another agent. Returns\nthe new agent_id (for get_agent, update_agent and the simulation tools), status, and\nhttp_webhook_key when http_webhook was set.\n\nPass at most one connection field (phone_number, websocket_url, http_webhook,\ndynamic_sip_webhook_url, eleven_labs_agent_id, retell_agent_id, sierra_agent_token,\nemail_address); phone_number may accompany retell_agent_id. connection_type is inferred from\nit when omitted. This tool has no fields for VAPI, Bland, Google, Kore, OpenAI, LiveKit or\nPipecat connections; import Vapi assistants with sync_vapi_agents.\n\nFor AMELIA_CHAT / AMELIA_VOICE pass amelia_base_url and amelia_domain_code, plus\namelia_flow_name or amelia_agent_name if you want workflow sync; provider then defaults to AMELIA.\n\nFor an email agent pass mode=\"EMAIL\", connection_type=\"EMAIL\" and email_address, then run it\nwith queue_email_simulation_run. That inbox must allowlist Bluejay's sending domain\n(bluejaysims.com), or corporate mail (Google Workspace, Microsoft 365) quarantines the test.\nFor an outbound email agent (your system emails the DH first) also pass agent_type=\"OUTBOUND\"\nand outbound_trigger_webhook_url; put {{digital_human.email}} in\noutbound_trigger_payload_template to receive the per-test address to email.",
"inputSchema": {
"type": "object",
"$defs": {
"Provider": {
"enum": [
"CUSTOM",
"ELEVENLABS",
"VAPI",
"RETELL",
"GOOGLE_CES_VOICE",
"GOOGLE_CES_CHAT",
"GOOGLE_DFCX_VOICE",
"GOOGLE_DFCX_CHAT",
"AMELIA",
"BLAND"
],
"type": "string",
"title": "Provider",
"description": "Source platform the agent's definition (system prompt, workflow) comes from.\n\nDistinct from `voice_provider` (TTS/STT vendor) and `provider_id` (handle on that vendor) —\nthis identifies where the agent's *behavior* (prompt, multi-agent graph) is authored."
},
"ConnectionType": {
"enum": [
"SMS",
"HTTP_WEBHOOK",
"PHONE",
"SIP",
"WEBSOCKET",
"LIVEKIT",
"PIPECAT",
"ELEVEN_LABS",
"RETELL",
"VAPI",
"KORE",
"OPENAI_CHAT",
"OPENAI_REALTIME",
"SIERRA_VOICE",
"AMELIA_CHAT",
"AMELIA_VOICE",
"GOOGLE_CES_CHAT",
"GOOGLE_CES_VOICE",
"GOOGLE_DFCX_VOICE",
"GOOGLE_DFCX_CHAT",
"BLAND_PHONE",
"BLAND_VOICE",
"BLAND_CHAT",
"EMAIL"
],
"type": "string",
"title": "ConnectionType",
"description": "Enum representing the connection type of the agent"
}
},
"title": "add_agentArguments",
"required": [
"name",
"system_prompt",
"knowledge_base",
"goals"
],
"properties": {
"mode": {
"anyOf": [
{
"enum": [
"VOICE",
"TEXT",
"EMAIL"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Mode",
"default": null,
"description": "The channel the agent works in: VOICE for calls, TEXT for chat or SMS, EMAIL for email. New agents default to VOICE; an EMAIL connection always uses EMAIL."
},
"name": {
"type": "string",
"title": "Name",
"description": "Display name for the new agent. If the org already has an agent with this name, Bluejay makes it unique."
},
"goals": {
"type": "array",
"items": {
"type": "string"
},
"title": "Goals",
"description": "What the agent should accomplish for callers, one goal per entry, e.g. \"Book a cleaning appointment\"."
},
"folder": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Folder",
"default": null,
"description": "Name of the folder to file the agent under; a folder with that name is created in the current workspace if none exists. To move an agent by folder id use move_agent_to_folder."
},
"keyterms": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Keyterms",
"default": null,
"description": "Words speech-to-text should recognize reliably in this agent's voice simulations, such as product, brand or people names."
},
"provider": {
"anyOf": [
{
"$ref": "#/$defs/Provider"
},
{
"type": "null"
}
],
"default": null,
"description": "Platform the agent's prompt and workflow are authored on; sync_agent_workflow and push_agent_workflow use it to pick the adapter. Defaults to ELEVENLABS with eleven_labs_agent_id, AMELIA for an Amelia connection, otherwise CUSTOM."
},
"agent_type": {
"anyOf": [
{
"enum": [
"INBOUND",
"OUTBOUND"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Agent Type",
"default": null,
"description": "Who opens the conversation: INBOUND when the digital human calls or writes to the agent, OUTBOUND when the agent (or your system) contacts the digital human first. New agents default to INBOUND."
},
"http_webhook": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Http Webhook",
"default": null,
"description": "HTTP_WEBHOOK text agents: the URL Bluejay sends each digital-human message to. The first time an agent gets one, a signing key is minted and returned as http_webhook_key."
},
"phone_number": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Phone Number",
"default": null,
"description": "The agent's phone number in E.164 form, e.g. +14155550123. For a PHONE agent this number is its connection; with retell_agent_id it is the Retell agent's number."
},
"email_address": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Email Address",
"default": null,
"description": "EMAIL agents: the agent's inbox that digital humans email during simulations, e.g. [email protected]. It must allowlist bluejaysims.com."
},
"system_prompt": {
"type": "string",
"title": "System Prompt",
"description": "The agent's system prompt. Saved as its first prompt version, labeled production and latest (see list_prompt_versions)."
},
"websocket_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Websocket Url",
"default": null,
"description": "WEBSOCKET agents: the WebSocket URL Bluejay connects to for the real-time conversation."
},
"knowledge_base": {
"type": "string",
"title": "Knowledge Base",
"description": "Reference text for the agent. Must be non-empty, but the add-agent endpoint does not store it: attach knowledge bases to the agent separately."
},
"sierra_release": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Sierra Release",
"default": null,
"description": "Sierra release to pin the conversation to: a release target name (e.g. staging, production) or a release hash. Empty string clears the field."
},
"amelia_base_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Amelia Base Url",
"default": null,
"description": "Amelia deployment base URL including context root (e.g. https://tenant.amelia.com/Amelia)"
},
"connection_type": {
"anyOf": [
{
"$ref": "#/$defs/ConnectionType"
},
{
"type": "null"
}
],
"default": null,
"description": "How Bluejay reaches the agent in simulations. When omitted it is inferred from the connection field you pass: eleven_labs_agent_id gives ELEVEN_LABS, retell_agent_id RETELL, vapi_assistant_id VAPI, kore_bot_id KORE, openai_base_url OPENAI_CHAT, openai_realtime_url OPENAI_REALTIME, ces_app_id GOOGLE_CES_VOICE, dfcx_agent_id GOOGLE_DFCX_VOICE, bland_pathway_id BLAND_VOICE with bland_agent_id or BLAND_PHONE without, amelia_base_url AMELIA_VOICE, email_address EMAIL, sierra_agent_token SIERRA_VOICE, dynamic_sip_webhook_url SIP, anything else PHONE. Pass it explicitly for any other type."
},
"retell_agent_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Retell Agent Id",
"default": null,
"description": "Retell agent_id (for RETELL connection type; the retell_key lives in the org's integrations row)"
},
"amelia_flow_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Amelia Flow Name",
"default": null,
"description": "Which conversation flow in the Amelia domain this agent tracks (required for workflow sync)"
},
"amelia_agent_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Amelia Agent Name",
"default": null,
"description": "Which cognitive agent in the Amelia domain this agent tracks (takes precedence over amelia_flow_name for workflow sync)"
},
"external_agent_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "External Agent Id",
"default": null,
"description": "Your own system's id for this agent, unique within the workspace. GET /v1/agent-by-external-id/{external_id} and PUT /v1/update-agent-by-external-id find the agent by it."
},
"amelia_domain_code": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Amelia Domain Code",
"default": null,
"description": "Amelia domain code the conversation opens against (from /api/init -> domains[].code)"
},
"sierra_agent_token": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Sierra Agent Token",
"default": null,
"description": "Sierra agent token: the URL path segment naming the agent in the Sierra Voice Protocol (for SIERRA_VOICE; the org's headless API token lives in the integrations row)"
},
"websocket_password": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Websocket Password",
"default": null,
"description": "Password for WebSocket authentication"
},
"websocket_username": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Websocket Username",
"default": null,
"description": "Username Bluejay authenticates to websocket_url with, if it requires credentials."
},
"eleven_labs_agent_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Eleven Labs Agent Id",
"default": null,
"description": "ElevenLabs agent_id (from list_elevenlabs_agents) to test; makes this an ELEVEN_LABS agent and defaults provider to ELEVENLABS. Uses the org's ElevenLabs API key stored in integrations."
},
"simulations_disabled": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Simulations Disabled",
"default": null,
"description": "Set true to turn simulations off for this agent, false to turn them back on."
},
"email_reply_addresses": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Email Reply Addresses",
"default": null,
"description": "EMAIL connection: other addresses the customer agent may reply from. The digital human always writes to email_address; a reply from any listed address is accepted once it authenticates."
},
"provider_request_data": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Provider Request Data",
"default": null,
"description": "Agent variables, e.g. {\"account_number\": \"A-111\"}. Every digital human of the agent inherits them at run time to fill {{name}} tokens; a digital human's trait or override of the same name wins. Bland also sends them as request_data. Pass {} to clear."
},
"dynamic_sip_webhook_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Dynamic Sip Webhook Url",
"default": null,
"description": "Per-call SIP endpoint webhook. When set (SIP connection), each call fetches its destination SIP URI from this URL at dial time."
},
"sierra_agent_parameters": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Sierra Agent Parameters",
"default": null,
"description": "Sierra agentParameters: a map of string key/value pairs the agent receives as request parameters at open (at most 512 entries)"
},
"follow_up_sms_sender_numbers": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Follow Up Sms Sender Numbers",
"default": null,
"description": "E.164 numbers authorized to send this agent's follow-up SMS, e.g. campaign numbers. A voice agent's own phone_number is added automatically when it can send SMS."
},
"outbound_trigger_webhook_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Outbound Trigger Webhook Url",
"default": null,
"description": "Customer-dialed simulations (type OUTBOUND): at dispatch Bluejay POSTs the filled-in outbound_trigger_payload_template here so your system calls or emails the digital human."
},
"outbound_trigger_payload_template": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Outbound Trigger Payload Template",
"default": null,
"description": "JSON body for the outbound trigger webhook. {{tokens}} are filled per test, e.g. {{digital_human.phone_number}} or {{digital_human.email}} for the address to contact."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "\"200\" on create, \"success\" on delete."
},
"agent_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Bluejay id of the agent. After a create, use it with get_agent, update_agent and the simulation routes."
},
"http_webhook_key": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Signing key to verify Bluejay's webhook requests; only present when http_webhook was set."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Change an existing agent's settings in Bluejay.
Only the fields you pass change; omitted fields keep their current values. Writes Bluejay's
agent record only, never the agent on its voice platform. Returns status, plus the written
fields as agent when id_type is external.
system_prompt saves a new prompt version and moves the agent's "latest" label to it, unless it
matches the "latest" prompt; it does not rewrite the agent row. Agent reads return the
"latest" version's prompt, so get_agent shows the new text right away. Earlier versions stay
in list_prompt_versions.
provider can be set to correct an agent's source label, e.g. re-stamping an ElevenLabs agent
that was saved as CUSTOM. Switching connection_type to AMELIA_CHAT / AMELIA_VOICE does not
restamp provider, so pass provider=AMELIA too if the workflow tools should see it as Amelia.
agent_id is whichever id you have and id_type says which one it is: "bluejay" for the numeric
id this API returns, "external" for the id from your own system stored on the agent as
external_agent_id. The external route writes a smaller field set: it cannot change
external_agent_id, the websocket credentials or eleven_labs_agent_id, and rejects the call
rather than dropping them.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
agent_id
The agent to update: its Bluejay id (from list_agents), or your own system's id when id_type is external.
Clear enough to supply this argument.
id_type
Which id agent_id is: bluejay for Bluejay's id, external for the external_agent_id stored on the agent.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
New display name for the agent.
Clear enough to supply this argument.
system_prompt
New system prompt. Saved as a new prompt version labeled latest, unless it matches the current latest prompt.
Clear enough to supply this argument.
knowledge_base
Accepted but not stored by the update endpoints, so it changes nothing; knowledge bases are attached to the agent separately.
Clear enough to supply this argument.
goals
Replacement list of what the agent should accomplish for callers, one goal per entry.
Clear enough to supply this argument.
phone_number
The agent's phone number in E.164 form, e.g. +14155550123. For a PHONE agent this number is its connection; with retell_agent_id it is the Retell agent's number.
Clear enough to supply this argument.
email_address
EMAIL agents: the agent's inbox that digital humans email during simulations, e.g. [email protected]. It must allowlist bluejaysims.com.
Clear enough to supply this argument.
email_reply_addresses
EMAIL connection: other addresses the customer agent may reply from. The digital human always writes to email_address; a reply from any listed address is accepted once it authenticates.
Clear enough to supply this argument.
agent_type
Who opens the conversation: INBOUND when the digital human calls or writes to the agent, OUTBOUND when the agent (or your system) contacts the digital human first. New agents default to INBOUND.
Clear enough to supply this argument.
connection_type
How Bluejay reaches the agent in simulations.
Explain the meaning of this value, not just its name.
mode
The channel the agent works in: VOICE for calls, TEXT for chat or SMS, EMAIL for email. New agents default to VOICE; an EMAIL connection always uses EMAIL.
Clear enough to supply this argument.
keyterms
Words speech-to-text should recognize reliably in this agent's voice simulations, such as product, brand or people names.
Clear enough to supply this argument.
follow_up_sms_sender_numbers
E.164 numbers authorized to send this agent's follow-up SMS, e.g. campaign numbers. A voice agent's own phone_number is added automatically when it can send SMS.
Clear enough to supply this argument.
external_agent_id
Your own system's id for this agent, unique within the workspace. GET /v1/agent-by-external-id/{external_id} and PUT /v1/update-agent-by-external-id find the agent by it.
Clear enough to supply this argument.
folder
Name of the folder to file the agent under; a folder with that name is created in the current workspace if none exists. To move an agent by folder id use move_agent_to_folder.
Clear enough to supply this argument.
http_webhook
HTTP_WEBHOOK text agents: the URL Bluejay sends each digital-human message to. The first time an agent gets one, a signing key is minted and returned as http_webhook_key.
Clear enough to supply this argument.
dynamic_sip_webhook_url
Per-call SIP endpoint webhook. When set (SIP connection), each call fetches its destination SIP URI from this URL at dial time.
Clear enough to supply this argument.
outbound_trigger_webhook_url
Customer-dialed simulations (type OUTBOUND): at dispatch Bluejay POSTs the filled-in outbound_trigger_payload_template here so your system calls or emails the digital human.
Clear enough to supply this argument.
outbound_trigger_payload_template
JSON body for the outbound trigger webhook. {{tokens}} are filled per test, e.g. {{digital_human.phone_number}} or {{digital_human.email}} for the address to contact.
Clear enough to supply this argument.
websocket_url
WEBSOCKET agents: the WebSocket URL Bluejay connects to for the real-time conversation.
Clear enough to supply this argument.
websocket_username
Username Bluejay authenticates to websocket_url with, if it requires credentials.
Clear enough to supply this argument.
websocket_password
Password for WebSocket authentication
Clear enough to supply this argument.
retell_agent_id
Retell agent_id (for RETELL connection type; the retell_key lives in the org's integrations row)
Clear enough to supply this argument.
eleven_labs_agent_id
ElevenLabs agent_id (from list_elevenlabs_agents) to test. Uses the org's ElevenLabs API key stored in integrations.
Clear enough to supply this argument.
amelia_base_url
Amelia deployment base URL including context root (e.g. https://tenant.amelia.com/Amelia)
Clear enough to supply this argument.
amelia_domain_code
Amelia domain code the conversation opens against (from /api/init -> domains[].code)
Clear enough to supply this argument.
amelia_flow_name
Which conversation flow in the Amelia domain this agent tracks (required for workflow sync)
Clear enough to supply this argument.
amelia_agent_name
Which cognitive agent in the Amelia domain this agent tracks (takes precedence over amelia_flow_name for workflow sync)
Clear enough to supply this argument.
sierra_agent_token
Sierra agent token: the URL path segment naming the agent in the Sierra Voice Protocol (for SIERRA_VOICE; the org's headless API token lives in the integrations row)
Clear enough to supply this argument.
sierra_release
Sierra release to pin the conversation to: a release target name (e.g. staging, production) or a release hash. Empty string clears the field.
Clear enough to supply this argument.
sierra_agent_parameters
Sierra agentParameters: a map of string key/value pairs the agent receives as request parameters at open (at most 512 entries)
Clear enough to supply this argument.
provider_request_data
Agent variables, e.g. {"account_number": "A-111"}. Every digital human of the agent inherits them at run time to fill {{name}} tokens; a digital human's trait or override of the same name wins. Bland also sends them as request_data. Pass {} to clear.
Clear enough to supply this argument.
provider
Platform the agent's prompt and workflow are authored on; sync_agent_workflow and push_agent_workflow use it to pick the adapter. Set it to correct an agent's source label, e.g. an ElevenLabs agent saved as CUSTOM.
Clear enough to supply this argument.
simulations_disabled
Set true to turn simulations off for this agent, false to turn them back on.
{
"type": "object",
"properties": {
"agent": {
"type": [
"object",
"array",
"null"
],
"description": "With id_type external only: the agent fields the update wrote."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "\"200\" when the update was saved."
},
"agent_id": {
"type": [
"integer",
"string",
"number",
"null"
],
"description": "Not echoed by the update endpoints, so null; the agent named by the agent_id you passed is the one updated."
},
"http_webhook_key": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "With id_type external only: the agent's HTTP webhook signing key, when it has one."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "update_agent",
"title": "Update agent",
"description": "Change an existing agent's settings in Bluejay.\n\nOnly the fields you pass change; omitted fields keep their current values. Writes Bluejay's\nagent record only, never the agent on its voice platform. Returns status, plus the written\nfields as agent when id_type is external.\n\nsystem_prompt saves a new prompt version and moves the agent's \"latest\" label to it, unless it\nmatches the \"latest\" prompt; it does not rewrite the agent row. Agent reads return the\n\"latest\" version's prompt, so get_agent shows the new text right away. Earlier versions stay\nin list_prompt_versions.\n\nprovider can be set to correct an agent's source label, e.g. re-stamping an ElevenLabs agent\nthat was saved as CUSTOM. Switching connection_type to AMELIA_CHAT / AMELIA_VOICE does not\nrestamp provider, so pass provider=AMELIA too if the workflow tools should see it as Amelia.\n\nagent_id is whichever id you have and id_type says which one it is: \"bluejay\" for the numeric\nid this API returns, \"external\" for the id from your own system stored on the agent as\nexternal_agent_id. The external route writes a smaller field set: it cannot change\nexternal_agent_id, the websocket credentials or eleven_labs_agent_id, and rejects the call\nrather than dropping them.",
"inputSchema": {
"type": "object",
"$defs": {
"Provider": {
"enum": [
"CUSTOM",
"ELEVENLABS",
"VAPI",
"RETELL",
"GOOGLE_CES_VOICE",
"GOOGLE_CES_CHAT",
"GOOGLE_DFCX_VOICE",
"GOOGLE_DFCX_CHAT",
"AMELIA",
"BLAND"
],
"type": "string",
"title": "Provider",
"description": "Source platform the agent's definition (system prompt, workflow) comes from.\n\nDistinct from `voice_provider` (TTS/STT vendor) and `provider_id` (handle on that vendor) —\nthis identifies where the agent's *behavior* (prompt, multi-agent graph) is authored."
},
"ConnectionType": {
"enum": [
"SMS",
"HTTP_WEBHOOK",
"PHONE",
"SIP",
"WEBSOCKET",
"LIVEKIT",
"PIPECAT",
"ELEVEN_LABS",
"RETELL",
"VAPI",
"KORE",
"OPENAI_CHAT",
"OPENAI_REALTIME",
"SIERRA_VOICE",
"AMELIA_CHAT",
"AMELIA_VOICE",
"GOOGLE_CES_CHAT",
"GOOGLE_CES_VOICE",
"GOOGLE_DFCX_VOICE",
"GOOGLE_DFCX_CHAT",
"BLAND_PHONE",
"BLAND_VOICE",
"BLAND_CHAT",
"EMAIL"
],
"type": "string",
"title": "ConnectionType",
"description": "Enum representing the connection type of the agent"
}
},
"title": "update_agentArguments",
"required": [
"agent_id"
],
"properties": {
"mode": {
"anyOf": [
{
"enum": [
"VOICE",
"TEXT",
"EMAIL"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Mode",
"default": null,
"description": "The channel the agent works in: VOICE for calls, TEXT for chat or SMS, EMAIL for email. New agents default to VOICE; an EMAIL connection always uses EMAIL."
},
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Name",
"default": null,
"description": "New display name for the agent."
},
"goals": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Goals",
"default": null,
"description": "Replacement list of what the agent should accomplish for callers, one goal per entry."
},
"folder": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Folder",
"default": null,
"description": "Name of the folder to file the agent under; a folder with that name is created in the current workspace if none exists. To move an agent by folder id use move_agent_to_folder."
},
"id_type": {
"enum": [
"bluejay",
"external"
],
"type": "string",
"title": "Id Type",
"default": "bluejay",
"description": "Which id agent_id is: bluejay for Bluejay's id, external for the external_agent_id stored on the agent."
},
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "The agent to update: its Bluejay id (from list_agents), or your own system's id when id_type is external."
},
"keyterms": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Keyterms",
"default": null,
"description": "Words speech-to-text should recognize reliably in this agent's voice simulations, such as product, brand or people names."
},
"provider": {
"anyOf": [
{
"$ref": "#/$defs/Provider"
},
{
"type": "null"
}
],
"default": null,
"description": "Platform the agent's prompt and workflow are authored on; sync_agent_workflow and push_agent_workflow use it to pick the adapter. Set it to correct an agent's source label, e.g. an ElevenLabs agent saved as CUSTOM."
},
"agent_type": {
"anyOf": [
{
"enum": [
"INBOUND",
"OUTBOUND"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Agent Type",
"default": null,
"description": "Who opens the conversation: INBOUND when the digital human calls or writes to the agent, OUTBOUND when the agent (or your system) contacts the digital human first. New agents default to INBOUND."
},
"http_webhook": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Http Webhook",
"default": null,
"description": "HTTP_WEBHOOK text agents: the URL Bluejay sends each digital-human message to. The first time an agent gets one, a signing key is minted and returned as http_webhook_key."
},
"phone_number": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Phone Number",
"default": null,
"description": "The agent's phone number in E.164 form, e.g. +14155550123. For a PHONE agent this number is its connection; with retell_agent_id it is the Retell agent's number."
},
"email_address": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Email Address",
"default": null,
"description": "EMAIL agents: the agent's inbox that digital humans email during simulations, e.g. [email protected]. It must allowlist bluejaysims.com."
},
"system_prompt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "System Prompt",
"default": null,
"description": "New system prompt. Saved as a new prompt version labeled latest, unless it matches the current latest prompt."
},
"websocket_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Websocket Url",
"default": null,
"description": "WEBSOCKET agents: the WebSocket URL Bluejay connects to for the real-time conversation."
},
"knowledge_base": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Knowledge Base",
"default": null,
"description": "Accepted but not stored by the update endpoints, so it changes nothing; knowledge bases are attached to the agent separately."
},
"sierra_release": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Sierra Release",
"default": null,
"description": "Sierra release to pin the conversation to: a release target name (e.g. staging, production) or a release hash. Empty string clears the field."
},
"amelia_base_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Amelia Base Url",
"default": null,
"description": "Amelia deployment base URL including context root (e.g. https://tenant.amelia.com/Amelia)"
},
"connection_type": {
"anyOf": [
{
"$ref": "#/$defs/ConnectionType"
},
{
"type": "null"
}
],
"default": null,
"description": "How Bluejay reaches the agent in simulations."
},
"retell_agent_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Retell Agent Id",
"default": null,
"description": "Retell agent_id (for RETELL connection type; the retell_key lives in the org's integrations row)"
},
"amelia_flow_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Amelia Flow Name",
"default": null,
"description": "Which conversation flow in the Amelia domain this agent tracks (required for workflow sync)"
},
"amelia_agent_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Amelia Agent Name",
"default": null,
"description": "Which cognitive agent in the Amelia domain this agent tracks (takes precedence over amelia_flow_name for workflow sync)"
},
"external_agent_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "External Agent Id",
"default": null,
"description": "Your own system's id for this agent, unique within the workspace. GET /v1/agent-by-external-id/{external_id} and PUT /v1/update-agent-by-external-id find the agent by it."
},
"amelia_domain_code": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Amelia Domain Code",
"default": null,
"description": "Amelia domain code the conversation opens against (from /api/init -> domains[].code)"
},
"sierra_agent_token": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Sierra Agent Token",
"default": null,
"description": "Sierra agent token: the URL path segment naming the agent in the Sierra Voice Protocol (for SIERRA_VOICE; the org's headless API token lives in the integrations row)"
},
"websocket_password": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Websocket Password",
"default": null,
"description": "Password for WebSocket authentication"
},
"websocket_username": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Websocket Username",
"default": null,
"description": "Username Bluejay authenticates to websocket_url with, if it requires credentials."
},
"eleven_labs_agent_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Eleven Labs Agent Id",
"default": null,
"description": "ElevenLabs agent_id (from list_elevenlabs_agents) to test. Uses the org's ElevenLabs API key stored in integrations."
},
"simulations_disabled": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Simulations Disabled",
"default": null,
"description": "Set true to turn simulations off for this agent, false to turn them back on."
},
"email_reply_addresses": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Email Reply Addresses",
"default": null,
"description": "EMAIL connection: other addresses the customer agent may reply from. The digital human always writes to email_address; a reply from any listed address is accepted once it authenticates."
},
"provider_request_data": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Provider Request Data",
"default": null,
"description": "Agent variables, e.g. {\"account_number\": \"A-111\"}. Every digital human of the agent inherits them at run time to fill {{name}} tokens; a digital human's trait or override of the same name wins. Bland also sends them as request_data. Pass {} to clear."
},
"dynamic_sip_webhook_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Dynamic Sip Webhook Url",
"default": null,
"description": "Per-call SIP endpoint webhook. When set (SIP connection), each call fetches its destination SIP URI from this URL at dial time."
},
"sierra_agent_parameters": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Sierra Agent Parameters",
"default": null,
"description": "Sierra agentParameters: a map of string key/value pairs the agent receives as request parameters at open (at most 512 entries)"
},
"follow_up_sms_sender_numbers": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Follow Up Sms Sender Numbers",
"default": null,
"description": "E.164 numbers authorized to send this agent's follow-up SMS, e.g. campaign numbers. A voice agent's own phone_number is added automatically when it can send SMS."
},
"outbound_trigger_webhook_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Outbound Trigger Webhook Url",
"default": null,
"description": "Customer-dialed simulations (type OUTBOUND): at dispatch Bluejay POSTs the filled-in outbound_trigger_payload_template here so your system calls or emails the digital human."
},
"outbound_trigger_payload_template": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Outbound Trigger Payload Template",
"default": null,
"description": "JSON body for the outbound trigger webhook. {{tokens}} are filled per test, e.g. {{digital_human.phone_number}} or {{digital_human.email}} for the address to contact."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"agent": {
"type": [
"object",
"array",
"null"
],
"description": "With id_type external only: the agent fields the update wrote."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "\"200\" when the update was saved."
},
"agent_id": {
"type": [
"integer",
"string",
"number",
"null"
],
"description": "Not echoed by the update endpoints, so null; the agent named by the agent_id you passed is the one updated."
},
"http_webhook_key": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "With id_type external only: the agent's HTTP webhook signing key, when it has one."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description80/100
Retrieve a single agent via Bluejay GET /v1/agents/{agent_id}.
`agent_id` is whichever id you have; `id_type` says which one it is —
"bluejay" for the numeric id this API returns and list_agents reports,
"external" for the id from your own system that was stored on the agent as
external_agent_id.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
agent_id
The agent to fetch: its Bluejay id (from list_agents), or your own system's id when id_type is external.
Clear enough to supply this argument.
id_type
Which id agent_id is: bluejay for Bluejay's id, external for the external_agent_id stored on the agent.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
List the agents in the org, read-only, to find an agent's id or count agents.
Returns {id, name} for every agent in the org. `folder_id` narrows the listing
to one folder (from list_folders) and returns the full agent rows for it.
`total_count` is the number of agents returned; use it for "how many" instead of counting.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
folder_id
Folder to list, by its id from list_folders. Omit to list every agent in the org.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"agents": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"integer",
"string",
"number",
"null"
],
"description": "Bluejay agent id."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Agent display name."
}
},
"description": "One agent.",
"additionalProperties": true
},
"description": "The agents: {id, name} for each agent in the org, or the folder's full agent rows when folder_id is set. Pass an id to get_agent for the full configuration."
},
"total_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Number of agents returned; use it to answer \"how many\"."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "list_agents",
"title": "List agents",
"description": "List the agents in the org, read-only, to find an agent's id or count agents.\n\nReturns {id, name} for every agent in the org. `folder_id` narrows the listing\nto one folder (from list_folders) and returns the full agent rows for it.\n`total_count` is the number of agents returned; use it for \"how many\" instead of counting.\n",
"inputSchema": {
"type": "object",
"title": "list_agentsArguments",
"properties": {
"folder_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Folder Id",
"default": null,
"description": "Folder to list, by its id from list_folders. Omit to list every agent in the org."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"agents": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"integer",
"string",
"number",
"null"
],
"description": "Bluejay agent id."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Agent display name."
}
},
"description": "One agent.",
"additionalProperties": true
},
"description": "The agents: {id, name} for each agent in the org, or the folder's full agent rows when folder_id is set. Pass an id to get_agent for the full configuration."
},
"total_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Number of agents returned; use it to answer \"how many\"."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Delete an agent: move it to Recently Deleted, where it can be restored for 30 days before it
is purged permanently.
The delete also disables the agent's scheduled simulation runs, pauses its uptime monitors and
deactivates its always-on digital humans, tearing down their SIP trunks. Confirm with the user
before calling.
confirm: pass true only after the user agrees to stop an always-on number or a
simulation that is still running. Without it those deletes return HTTP 409.
Returns deleted and the agent_id.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Bluejay id of the agent to delete, from list_agents.
Clear enough to supply this argument.
confirm
Set true only once the requester agrees to stop the agent's always-on numbers or its still-running simulations; without it such a delete fails with HTTP 409 and changes nothing.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the agent was moved to Recently Deleted."
},
"agent_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The id of the deleted agent, as passed."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "delete_agent",
"title": "Delete agent",
"description": "Delete an agent: move it to Recently Deleted, where it can be restored for 30 days before it\nis purged permanently.\n\nThe delete also disables the agent's scheduled simulation runs, pauses its uptime monitors and\ndeactivates its always-on digital humans, tearing down their SIP trunks. Confirm with the user\nbefore calling.\n\nconfirm: pass true only after the user agrees to stop an always-on number or a\nsimulation that is still running. Without it those deletes return HTTP 409.\nReturns deleted and the agent_id.\n",
"inputSchema": {
"type": "object",
"title": "delete_agentArguments",
"required": [
"agent_id"
],
"properties": {
"confirm": {
"type": "boolean",
"title": "Confirm",
"default": false,
"description": "Set true only once the requester agrees to stop the agent's always-on numbers or its still-running simulations; without it such a delete fails with HTTP 409 and changes nothing."
},
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "Bluejay id of the agent to delete, from list_agents."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the agent was moved to Recently Deleted."
},
"agent_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The id of the deleted agent, as passed."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Create a simulation: a reusable test suite that runs digital humans against one agent (POST /v1/create-simulation).
Saves a new simulation for agent_id with its call limits, digital-human defaults and metric
selection. Nothing is dialed or billed until queue_simulation_run. Unset fields take Bluejay's
defaults (see each field). The new simulation has no digital humans yet: attach them with
create_digital_humans or bulk_set_digital_human_simulations before running it.
Returns simulation_id, which get_simulation, update_simulation and queue_simulation_run take,
and status.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent this simulation tests: its Bluejay id from list_agents or add_agent. It cannot be changed later.
Clear enough to supply this argument.
name
Display name. Omitted, it becomes "<agent name> Simulation <date-time>".
Clear enough to supply this argument.
description
Free-text note on what this simulation tests.
Clear enough to supply this argument.
prompt_id
Default agent version the runs test: a version uuid from list_prompt_versions for this agent. queue_simulation_run can override it per run.
Clear enough to supply this argument.
knowledge_base_id
Default Bluejay knowledge base uuid for this simulation's runs; queue_simulation_run can override it per run.
Clear enough to supply this argument.
max_concurrent
How many conversations may run at the same time, at most 500. Omitted, 150; a value above the org's concurrency ceiling is lowered to it.
Clear enough to supply this argument.
hangup_on_transfer
When true, the digital human hangs up as soon as the agent transfers the call, unless the agent said one of hangup_on_transfer_bypass_phrases. Omitted, false.
Clear enough to supply this argument.
hangup_on_transfer_bypass_phrases
Agent phrases that let a transfer go through while hangup_on_transfer is on, e.g. ["transferring you to billing"]. Blank entries are dropped.
Clear enough to supply this argument.
max_call_duration
Longest a single conversation may last, counted in max_call_duration_units. Omitted, the org's default call length, else 10 minutes.
Clear enough to supply this argument.
max_call_duration_units
Unit of max_call_duration; minutes when omitted. The duration is stored converted to seconds.
Clear enough to supply this argument.
ringing_timeout
Seconds to let a SIP call ring before giving up on it. Omitted, 300.
Clear enough to supply this argument.
digital_humans_settings
Defaults for this simulation's digital humans: default_name, default_caller_number and default_language ("random" picks one per call), default_background_noise ("none" for silence) and first_message ("ai_generated" lets the digital human write its opener). Keys left out take those values.
Clear enough to supply this argument.
selected_custom_metrics
Custom metric ids (from list_custom_metrics) to score this simulation's conversations with. Omitted, every metric attached to the agent; [] scores none.
Clear enough to supply this argument.
custom_metrics_failing_threshold
Score out of 100 below which a custom metric result counts as failing.
Clear enough to supply this argument.
custom_metrics_passing_threshold
Score out of 100 at or above which a custom metric result counts as passing.
Clear enough to supply this argument.
runs_per_digital_human
Conversations each digital human has per run; 1 when omitted. queue_simulation_run can override it per run.
Clear enough to supply this argument.
delay_between_tests_seconds
Seconds to wait after one conversation finishes before the next starts, up to 300; 0 turns the pause off.
Clear enough to supply this argument.
inactivity_timeout_seconds
Text and email agents: seconds to wait for the agent's reply before ending the conversation, 300 to 1800. Omitted, 300.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Status code for the request, \"200\" on success."
},
"simulation_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Id of the new simulation; pass it to get_simulation, update_simulation and queue_simulation_run."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_simulation",
"title": "Create simulation",
"description": "Create a simulation: a reusable test suite that runs digital humans against one agent (POST /v1/create-simulation).\n\nSaves a new simulation for agent_id with its call limits, digital-human defaults and metric\nselection. Nothing is dialed or billed until queue_simulation_run. Unset fields take Bluejay's\ndefaults (see each field). The new simulation has no digital humans yet: attach them with\ncreate_digital_humans or bulk_set_digital_human_simulations before running it.\n\nReturns simulation_id, which get_simulation, update_simulation and queue_simulation_run take,\nand status.\n",
"inputSchema": {
"type": "object",
"title": "create_simulationArguments",
"required": [
"agent_id"
],
"properties": {
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Name",
"default": null,
"description": "Display name. Omitted, it becomes \"<agent name> Simulation <date-time>\"."
},
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "The agent this simulation tests: its Bluejay id from list_agents or add_agent. It cannot be changed later."
},
"prompt_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Prompt Id",
"default": null,
"description": "Default agent version the runs test: a version uuid from list_prompt_versions for this agent. queue_simulation_run can override it per run."
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description",
"default": null,
"description": "Free-text note on what this simulation tests."
},
"max_concurrent": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Max Concurrent",
"default": null,
"description": "How many conversations may run at the same time, at most 500. Omitted, 150; a value above the org's concurrency ceiling is lowered to it."
},
"ringing_timeout": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Ringing Timeout",
"default": null,
"description": "Seconds to let a SIP call ring before giving up on it. Omitted, 300."
},
"knowledge_base_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Knowledge Base Id",
"default": null,
"description": "Default Bluejay knowledge base uuid for this simulation's runs; queue_simulation_run can override it per run."
},
"max_call_duration": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Max Call Duration",
"default": null,
"description": "Longest a single conversation may last, counted in max_call_duration_units. Omitted, the org's default call length, else 10 minutes."
},
"hangup_on_transfer": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Hangup On Transfer",
"default": null,
"description": "When true, the digital human hangs up as soon as the agent transfers the call, unless the agent said one of hangup_on_transfer_bypass_phrases. Omitted, false."
},
"runs_per_digital_human": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Runs Per Digital Human",
"default": null,
"description": "Conversations each digital human has per run; 1 when omitted. queue_simulation_run can override it per run."
},
"digital_humans_settings": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Digital Humans Settings",
"default": null,
"description": "Defaults for this simulation's digital humans: default_name, default_caller_number and default_language (\"random\" picks one per call), default_background_noise (\"none\" for silence) and first_message (\"ai_generated\" lets the digital human write its opener). Keys left out take those values."
},
"max_call_duration_units": {
"anyOf": [
{
"enum": [
"minutes",
"seconds"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Max Call Duration Units",
"default": null,
"description": "Unit of max_call_duration; minutes when omitted. The duration is stored converted to seconds."
},
"selected_custom_metrics": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Selected Custom Metrics",
"default": null,
"description": "Custom metric ids (from list_custom_metrics) to score this simulation's conversations with. Omitted, every metric attached to the agent; [] scores none."
},
"inactivity_timeout_seconds": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Inactivity Timeout Seconds",
"default": null,
"description": "Text and email agents: seconds to wait for the agent's reply before ending the conversation, 300 to 1800. Omitted, 300."
},
"delay_between_tests_seconds": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "Delay Between Tests Seconds",
"default": null,
"description": "Seconds to wait after one conversation finishes before the next starts, up to 300; 0 turns the pause off."
},
"custom_metrics_failing_threshold": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Custom Metrics Failing Threshold",
"default": null,
"description": "Score out of 100 below which a custom metric result counts as failing."
},
"custom_metrics_passing_threshold": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Custom Metrics Passing Threshold",
"default": null,
"description": "Score out of 100 at or above which a custom metric result counts as passing."
},
"hangup_on_transfer_bypass_phrases": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Hangup On Transfer Bypass Phrases",
"default": null,
"description": "Agent phrases that let a transfer go through while hangup_on_transfer is on, e.g. [\"transferring you to billing\"]. Blank entries are dropped."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Status code for the request, \"200\" on success."
},
"simulation_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Id of the new simulation; pass it to get_simulation, update_simulation and queue_simulation_run."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Fetch one simulation's full configuration (GET /v1/simulation/{simulation_id}). Read-only.
Returns the stored simulation's fields at the top level: id, name, description, agent_id,
max_concurrent, max_turns, ringing_timeout, inactivity_timeout_seconds, tags, pinned,
always_on, timestamps, and settings (max_call_duration in seconds, hangup_on_transfer,
digital-human defaults, selected_custom_metrics and thresholds, default prompt_id and
knowledge_base_id, runs_per_digital_human, rerun flags). `data` repeats the same body.
It does not include the simulation's digital humans (list_digital_humans with simulation_id)
or its runs (get_simulation_runs).
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
simulation_id
The simulation to read: its id from list_simulations or create_simulation.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
List the org's simulations (GET /v1/get-all-simulations). Read-only.
Returns {id, name, created_at} for up to 100 simulations in the org, newest first.
`agent_id` narrows the listing to the simulations that run against that one agent
(GET /v1/get-simulations-by-agent/{agent_id}) and returns the full simulation rows for it.
An org or agent with no simulations comes back as an error ("No simulations found"), not an
empty list. Use get_simulation for one simulation's full settings.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
A Bluejay agent id (from list_agents) to list only that agent's simulations, with full rows. Omit to list the whole org's.
Shorten the title to an action and subject; move usage details into the description.
Description100/100
Move a simulation to Recently Deleted (DELETE /v1/simulation/{simulation_id}).
The simulation leaves every list and can no longer be run or scheduled: its schedules are
disabled, and its always-on digital humans are switched off with their SIP trunks torn down.
Its runs and results are kept, and it can be restored from Recently Deleted for 30 days;
after that it is purged permanently with its runs. The digital humans themselves are not
deleted. Ask the user to confirm before calling.
Returns deleted, simulation_id, deleted_simulation_id and message.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
simulation_id
The simulation to delete: its id from list_simulations or get_simulation.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True once the simulation is in Recently Deleted."
},
"message": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Confirmation message, \"success\"."
},
"simulation_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The simulation id that was deleted, as passed in."
},
"deleted_simulation_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The deleted simulation's id."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "delete_simulation",
"title": "Delete simulation",
"description": "Move a simulation to Recently Deleted (DELETE /v1/simulation/{simulation_id}).\n\nThe simulation leaves every list and can no longer be run or scheduled: its schedules are\ndisabled, and its always-on digital humans are switched off with their SIP trunks torn down.\nIts runs and results are kept, and it can be restored from Recently Deleted for 30 days;\nafter that it is purged permanently with its runs. The digital humans themselves are not\ndeleted. Ask the user to confirm before calling.\n\nReturns deleted, simulation_id, deleted_simulation_id and message.\n",
"inputSchema": {
"type": "object",
"title": "delete_simulationArguments",
"required": [
"simulation_id"
],
"properties": {
"simulation_id": {
"type": "string",
"title": "Simulation Id",
"description": "The simulation to delete: its id from list_simulations or get_simulation."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True once the simulation is in Recently Deleted."
},
"message": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Confirmation message, \"success\"."
},
"simulation_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The simulation id that was deleted, as passed in."
},
"deleted_simulation_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The deleted simulation's id."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Change an existing simulation's settings in place (PUT /v1/simulation/{simulation_id}).
Only the fields you pass are written; the rest keep their stored values. A null or omitted
field is not sent, so this tool cannot reset a setting to unset. Written values overwrite
the old ones with no history and apply to every run queued afterwards. List fields (tags,
selected_custom_metrics, hangup_on_transfer_bypass_phrases) replace the stored list rather
than add to it; digital_humans_settings only overwrites the keys it contains. Digital humans
are attached separately (bulk_set_digital_human_simulations).
Returns the updated simulation's fields at the top level, the same shape as get_simulation
without `data`.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Input documentation gives an agent enough context to populate the arguments.
simulation_id
The simulation to change: its id from list_simulations or create_simulation.
Clear enough to supply this argument.
name
New display name.
Clear enough to supply this argument.
description
New free-text description.
Clear enough to supply this argument.
prompt_id
New default agent version for runs: a version uuid from list_prompt_versions for this simulation's agent.
Clear enough to supply this argument.
knowledge_base_id
New default knowledge base uuid for runs; it must be in the simulation's workspace.
Clear enough to supply this argument.
max_concurrent
New limit on simultaneous conversations, at most 500; lowered to the org's concurrency ceiling if above it.
Clear enough to supply this argument.
hangup_on_transfer
true makes the digital human hang up when the agent transfers the call (unless a bypass phrase was said); false lets transfers through.
Clear enough to supply this argument.
hangup_on_transfer_bypass_phrases
Replaces the agent phrases that let a transfer go through while hangup_on_transfer is on; [] removes them all.
Clear enough to supply this argument.
max_call_duration
New longest conversation length, counted in max_call_duration_units (minutes when those are omitted).
Clear enough to supply this argument.
max_call_duration_units
Unit of max_call_duration; only read together with max_call_duration.
Clear enough to supply this argument.
max_turns
Text and email agents only: most turns a conversation may take. Rejected for voice agents, which use max_call_duration.
Clear enough to supply this argument.
ringing_timeout
New number of seconds to let a SIP call ring before abandoning it.
Clear enough to supply this argument.
digital_humans_settings
Digital-human defaults to change, as an object with any of default_name, default_caller_number, default_language, default_background_noise and first_message. Only the keys present are written.
Clear enough to supply this argument.
selected_custom_metrics
Replaces the custom metric ids (from list_custom_metrics) scored on this simulation; [] scores none.
Clear enough to supply this argument.
tags
Replaces the simulation's tags; [] removes them all.
Clear enough to supply this argument.
pinned
true pins the simulation, false unpins it.
Clear enough to supply this argument.
runs_per_digital_human
New default number of conversations each digital human has per run.
Clear enough to supply this argument.
delay_between_tests_seconds
New pause in seconds after one conversation finishes before the next starts, up to 300; 0 turns it off.
Clear enough to supply this argument.
inactivity_timeout_seconds
Text and email agents: new number of seconds to wait for the agent's reply before ending the conversation, 300 to 1800.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List every run of one simulation with its pass/fail counts (GET /v1/get-simulation-runs/{simulation_id}). Read-only.
`runs.simulation_runs` has one entry per run: id (pass it to get_simulation_results as
simulation_run_id), status (RUNNING or COMPLETED), created_at, total_tests, tests_completed,
tests_passed, eval_failed (graded failures), tests_failed (dropped calls and infra errors
only, not graded failures), summary and phone_number. A simulation that has never run comes
back as an error ("No simulation runs found"), not an empty list. For counts across many
runs, use list_simulated_conversations.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
simulation_id
The simulation whose runs to list: its id from list_simulations or create_simulation.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Create one or many digital humans in ONE call (POST /v1/create-digital-humans).
Three rules a good digital human follows (docs: /key-concepts/digital-humans/best-practices):
1. intent and success_criteria stay one or two sentences. Detail that grows them belongs
elsewhere: configuration for the caller, a custom metric for the grading.
2. Every "if the agent says X, the caller does Y" moves out of prose into a field —
traits for case facts the caller recites, scripted_responses for verbatim lines / DTMF /
silence, speaks_first_config for the opener, and lower creativity for repeatability.
3. Ground the case in the agent's real context (get_agent, get_workflow_summary) so the
scenario resembles a call this agent actually takes.
Always pass `simulation_ids`: the simulation the user named or is working in, else a new one
for that agent.
Pass a single-item list to create one. `digital_humans` carries each digital
human's config (intent, traits, voice, transcripts); `simulation_ids` is separate because
the endpoint attaches the SAME simulations to every item in the call. To give
items different simulations, create them here and then set membership per digital
human with bulk_set_digital_human_simulations.
language/accent/gender must form a valid combination — call get_voice_options
first to see the valid language -> accent pairings.
background_noise="custom" requires custom_background_noise_url: a storage_path
from the org's noise library (list_custom_background_noises, or upload via
create_custom_background_noise_upload_url + create_custom_background_noise).
Returns `created` (the new digital humans) and `errors` (per-item failures by index);
a partially successful batch returns both.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Bluejay-as-Code identity that pull and push use to match this digital human to its entry in your config files. Bluejay-as-Code assigns it; leave it unset when creating digital humans directly.
Clear enough to supply this argument.
$defs › DigitalHumanRequestData › intent
The scenario the digital human enacts, in ONE OR TWO SENTENCES: what this caller wants, not how to behave. It fills one slot in a prompt that ALREADY renders traits, verbosity, fluency, a not-the-agent guardrail and end-of-call instructions, so restating those here is duplicate prompt. Anything shaped like 'if the agent says X, do Y' does not belong here — it belongs in a field, and prose makes it non-deterministic. Move it: case facts the agent may ask for (member ID, DOB, order number, policy number) to `traits`; lines that must be said verbatim, a keypad entry, or a deliberate pause to `scripted_responses`; who opens the call to `speaks_first_config`; language, accent, fluency, verbosity, background noise, audio quality, interruptions, hangup and silence behavior to their own fields; and lower `creativity` for repeatability. If you reach for 'correctly', 'appropriately' or 'successfully' you are describing what the AGENT should do — that goes in `success_criteria`, not here. Leave empty when enriched_playback is set; the agent uses playback instead.
The pass/fail condition for this one test, in ONE OR TWO observable outcomes the transcript can settle (e.g. 'the agent verified the member ID and booked a callback'). It is not a rubric: a scored checklist, a per-dimension score, or a condition you want graded on every call in the suite belongs in a custom metric (`create_custom_metrics`) attached to the simulation, not in this string. Describe the AGENT's outcome here, never the digital human's own actions — those are `intent`. Leave empty when enriched_playback is set; the agent uses playback instead.
Clear enough to supply this argument.
$defs › DigitalHumanRequestData › name
Name of the digital human
Clear enough to supply this argument.
$defs › DigitalHumanRequestData › tag
Older single-string form of `tags`: a free-form label for grouping and filtering digital humans (list_digital_humans filters by tag). A comma-separated string becomes several tags. Ignored when `tags` is sent.
Clear enough to supply this argument.
$defs › DigitalHumanRequestData › tags
Full tag list (takes precedence over `tag`). Free-form labels; use `type` for voicemail, replay and the other kinds.
Clear enough to supply this argument.
$defs › DigitalHumanRequestData › type
What kind of digital human this is. Set it instead of putting sentinel values in tags; tags are free-form labels. Legacy sentinel tags (e.g. 'voicemail-custom', or 'transcript_generated' + 'smart') still set it when this is omitted.
The quoted system-prompt rules this digital human covers, shown on its card.
Clear enough to supply this argument.
$defs › DigitalHumanRequestData › language
Language the digital human speaks
Clear enough to supply this argument.
$defs › DigitalHumanRequestData › accent
Accent of the digital human
Clear enough to supply this argument.
$defs › DigitalHumanRequestData › gender
Gender of the digital human
Clear enough to supply this argument.
$defs › DigitalHumanRequestData › custom_voice_id
ElevenLabs voice_id of a cloned voice. When set, the agent speaks with this voice instead of the accent's stock voice (language/accent still drive prompts and STT).
How the digital human gives numbers the agent asks for (account numbers, PINs, menu choices): voiced speaks them, dtmf presses them as keypad tones where the input allows it.
Seconds the digital human waits before it replies. Named patience in the UI, and accepted under either name.
Clear enough to supply this argument.
$defs › DigitalHumanRequestData › creativity
Model temperature for the digital human's own speech. Lower it (0.0-0.3) when you want the same call twice — regression tests and anything you will compare run over run. Keep it near the 0.7 default for exploratory or red-team cases.
Freeform instructions for how/when to hang up. The literal string "default" (or null) keeps the tuned built-in end-of-call behavior, which already handles ordinary goodbyes; any other string REPLACES it, so write one only for a condition the default would miss.
Who this caller is, in one short line (e.g. 'retiree on a family plan, not comfortable with phone menus'). It owns identity and disposition only. What they are calling about is `intent`; the facts they can recite are `traits`; how they sound is language/accent/fluency/verbosity. Never put internal or agent-side information here — the digital human only knows what a real caller would know.
Clear enough to supply this argument.
$defs › Trait › trait_name
The fact's name, as the agent would ask for it (e.g. member_id, date_of_birth, order_number). Trait names are shared across the organization, so reuse an existing name rather than coining a variant. A trait is always something the CALLER knows and can say out loud, never internal or agent-side information (CRM contents, what the agent should look up or say, grader notes).
Clear enough to supply this argument.
$defs › Trait › trait_data_type
What kind of fact `value` holds: yes/no, free text, a calendar date written as an ISO 8601 string, or a number. `value` is converted to this kind when saved, so '42' or 'yes' is accepted.
Clear enough to supply this argument.
$defs › Trait › value
The concrete value this caller gives (stored as JSONB). Fixing it here is what makes the call repeatable — leave it out of `intent` prose, where the model would improvise a different one each run.
Clear enough to supply this argument.
$defs › Trait › is_sip_header
Send this fact as a SIP header on the call instead of as something the caller says aloud. Use it only when the agent reads the value from call metadata; ordinary case facts stay spoken.
Clear enough to supply this argument.
$defs › SimpleInterruptionConfig › type
How readily the digital human talks over the agent while the agent is still speaking, from never (none) to most often (high).
Clear enough to supply this argument.
$defs › KeywordsInterruptionConfig › type
Selects keyword interruptions: the digital human cuts in only when the agent says one of the keywords in keyword_responses.
Clear enough to supply this argument.
$defs › KeywordResponse › keyword
A word or phrase in the agent's speech that makes the digital human cut in, e.g. 'warranty'.
Clear enough to supply this argument.
$defs › KeywordResponse › response
What the digital human says when it cuts in on that keyword.
Clear enough to supply this argument.
$defs › KeywordResponse › probability
Chance the digital human actually cuts in each time the keyword comes up; lower it to make the interruption occasional.
How match_phrase is compared to the agent's turn. 'exact' is a fuzzy string comparison. Use it when you have the agent's literal line from a transcript, since it is stricter and costs no LLM call. 'context' asks an LLM whether the two utterances mean the same thing. Use it when the agent could phrase the same intent several ways.
Clear enough to supply this argument.
$defs › ScriptedResponse › match_phrase
An utterance the AGENT would say, which releases this response, e.g. 'Can I have your account number?'. Matching compares utterance to utterance, so a description of what the agent is doing ('the agent finished answering and is inviting another question') never matches anything: the rule saves and silently never fires. Write the line you expect to hear. Empty string is only meaningful when the digital human has scripted_responses_ordered set, where it fires on the digital human's next turn regardless of what the agent said.
Clear enough to supply this argument.
$defs › ScriptedResponse › response_type
Type of response: 'phrase', 'silence', 'dtmf', or 'audio'
Clear enough to supply this argument.
$defs › ScriptedResponse › response_value
The response text (required for 'phrase' and 'dtmf', optional for 'silence', unused for 'audio')
Skywatch bucket path of an uploaded audio file. AUDIO rows only — the agent downloads and plays this verbatim.
Clear enough to supply this argument.
$defs › ScriptedResponse › occurrence_mode
When to apply: 'always' or 'first_n'. Ignored when the digital human has scripted_responses_ordered set, where every step fires exactly once regardless.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › ScriptedResponse › occurrence_n
How many times this response fires when occurrence_mode is first_n; after that it no longer fires. Leave unset with always.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › ScriptedResponse › silence_duration
For a silence response, how many seconds the digital human stays silent. Only used when response_type is silence.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Run scripted_responses as a script in list order: only the next unfired one is armed, each fires once, and a blank match_phrase fires on the digital human's next turn. Turned off, any scripted response fires whenever its match_phrase comes up.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › SpeaksFirstConfig › speaks_first
Turn on to have the digital human open the call instead of waiting for the agent's greeting. Turned off, it waits for the agent to speak first, and mode, message and dynamic are cleared.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › SpeaksFirstConfig › mode
How the digital human opens when speaks_first is on: custom says your message word for word; ai_generated lets the digital human compose its own opener. Left unset with speaks_first on, it becomes ai_generated.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › SpeaksFirstConfig › message
The exact opening line the digital human says when mode is custom, e.g. 'Hi, I'm calling about my bill.'
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › SpeaksFirstConfig › dynamic
With speaks_first on: wait up to 5s for the agent to open, and speak first only if it stays quiet. If the agent does open, the digital human yields and a custom message is DISCARDED, not spoken after the greeting, so on any agent that greets callers a dynamic custom opener is never heard. Turn it off to say the opener every time, at the top of the call and possibly over the greeting. Configs saved before this setting existed behave as dynamic.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
A past call, as plain text, for the digital human to replay. Bluejay extracts the caller's lines with an LLM and uses them as the intent, unless formatted_transcript is also sent.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
A past call already split into turns, each with a role (USER for the caller, AGENT for the agent) and an utterance. The caller's lines become what the digital human says and the first speaker decides who opens. Sending it skips Bluejay's LLM formatting of original_transcript.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Turn-by-turn playbook the digital human follows instead of a free-form intent, usually built from a scenario-builder workflow path. Speech turns use type "message": a user turn carries intent and/or exact_message, an agent turn carries criteria and/or exact_match_text.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › DigitalHumanRequestData › workflow_v2_id
The scenario-builder workflow (id from list_workflows) this digital human walks a path of. Set together with workflow_path_index and tested_path.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Which path through that workflow this digital human walks, counting from 0 in the order Bluejay enumerates the workflow's paths.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › DigitalHumanRequestData › tested_path
Names of the workflow steps along the path this digital human walks, in order. Recorded when a digital human is generated from a workflow path.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › step
This leg's position in the journey, counting from 1. Legs run in this order, and the numbers across the list must run 1, 2, 3 with no gaps or repeats.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › intent
What the simulated customer does or wants on this leg, in one short sentence from the customer's side (e.g. 'Follow up about the late order'). Leave the channel out; modality carries it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › success_criteria
What the AGENT must have done for this leg to count as complete (e.g. 'the agent confirmed the new delivery date'). Describe the agent's outcome, not the customer's action.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › modality
Channel for this leg: a phone call, or an SMS exchange. One SMS leg covers the whole back-and-forth, the customer's text and the agent's reply.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › direction
Who reaches out first on this leg, seen from the agent: inbound means the customer calls or texts the agent; outbound means the agent places the call or sends the first text. Leave unset to use the agent's own direction. An outbound SMS leg cannot directly follow another SMS leg.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › wait_seconds
Delay before this leg starts, counted from when the previous leg finished; use it for 'an hour later' or 'the next day'. Values over 72 hours are cut to 72 hours.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › response_window_seconds
How long this leg waits for the agent to act (place the call, send the first text) before it ends. Leave unset for the standard step deadline. Values over 72 hours are cut to 72 hours.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › unresponsive
Make the customer deliberately not answer on this leg, to test whether the agent follows up: a voice leg goes to voicemail, and on an SMS leg the customer never texts.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › phone_number
Number to call, text, or expect contact from on this leg only, overriding the agent's number. Leave unset to use the run's or the agent's number.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › DigitalHumanRequestData › always_on_mode
Make this an always-on digital human: it answers calls arriving on its phone_number at any time, not only when a run dials out. Digital humans in an always-on simulation need it on.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Whether this always-on digital human is live on phone_number and picks up calls arriving there. Turned off, the number stays assigned but is not answered. Left unset, it is switched on when phone_number is set.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › DigitalHumanRequestData › num_runs
How many separate calls this digital human makes each time its simulation runs. Raise it to see how consistently the agent handles the same case.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Key-value metadata kept with this digital human for agents connected over LiveKit. Only meaningful for LiveKit agents.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › DigitalHumanRequestData › test_name
Short label identifying this test case in lists and run results, unique in the organization (a label already taken gets a number appended). Different from name, the caller's own name.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › DigitalHumanRequestData › attack_vector
For a red-team digital human, the attack tactic it uses, as a tactic key such as partial_info_bluff, sympathy_pressure or authority_impersonation. An unknown key is dropped. Leave unset for ordinary digital humans.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › DigitalHumanRequestData › attack_type
For a red-team digital human, its broad attack family. Normally derived from attack_vector. A value you send is kept if it is recon, or if no vector decides the family and it is one of social_engineering, prompt_injection, text_native, audio_native or content_harm.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › DigitalHumanRequestData › attack_plan
For a red-team digital human, its escalation plan: the objective, the condition that counts as a breach (breach_predicate), and the ladder of escalating steps. Leave unset for ordinary digital humans.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
simulation_ids
Simulations (ids from list_simulations) to attach EVERY created digital human to. Leave it out to create them unattached. To give items different simulations, create them first, then set each one's simulation_ids with update_digital_humans.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"errors": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"description": "Items the server rejected; every other item was still created. Each has index (its position in the digital_humans list sent), status_code (e.g. 400 invalid input, 409 always-on phone conflict) and detail (why it was rejected; a 409 ALWAYS_ON_PHONE_CONFLICT detail is an object with code, message and phone_number).",
"additionalProperties": true
},
"created": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"digital_human": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Unique identifier for the digital human"
},
"tag": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Tag for categorizing the digital human"
},
"name": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Name of the digital human"
},
"tags": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "All tags associated with the digital human"
},
"type": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What kind of digital human this is. Stored in test_cases.type; tags are free-form labels."
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "What kind of digital human this is (voicemail_custom, replay_smart, scenario, ...); null for a standard one"
},
"accent": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Enum for accent options."
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Accent of the digital human"
},
"gender": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Enum for gender options."
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Gender of the digital human"
},
"intent": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Description of the digital human"
},
"traits": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"value": {
"description": "The concrete value this caller gives (stored as JSONB). Fixing it here is what makes the call repeatable — leave it out of `intent` prose, where the model would improvise a different one each run."
},
"trait_name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The fact's name, as the agent would ask for it (e.g. member_id, date_of_birth, order_number). Trait names are shared across the organization, so reuse an existing name rather than coining a variant. A trait is always something the CALLER knows and can say out loud, never internal or agent-side information (CRM contents, what the agent should look up or say, grader notes)."
},
"is_sip_header": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Send this fact as a SIP header on the call instead of as something the caller says aloud. Use it only when the agent reads the value from call metadata; ordinary case facts stay spoken."
},
"trait_data_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What kind of fact `value` holds: yes/no, free text, a calendar date written as an ISO 8601 string, or a number. `value` is converted to this kind when saved, so '42' or 'yes' is accepted."
}
},
"description": "Model for a single trait.",
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "List of traits associated with this digital human"
},
"fluency": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Fluency level of the digital human's speech"
},
"language": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Enum for supported language types."
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Language of the digital human"
},
"num_runs": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Number of times this digital human is run per simulation run"
},
"extension": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Extension dialed as DTMF after connecting when this DH calls an inbound agent"
},
"test_name": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "User-facing label for this digital human"
},
"verbosity": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Verbosity level of the digital human's responses"
},
"created_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When this digital human was created"
},
"creativity": {
"anyOf": [
{
"type": [
"number",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Temperature setting"
},
"attack_plan": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Crescendo escalation ladder. NULL for non-red-team."
},
"attack_type": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Umbrella attack category. NULL for non-red-team."
},
"tested_path": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Ordered names of the workflow path steps this DH was generated from (Generate-From-Workflow only)."
},
"voice_speed": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Speed of the digital human's voice"
},
"phone_number": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Phone number for the digital human"
},
"attack_vector": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Attack tactic key from VECTOR_CATALOG. NULL for non-red-team."
},
"audio_quality": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Audio quality of the digital human's voice"
},
"interruptions": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Interruption configuration for the digital human"
},
"journey_steps": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"step": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "This leg's position in the journey, counting from 1. Legs run in this order, and the numbers across the list must run 1, 2, 3 with no gaps or repeats."
},
"intent": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the simulated customer does or wants on this leg, in one short sentence from the customer's side (e.g. 'Follow up about the late order'). Leave the channel out; modality carries it."
},
"modality": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Channel for this leg: a phone call, or an SMS exchange. One SMS leg covers the whole back-and-forth, the customer's text and the agent's reply."
},
"direction": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Who reaches out first on this leg, seen from the agent: inbound means the customer calls or texts the agent; outbound means the agent places the call or sends the first text. Leave unset to use the agent's own direction. An outbound SMS leg cannot directly follow another SMS leg."
},
"phone_number": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Number to call, text, or expect contact from on this leg only, overriding the agent's number. Leave unset to use the run's or the agent's number."
},
"unresponsive": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Make the customer deliberately not answer on this leg, to test whether the agent follows up: a voice leg goes to voicemail, and on an SMS leg the customer never texts."
},
"wait_seconds": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Delay before this leg starts, counted from when the previous leg finished; use it for 'an hour later' or 'the next day'. Values over 72 hours are cut to 72 hours."
},
"success_criteria": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the AGENT must have done for this leg to count as complete (e.g. 'the agent confirmed the new delivery date'). Describe the agent's outcome, not the customer's action."
},
"response_window_seconds": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How long this leg waits for the agent to act (place the call, send the first text) before it ends. Leave unset for the standard step deadline. Values over 72 hours are cut to 72 hours."
}
},
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Ordered journey steps for a multi-step (Customer Journey) digital human"
},
"websocket_url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "WebSocket URL for real-time communication"
},
"always_on_mode": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Whether always-on mode is enabled"
},
"hangup_phrases": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Phrases that trigger hangup"
},
"workflow_v2_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Source workflow_v2 UUID — set when this DH is generated from a workflow"
},
"allow_dtmf_tool": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Allow the digital human to use the DTMF tool"
},
"custom_voice_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "ElevenLabs voice_id of a cloned voice used for TTS, if assigned"
},
"silence_timeout": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Silence timeout in seconds"
},
"always_on_active": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When true, this DH actively receives inbound calls on phone_number"
},
"background_noise": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Type of background noise"
},
"livekit_metadata": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "LiveKit-specific configuration and metadata for this digital human"
},
"role_description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Description of the role for the digital human"
},
"success_criteria": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Success criteria for the digital human"
},
"endpointing_delay": {
"anyOf": [
{
"type": [
"number",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Delay for endpointing"
},
"enriched_playback": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Optional enriched playback stored as JSONB: a list of turn objects"
},
"allow_silence_tool": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Allow the digital human to use the silence tool"
},
"bluejay_as_code_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Stable code-addressable identifier"
},
"scripted_responses": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"match_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "How match_phrase is compared to the agent's turn. 'exact' is a fuzzy string comparison. Use it when you have the agent's literal line from a transcript, since it is stricter and costs no LLM call. 'context' asks an LLM whether the two utterances mean the same thing. Use it when the agent could phrase the same intent several ways."
},
"match_phrase": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "An utterance the AGENT would say, which releases this response, e.g. 'Can I have your account number?'. Matching compares utterance to utterance, so a description of what the agent is doing ('the agent finished answering and is inviting another question') never matches anything: the rule saves and silently never fires. Write the line you expect to hear. Empty string is only meaningful when the digital human has scripted_responses_ordered set, where it fires on the digital human's next turn regardless of what the agent said."
},
"occurrence_n": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How many times this response fires when occurrence_mode is first_n; after that it no longer fires. Leave unset with always."
},
"response_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Type of response: 'phrase', 'silence', 'dtmf', or 'audio'"
},
"response_value": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The response text (required for 'phrase' and 'dtmf', optional for 'silence', unused for 'audio')"
},
"occurrence_mode": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When to apply: 'always' or 'first_n'. Ignored when the digital human has scripted_responses_ordered set, where every step fires exactly once regardless."
},
"silence_duration": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "For a silence response, how many seconds the digital human stays silent. Only used when response_type is silence."
},
"scripted_response_audio_snippet_url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Skywatch bucket path of an uploaded audio file. AUDIO rows only — the agent downloads and plays this verbatim."
}
},
"description": "Model for a scripted response configuration.",
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "List of scripted responses for the digital human, in the order they were saved"
},
"allow_end_call_tool": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Allow the digital human to end the tool call"
},
"expected_tool_calls": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Name of the expected tool call"
},
"output": {
"anyOf": [
{},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Expected output returned by the tool call"
},
"parameters": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Expected parameters passed to the tool call"
}
},
"description": "Represents an expected tool call during a conversation.",
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Expected tool calls"
},
"hangup_instructions": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Freeform instructions for how/when to hang up"
},
"original_transcript": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The original transcript text attached to this digital human"
},
"speaks_first_config": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {
"mode": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How the digital human opens when speaks_first is on: custom says your message word for word; ai_generated lets the digital human compose its own opener. Left unset with speaks_first on, it becomes ai_generated."
},
"dynamic": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "With speaks_first on: wait up to 5s for the agent to open, and speak first only if it stays quiet. If the agent does open, the digital human yields and a custom message is DISCARDED, not spoken after the greeting, so on any agent that greets callers a dynamic custom opener is never heard. Turn it off to say the opener every time, at the top of the call and possibly over the greeting. Configs saved before this setting existed behave as dynamic."
},
"message": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The exact opening line the digital human says when mode is custom, e.g. 'Hi, I'm calling about my bill.'"
},
"speaks_first": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Turn on to have the digital human open the call instead of waiting for the agent's greeting. Turned off, it waits for the agent to speak first, and mode, message and dynamic are cleared."
}
},
"description": "Configuration for whether the digital human speaks first and how.\nStored as JSONB in Supabase (speaks_first_config).",
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Speaks first config: speaks_first, mode (custom|ai_generated), message (when custom), dynamic (wait for the agent, open only if quiet; defaults true)"
},
"workflow_path_index": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "0-based path index within enumerate_workflow_v2_paths output"
},
"formatted_transcript": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Structured transcript as [{\"role\": \"USER\"|\"AGENT\", \"utterance\": \"...\"}]"
},
"outbound_text_number": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Outbound text number"
},
"provider_request_data": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Per-digital-human variables handed to the provider when it originates the call"
},
"default_dtmf_or_voiced": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How the digital human gives numbers the agent asks for (account numbers, PINs, menu choices): voiced speaks them, dtmf presses them as keypad tones where the input allows it."
},
"system_prompt_rule_ids": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Ids of the system-prompt rules this digital human covers."
},
"background_noise_volume": {
"anyOf": [
{
"type": [
"number",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Volume of background noise"
},
"silence_tool_instructions": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Tool instructions; \"default\" or custom text"
},
"system_prompt_rule_quotes": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The quoted system-prompt rules this digital human covers."
},
"scripted_responses_ordered": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When true, scripted_responses run as a script in list order (each fires once, next one arms); when false any one fires whenever its match_phrase comes up"
},
"custom_background_noise_url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Bucket-relative path of the uploaded custom background noise audio when background_noise is 'custom'"
},
"follow_up_sms_success_criteria": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Criteria the captured follow-up SMS is graded against"
}
},
"description": "The full stored configuration: id, name, test_name, intent, success_criteria, tags, type, traits, scripted_responses, expected_tool_calls, language/accent/gender and the other voice and audio settings, speaks_first_config, interruptions, hangup settings, transcripts, journey_steps, phone_number and always-on state.",
"additionalProperties": true
},
"simulation_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Deprecated single-simulation form of simulation_ids; read simulation_ids instead."
},
"simulation_ids": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Ids of the simulations this digital human belongs to."
}
},
"description": "One digital human's stored configuration and the simulations it belongs to.",
"additionalProperties": true
},
"properties": {},
"description": "The digital humans that were created, each as {digital_human, simulation_ids}. Pass digital_human.id to get_digital_human, update_digital_humans or delete_digital_human.",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_digital_humans",
"title": "Create digital humans",
"description": "Create one or many digital humans in ONE call (POST /v1/create-digital-humans).\n\nThree rules a good digital human follows (docs: /key-concepts/digital-humans/best-practices):\n1. intent and success_criteria stay one or two sentences. Detail that grows them belongs\n elsewhere: configuration for the caller, a custom metric for the grading.\n2. Every \"if the agent says X, the caller does Y\" moves out of prose into a field —\n traits for case facts the caller recites, scripted_responses for verbatim lines / DTMF /\n silence, speaks_first_config for the opener, and lower creativity for repeatability.\n3. Ground the case in the agent's real context (get_agent, get_workflow_summary) so the\n scenario resembles a call this agent actually takes.\n\nAlways pass `simulation_ids`: the simulation the user named or is working in, else a new one\nfor that agent.\n\nPass a single-item list to create one. `digital_humans` carries each digital\nhuman's config (intent, traits, voice, transcripts); `simulation_ids` is separate because\nthe endpoint attaches the SAME simulations to every item in the call. To give\nitems different simulations, create them here and then set membership per digital\nhuman with bulk_set_digital_human_simulations.\n\nlanguage/accent/gender must form a valid combination — call get_voice_options\nfirst to see the valid language -> accent pairings.\n\nbackground_noise=\"custom\" requires custom_background_noise_url: a storage_path\nfrom the org's noise library (list_custom_background_noises, or upload via\ncreate_custom_background_noise_upload_url + create_custom_background_noise).\n\nReturns `created` (the new digital humans) and `errors` (per-item failures by index);\na partially successful batch returns both.\n",
"inputSchema": {
"type": "object",
"$defs": {
"Trait": {
"type": "object",
"title": "Trait",
"required": [
"trait_name",
"trait_data_type",
"value"
],
"properties": {
"value": {
"title": "Value",
"description": "The concrete value this caller gives (stored as JSONB). Fixing it here is what makes the call repeatable — leave it out of `intent` prose, where the model would improvise a different one each run."
},
"trait_name": {
"type": "string",
"title": "Trait Name",
"description": "The fact's name, as the agent would ask for it (e.g. member_id, date_of_birth, order_number). Trait names are shared across the organization, so reuse an existing name rather than coining a variant. A trait is always something the CALLER knows and can say out loud, never internal or agent-side information (CRM contents, what the agent should look up or say, grader notes)."
},
"is_sip_header": {
"type": "boolean",
"title": "Is Sip Header",
"default": false,
"description": "Send this fact as a SIP header on the call instead of as something the caller says aloud. Use it only when the agent reads the value from call metadata; ordinary case facts stay spoken."
},
"trait_data_type": {
"$ref": "#/$defs/TraitDataType",
"description": "What kind of fact `value` holds: yes/no, free text, a calendar date written as an ISO 8601 string, or a number. `value` is converted to this kind when saved, so '42' or 'yes' is accepted."
}
},
"description": "Model for a single trait."
},
"MatchType": {
"enum": [
"exact",
"context"
],
"type": "string",
"title": "MatchType",
"description": "Enum for scripted response match types."
},
"AccentType": {
"enum": [
"multilingual",
"american",
"american2",
"mature",
"southern",
"italian",
"indian",
"british",
"australian",
"scottish",
"irish",
"welsh",
"mexican",
"spanish",
"portuguese",
"french",
"turkish",
"japanese",
"hindi",
"arabic",
"egyptian",
"levantine",
"hebrew",
"russian",
"chinese",
"german",
"korean",
"urdu",
"telugu",
"tamil",
"malayalam",
"kannada",
"marathi",
"gujarati",
"vietnamese",
"cantonese",
"tagalog",
"greek",
"autodetect",
"watson",
"watsonbritish",
"watsonaustralian",
"watsoncanadian"
],
"type": "string",
"title": "AccentType",
"description": "Enum for accent options."
},
"GenderType": {
"enum": [
"male",
"female"
],
"type": "string",
"title": "GenderType",
"description": "Enum for gender options."
},
"FluencyType": {
"enum": [
"beginner",
"intermediate",
"native"
],
"type": "string",
"title": "FluencyType",
"description": "Enum for fluency level options."
},
"JourneyStep": {
"type": "object",
"title": "JourneyStep",
"required": [
"step"
],
"properties": {
"step": {
"type": "integer",
"title": "Step",
"minimum": 0,
"description": "This leg's position in the journey, counting from 1. Legs run in this order, and the numbers across the list must run 1, 2, 3 with no gaps or repeats."
},
"intent": {
"type": "string",
"title": "Intent",
"default": "",
"description": "What the simulated customer does or wants on this leg, in one short sentence from the customer's side (e.g. 'Follow up about the late order'). Leave the channel out; modality carries it."
},
"modality": {
"enum": [
"voice",
"sms"
],
"type": "string",
"title": "Modality",
"default": "voice",
"description": "Channel for this leg: a phone call, or an SMS exchange. One SMS leg covers the whole back-and-forth, the customer's text and the agent's reply."
},
"direction": {
"anyOf": [
{
"enum": [
"inbound",
"outbound"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Direction",
"default": null,
"description": "Who reaches out first on this leg, seen from the agent: inbound means the customer calls or texts the agent; outbound means the agent places the call or sends the first text. Leave unset to use the agent's own direction. An outbound SMS leg cannot directly follow another SMS leg."
},
"phone_number": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Phone Number",
"default": null,
"description": "Number to call, text, or expect contact from on this leg only, overriding the agent's number. Leave unset to use the run's or the agent's number."
},
"unresponsive": {
"type": "boolean",
"title": "Unresponsive",
"default": false,
"description": "Make the customer deliberately not answer on this leg, to test whether the agent follows up: a voice leg goes to voicemail, and on an SMS leg the customer never texts."
},
"wait_seconds": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Wait Seconds",
"default": null,
"description": "Delay before this leg starts, counted from when the previous leg finished; use it for 'an hour later' or 'the next day'. Values over 72 hours are cut to 72 hours."
},
"success_criteria": {
"type": "string",
"title": "Success Criteria",
"default": "",
"description": "What the AGENT must have done for this leg to count as complete (e.g. 'the agent confirmed the new delivery date'). Describe the agent's outcome, not the customer's action."
},
"response_window_seconds": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Response Window Seconds",
"default": null,
"description": "How long this leg waits for the agent to act (place the call, send the first text) before it ends. Leave unset for the standard step deadline. Values over 72 hours are cut to 72 hours."
}
}
},
"LanguageType": {
"enum": [
"en",
"es",
"pt",
"ja",
"tr",
"hi",
"ar",
"he",
"ru",
"zh",
"ml",
"fr",
"yue",
"vi",
"de",
"ko",
"ur",
"te",
"ta",
"mal",
"kn",
"mr",
"gu",
"tl",
"el",
"ad"
],
"type": "string",
"title": "LanguageType",
"description": "Enum for supported language types."
},
"ResponseType": {
"enum": [
"phrase",
"silence",
"dtmf",
"audio"
],
"type": "string",
"title": "ResponseType",
"description": "Enum for scripted response types."
},
"TraitDataType": {
"enum": [
"BOOLEAN",
"STRING",
"DATE",
"NUMBER"
],
"type": "string",
"title": "TraitDataType",
"description": "Enum for trait data types."
},
"VerbosityType": {
"enum": [
"low",
"medium",
"high"
],
"type": "string",
"title": "VerbosityType",
"description": "Enum for verbosity level options."
},
"OccurrenceMode": {
"enum": [
"always",
"first_n"
],
"type": "string",
"title": "OccurrenceMode",
"description": "Enum for scripted response occurrence modes."
},
"VoiceSpeedType": {
"enum": [
"slowest",
"slow",
"normal",
"fast",
"fastest"
],
"type": "string",
"title": "VoiceSpeedType",
"description": "Enum for voice speed options."
},
"KeywordResponse": {
"type": "object",
"title": "KeywordResponse",
"required": [
"keyword",
"response"
],
"properties": {
"keyword": {
"type": "string",
"title": "Keyword",
"description": "A word or phrase in the agent's speech that makes the digital human cut in, e.g. 'warranty'."
},
"response": {
"type": "string",
"title": "Response",
"description": "What the digital human says when it cuts in on that keyword."
},
"probability": {
"type": "number",
"title": "Probability",
"default": 1,
"maximum": 1,
"minimum": 0,
"description": "Chance the digital human actually cuts in each time the keyword comes up; lower it to make the interruption occasional."
}
},
"description": "Model for a keyword response configuration."
},
"AudioQualityType": {
"enum": [
"high",
"medium",
"low",
"horrible"
],
"type": "string",
"title": "AudioQualityType",
"description": "Enum for audio quality options."
},
"DigitalHumanType": {
"enum": [
"voicemail_custom",
"voicemail_ai",
"replay_smart",
"replay_strict",
"red_team",
"scenario",
"workflow",
"persona",
"journey"
],
"type": "string",
"title": "DigitalHumanType",
"description": "What kind of digital human this is. Stored in test_cases.type; tags are free-form labels."
},
"DtmfOrVoicedType": {
"enum": [
"voiced",
"dtmf"
],
"type": "string",
"title": "DtmfOrVoicedType",
"description": "Enum for DTMF vs voiced input mode."
},
"ExpectedToolCall": {
"type": "object",
"title": "ExpectedToolCall",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "Name of the expected tool call"
},
"output": {
"anyOf": [
{},
{
"type": "null"
}
],
"title": "Output",
"default": null,
"description": "Expected output returned by the tool call"
},
"parameters": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Parameters",
"default": null,
"description": "Expected parameters passed to the tool call"
}
},
"description": "Represents an expected tool call during a conversation."
},
"ScriptedResponse": {
"type": "object",
"title": "ScriptedResponse",
"required": [
"match_type",
"match_phrase",
"response_type",
"occurrence_mode"
],
"properties": {
"match_type": {
"$ref": "#/$defs/MatchType",
"description": "How match_phrase is compared to the agent's turn. 'exact' is a fuzzy string comparison. Use it when you have the agent's literal line from a transcript, since it is stricter and costs no LLM call. 'context' asks an LLM whether the two utterances mean the same thing. Use it when the agent could phrase the same intent several ways."
},
"match_phrase": {
"type": "string",
"title": "Match Phrase",
"description": "An utterance the AGENT would say, which releases this response, e.g. 'Can I have your account number?'. Matching compares utterance to utterance, so a description of what the agent is doing ('the agent finished answering and is inviting another question') never matches anything: the rule saves and silently never fires. Write the line you expect to hear. Empty string is only meaningful when the digital human has scripted_responses_ordered set, where it fires on the digital human's next turn regardless of what the agent said."
},
"occurrence_n": {
"anyOf": [
{
"type": "integer",
"exclusiveMinimum": 0
},
{
"type": "null"
}
],
"title": "Occurrence N",
"default": null,
"description": "How many times this response fires when occurrence_mode is first_n; after that it no longer fires. Leave unset with always."
},
"response_type": {
"$ref": "#/$defs/ResponseType",
"description": "Type of response: 'phrase', 'silence', 'dtmf', or 'audio'"
},
"response_value": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Response Value",
"default": null,
"description": "The response text (required for 'phrase' and 'dtmf', optional for 'silence', unused for 'audio')"
},
"occurrence_mode": {
"$ref": "#/$defs/OccurrenceMode",
"description": "When to apply: 'always' or 'first_n'. Ignored when the digital human has scripted_responses_ordered set, where every step fires exactly once regardless."
},
"silence_duration": {
"anyOf": [
{
"type": "integer",
"exclusiveMinimum": 0
},
{
"type": "null"
}
],
"title": "Silence Duration",
"default": null,
"description": "For a silence response, how many seconds the digital human stays silent. Only used when response_type is silence."
},
"scripted_response_audio_snippet_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Scripted Response Audio Snippet Url",
"default": null,
"description": "Skywatch bucket path of an uploaded audio file. AUDIO rows only — the agent downloads and plays this verbatim."
}
},
"description": "Model for a scripted response configuration."
},
"SpeaksFirstConfig": {
"type": "object",
"title": "SpeaksFirstConfig",
"required": [
"speaks_first"
],
"properties": {
"mode": {
"anyOf": [
{
"enum": [
"custom",
"ai_generated"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Mode",
"default": null,
"description": "How the digital human opens when speaks_first is on: custom says your message word for word; ai_generated lets the digital human compose its own opener. Left unset with speaks_first on, it becomes ai_generated."
},
"dynamic": {
"type": "boolean",
"title": "Dynamic",
"default": true,
"description": "With speaks_first on: wait up to 5s for the agent to open, and speak first only if it stays quiet. If the agent does open, the digital human yields and a custom message is DISCARDED, not spoken after the greeting, so on any agent that greets callers a dynamic custom opener is never heard. Turn it off to say the opener every time, at the top of the call and possibly over the greeting. Configs saved before this setting existed behave as dynamic."
},
"message": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Message",
"default": null,
"description": "The exact opening line the digital human says when mode is custom, e.g. 'Hi, I'm calling about my bill.'"
},
"speaks_first": {
"type": "boolean",
"title": "Speaks First",
"description": "Turn on to have the digital human open the call instead of waiting for the agent's greeting. Turned off, it waits for the agent to speak first, and mode, message and dynamic are cleared."
}
},
"description": "Configuration for whether the digital human speaks first and how.\nStored as JSONB in Supabase (speaks_first_config)."
},
"BackgroundNoiseType": {
"enum": [
"none",
"office",
"talking",
"traffic",
"cafe",
"park",
"tv",
"noisy_restaurant",
"hospital",
"airport",
"birdsong",
"bus_station",
"car_interior",
"city_night",
"city_traffic",
"construction",
"driving",
"factory",
"hotel_lobby",
"hotel_restaurant",
"keyboard_typing",
"light_rain",
"night_insects",
"office_open_plan",
"playground",
"pub",
"quiet_home",
"rain",
"restaurant_busy",
"restaurant_party",
"road_traffic",
"school",
"shopping_centre",
"street",
"subway_station",
"subway_train",
"supermarket",
"thunderstorm",
"train_station",
"urban",
"urban_park",
"wind",
"kitchen",
"living_room",
"meeting_room",
"small_office",
"cafeteria",
"restaurant",
"town_square",
"bus_ride",
"babble_light",
"babble_crowd",
"custom"
],
"type": "string",
"title": "BackgroundNoiseType",
"description": "Enum for background noise options."
},
"DigitalHumanRequestData": {
"type": "object",
"title": "DigitalHumanRequestData",
"properties": {
"tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tag",
"default": null,
"description": "Older single-string form of `tags`: a free-form label for grouping and filtering digital humans (list_digital_humans filters by tag). A comma-separated string becomes several tags. Ignored when `tags` is sent."
},
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Name",
"default": null,
"description": "Name of the digital human"
},
"tags": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Tags",
"default": null,
"description": "Full tag list (takes precedence over `tag`). Free-form labels; use `type` for voicemail, replay and the other kinds."
},
"type": {
"anyOf": [
{
"$ref": "#/$defs/DigitalHumanType"
},
{
"type": "null"
}
],
"default": null,
"description": "What kind of digital human this is. Set it instead of putting sentinel values in tags; tags are free-form labels. Legacy sentinel tags (e.g. 'voicemail-custom', or 'transcript_generated' + 'smart') still set it when this is omitted."
},
"accent": {
"anyOf": [
{
"$ref": "#/$defs/AccentType"
},
{
"type": "null"
}
],
"default": null,
"description": "Accent of the digital human"
},
"gender": {
"anyOf": [
{
"$ref": "#/$defs/GenderType"
},
{
"type": "null"
}
],
"default": null,
"description": "Gender of the digital human"
},
"intent": {
"type": "string",
"title": "Intent",
"default": "",
"description": "The scenario the digital human enacts, in ONE OR TWO SENTENCES: what this caller wants, not how to behave. It fills one slot in a prompt that ALREADY renders traits, verbosity, fluency, a not-the-agent guardrail and end-of-call instructions, so restating those here is duplicate prompt. Anything shaped like 'if the agent says X, do Y' does not belong here — it belongs in a field, and prose makes it non-deterministic. Move it: case facts the agent may ask for (member ID, DOB, order number, policy number) to `traits`; lines that must be said verbatim, a keypad entry, or a deliberate pause to `scripted_responses`; who opens the call to `speaks_first_config`; language, accent, fluency, verbosity, background noise, audio quality, interruptions, hangup and silence behavior to their own fields; and lower `creativity` for repeatability. If you reach for 'correctly', 'appropriately' or 'successfully' you are describing what the AGENT should do — that goes in `success_criteria`, not here. Leave empty when enriched_playback is set; the agent uses playback instead."
},
"traits": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/Trait"
}
},
{
"type": "null"
}
],
"title": "Traits",
"description": "Case facts THIS CALLER holds and can recite when the agent asks — member ID, DOB, order number, policy number, zip. Each is an org-level trait (name + BOOLEAN/STRING/DATE/NUMBER type + value), so the same fact stays a stable fixture across the suite instead of a number the model invents mid-call. Traits are the determinism lever: any case-specific value mentioned in `intent` prose should be a trait instead. They are NOT a place for internal or agent-side information (what the CRM holds, what the agent should look up or say, expected tool arguments, notes for the grader) — the schema has no notion of an internal trait, and a caller cannot know those. Expected tool arguments go in `expected_tool_calls`; grading notes go in `success_criteria` or a custom metric."
},
"fluency": {
"anyOf": [
{
"$ref": "#/$defs/FluencyType"
},
{
"type": "null"
}
],
"default": "native",
"description": "Fluency level of the digital human's speech"
},
"language": {
"anyOf": [
{
"$ref": "#/$defs/LanguageType"
},
{
"type": "null"
}
],
"default": "en",
"description": "Language the digital human speaks"
},
"num_runs": {
"anyOf": [
{
"type": "integer",
"minimum": 1
},
{
"type": "null"
}
],
"title": "Num Runs",
"default": 1,
"description": "How many separate calls this digital human makes each time its simulation runs. Raise it to see how consistently the agent handles the same case."
},
"extension": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Extension",
"default": null,
"description": "Extension dialed as DTMF after connecting when this DH calls an inbound agent"
},
"test_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Test Name",
"default": null,
"description": "Short label identifying this test case in lists and run results, unique in the organization (a label already taken gets a number appended). Different from name, the caller's own name."
},
"verbosity": {
"anyOf": [
{
"$ref": "#/$defs/VerbosityType"
},
{
"type": "null"
}
],
"default": "medium",
"description": "Verbosity level of the digital human's responses"
},
"creativity": {
"anyOf": [
{
"type": "number",
"maximum": 2,
"minimum": 0
},
{
"type": "null"
}
],
"title": "Creativity",
"default": 0.7,
"description": "Model temperature for the digital human's own speech. Lower it (0.0-0.3) when you want the same call twice — regression tests and anything you will compare run over run. Keep it near the 0.7 default for exploratory or red-team cases."
},
"attack_plan": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Attack Plan",
"default": null,
"description": "For a red-team digital human, its escalation plan: the objective, the condition that counts as a breach (breach_predicate), and the ladder of escalating steps. Leave unset for ordinary digital humans."
},
"attack_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Attack Type",
"default": null,
"description": "For a red-team digital human, its broad attack family. Normally derived from attack_vector. A value you send is kept if it is recon, or if no vector decides the family and it is one of social_engineering, prompt_injection, text_native, audio_native or content_harm."
},
"tested_path": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Tested Path",
"default": null,
"description": "Names of the workflow steps along the path this digital human walks, in order. Recorded when a digital human is generated from a workflow path."
},
"voice_speed": {
"anyOf": [
{
"$ref": "#/$defs/VoiceSpeedType"
},
{
"type": "null"
}
],
"default": "normal",
"description": "Speed of the digital human's voice"
},
"phone_number": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Phone Number",
"default": null,
"description": "Phone number for the digital human"
},
"attack_vector": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Attack Vector",
"default": null,
"description": "For a red-team digital human, the attack tactic it uses, as a tactic key such as partial_info_bluff, sympathy_pressure or authority_impersonation. An unknown key is dropped. Leave unset for ordinary digital humans."
},
"audio_quality": {
"anyOf": [
{
"$ref": "#/$defs/AudioQualityType"
},
{
"type": "null"
}
],
"default": "high",
"description": "Audio quality of the digital human's voice"
},
"interruptions": {
"anyOf": [
{
"$ref": "#/$defs/SimpleInterruptionConfig"
},
{
"$ref": "#/$defs/KeywordsInterruptionConfig"
},
{
"$ref": "#/$defs/ContextualInterruptionConfig"
},
{
"type": "null"
}
],
"title": "Interruptions",
"default": null,
"description": "Interruption configuration for the digital human"
},
"journey_steps": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/JourneyStep"
}
},
{
"type": "null"
}
],
"title": "Journey Steps",
"default": null,
"description": "The legs of a multi-step customer journey (calls and texts spread over time) this digital human plays out instead of a single call. With journey steps, intent can stay empty."
},
"always_on_mode": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Always On Mode",
"default": false,
"description": "Make this an always-on digital human: it answers calls arriving on its phone_number at any time, not only when a run dials out. Digital humans in an always-on simulation need it on."
},
"hangup_phrases": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Hangup Phrases",
"description": "Phrases that trigger hangup"
},
"workflow_v2_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Workflow V2 Id",
"default": null,
"description": "The scenario-builder workflow (id from list_workflows) this digital human walks a path of. Set together with workflow_path_index and tested_path."
},
"allow_dtmf_tool": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Allow Dtmf Tool",
"default": true,
"description": "Allow the digital human to use the DTMF tool"
},
"custom_voice_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Custom Voice Id",
"default": null,
"description": "ElevenLabs voice_id of a cloned voice. When set, the agent speaks with this voice instead of the accent's stock voice (language/accent still drive prompts and STT)."
},
"silence_timeout": {
"anyOf": [
{
"type": "integer",
"minimum": 15
},
{
"type": "null"
}
],
"title": "Silence Timeout",
"default": null,
"description": "Silence timeout in seconds"
},
"always_on_active": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Always On Active",
"default": null,
"description": "Whether this always-on digital human is live on phone_number and picks up calls arriving there. Turned off, the number stays assigned but is not answered. Left unset, it is switched on when phone_number is set."
},
"background_noise": {
"anyOf": [
{
"$ref": "#/$defs/BackgroundNoiseType"
},
{
"type": "null"
}
],
"default": "none",
"description": "Type of background noise"
},
"livekit_metadata": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Livekit Metadata",
"default": null,
"description": "Key-value metadata kept with this digital human for agents connected over LiveKit. Only meaningful for LiveKit agents."
},
"role_description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Role Description",
"default": null,
"description": "Who this caller is, in one short line (e.g. 'retiree on a family plan, not comfortable with phone menus'). It owns identity and disposition only. What they are calling about is `intent`; the facts they can recite are `traits`; how they sound is language/accent/fluency/verbosity. Never put internal or agent-side information here — the digital human only knows what a real caller would know."
},
"success_criteria": {
"type": "string",
"title": "Success Criteria",
"default": "",
"description": "The pass/fail condition for this one test, in ONE OR TWO observable outcomes the transcript can settle (e.g. 'the agent verified the member ID and booked a callback'). It is not a rubric: a scored checklist, a per-dimension score, or a condition you want graded on every call in the suite belongs in a custom metric (`create_custom_metrics`) attached to the simulation, not in this string. Describe the AGENT's outcome here, never the digital human's own actions — those are `intent`. Leave empty when enriched_playback is set; the agent uses playback instead."
},
"endpointing_delay": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "Endpointing Delay",
"default": 1.5,
"description": "Seconds the digital human waits before it replies. Named patience in the UI, and accepted under either name."
},
"enriched_playback": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
{
"type": "null"
}
],
"title": "Enriched Playback",
"default": null,
"description": "Turn-by-turn playbook the digital human follows instead of a free-form intent, usually built from a scenario-builder workflow path. Speech turns use type \"message\": a user turn carries intent and/or exact_message, an agent turn carries criteria and/or exact_match_text."
},
"allow_silence_tool": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Allow Silence Tool",
"default": true,
"description": "Allow the digital human to use the silence tool"
},
"bluejay_as_code_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Bluejay As Code Id",
"default": null,
"description": "Bluejay-as-Code identity that pull and push use to match this digital human to its entry in your config files. Bluejay-as-Code assigns it; leave it unset when creating digital humans directly."
},
"scripted_responses": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/ScriptedResponse"
}
},
{
"type": "null"
}
],
"title": "Scripted Responses",
"description": "The 'if the agent says X, the caller does Y' rules for this test, as data instead of prose. Reach for one whenever a reply must be identical every run: a verbatim line, a keypad entry (DTMF), or a deliberate silence. Each row pairs an agent utterance (`match_phrase`) with the response. Writing the same rule into `intent` makes it advisory; putting it here makes it deterministic."
},
"allow_end_call_tool": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Allow End Call Tool",
"default": true,
"description": "Allow the digital human to end the tool call"
},
"expected_tool_calls": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/ExpectedToolCall"
}
},
{
"type": "null"
}
],
"title": "Expected Tool Calls",
"description": "Expected tool call outputs"
},
"hangup_instructions": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Hangup Instructions",
"default": null,
"description": "Freeform instructions for how/when to hang up. The literal string \"default\" (or null) keeps the tuned built-in end-of-call behavior, which already handles ordinary goodbyes; any other string REPLACES it, so write one only for a condition the default would miss."
},
"original_transcript": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Original Transcript",
"default": null,
"description": "A past call, as plain text, for the digital human to replay. Bluejay extracts the caller's lines with an LLM and uses them as the intent, unless formatted_transcript is also sent."
},
"speaks_first_config": {
"anyOf": [
{
"$ref": "#/$defs/SpeaksFirstConfig"
},
{
"type": "null"
}
],
"default": null,
"description": "Who opens the call, and the caller's opening line when it must be fixed. Owns the opener so it does not have to be described in `intent`. Read the `dynamic` field before setting a custom message: on an agent that greets callers, a dynamic custom opener is discarded and never heard."
},
"workflow_path_index": {
"anyOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "null"
}
],
"title": "Workflow Path Index",
"default": null,
"description": "Which path through that workflow this digital human walks, counting from 0 in the order Bluejay enumerates the workflow's paths."
},
"formatted_transcript": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
{
"type": "null"
}
],
"title": "Formatted Transcript",
"default": null,
"description": "A past call already split into turns, each with a role (USER for the caller, AGENT for the agent) and an utterance. The caller's lines become what the digital human says and the first speaker decides who opens. Sending it skips Bluejay's LLM formatting of original_transcript."
},
"outbound_text_number": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Outbound Text Number",
"default": null,
"description": "Outbound text number"
},
"default_dtmf_or_voiced": {
"anyOf": [
{
"$ref": "#/$defs/DtmfOrVoicedType"
},
{
"type": "null"
}
],
"default": "voiced",
"description": "How the digital human gives numbers the agent asks for (account numbers, PINs, menu choices): voiced speaks them, dtmf presses them as keypad tones where the input allows it."
},
"system_prompt_rule_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "System Prompt Rule Ids",
"default": null,
"description": "Ids of the system-prompt rules this digital human covers, from generate."
},
"background_noise_volume": {
"anyOf": [
{
"type": "number",
"maximum": 1,
"minimum": 0
},
{
"type": "null"
}
],
"title": "Background Noise Volume",
"default": 0.8,
"description": "Volume of background noise"
},
"silence_tool_instructions": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Silence Tool Instructions",
"default": "default",
"description": "Tool instructions; use \"default\" for built-in behavior or custom text"
},
"system_prompt_rule_quotes": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "System Prompt Rule Quotes",
"default": null,
"description": "The quoted system-prompt rules this digital human covers, shown on its card."
},
"scripted_responses_ordered": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Scripted Responses Ordered",
"default": false,
"description": "Run scripted_responses as a script in list order: only the next unfired one is armed, each fires once, and a blank match_phrase fires on the digital human's next turn. Turned off, any scripted response fires whenever its match_phrase comes up."
},
"custom_background_noise_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Custom Background Noise Url",
"default": null,
"description": "Bucket-relative path of the uploaded custom background noise audio; required when background_noise is 'custom'"
},
"follow_up_sms_success_criteria": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Follow Up Sms Success Criteria",
"default": null,
"description": "Criteria the captured follow-up SMS is graded against"
}
},
"description": "Digital human data model for requests (without id and created_at)."
},
"SimpleInterruptionConfig": {
"type": "object",
"title": "Default",
"required": [
"type"
],
"properties": {
"type": {
"enum": [
"none",
"low",
"medium",
"high"
],
"type": "string",
"title": "Type",
"description": "How readily the digital human talks over the agent while the agent is still speaking, from never (none) to most often (high)."
}
},
"description": "Simple interruption configuration with predefined levels."
},
"KeywordsInterruptionConfig": {
"type": "object",
"title": "Keywords",
"required": [
"type",
"keyword_responses"
],
"properties": {
"type": {
"type": "string",
"const": "keywords",
"title": "Type",
"description": "Selects keyword interruptions: the digital human cuts in only when the agent says one of the keywords in keyword_responses."
},
"keyword_responses": {
"type": "array",
"items": {
"$ref": "#/$defs/KeywordResponse"
},
"title": "Keyword Responses",
"description": "The keywords to listen for in the agent's speech, each with what the digital human says when it cuts in."
}
},
"description": "Keywords-based interruption configuration."
},
"ContextualInterruptionConfig": {
"type": "object",
"title": "Contextual",
"required": [
"type",
"contextual_prompt"
],
"properties": {
"type": {
"type": "string",
"const": "contextual",
"title": "Type",
"description": "Type discriminator for contextual interruption"
},
"contextual_prompt": {
"type": "string",
"title": "Contextual Prompt",
"description": "Contextual prompt for LLM-based interruptions"
}
},
"description": "Contextual/LLM-based interruption configuration."
}
},
"title": "create_digital_humansArguments",
"required": [
"digital_humans"
],
"properties": {
"digital_humans": {
"type": "array",
"items": {
"$ref": "#/$defs/DigitalHumanRequestData"
},
"title": "Digital Humans",
"description": "The digital humans to create (1 to 100), one object per simulated caller; send a single-item list to create one. Each item is checked on its own: a rejected item is reported in errors by its index and the rest are still created."
},
"simulation_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "integer"
}
},
{
"type": "null"
}
],
"title": "Simulation Ids",
"default": null,
"description": "Simulations (ids from list_simulations) to attach EVERY created digital human to. Leave it out to create them unattached. To give items different simulations, create them first, then set each one's simulation_ids with update_digital_humans."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"errors": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"description": "Items the server rejected; every other item was still created. Each has index (its position in the digital_humans list sent), status_code (e.g. 400 invalid input, 409 always-on phone conflict) and detail (why it was rejected; a 409 ALWAYS_ON_PHONE_CONFLICT detail is an object with code, message and phone_number).",
"additionalProperties": true
},
"created": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"digital_human": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Unique identifier for the digital human"
},
"tag": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Tag for categorizing the digital human"
},
"name": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Name of the digital human"
},
"tags": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "All tags associated with the digital human"
},
"type": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What kind of digital human this is. Stored in test_cases.type; tags are free-form labels."
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "What kind of digital human this is (voicemail_custom, replay_smart, scenario, ...); null for a standard one"
},
"accent": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Enum for accent options."
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Accent of the digital human"
},
"gender": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Enum for gender options."
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Gender of the digital human"
},
"intent": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Description of the digital human"
},
"traits": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"value": {
"description": "The concrete value this caller gives (stored as JSONB). Fixing it here is what makes the call repeatable — leave it out of `intent` prose, where the model would improvise a different one each run."
},
"trait_name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The fact's name, as the agent would ask for it (e.g. member_id, date_of_birth, order_number). Trait names are shared across the organization, so reuse an existing name rather than coining a variant. A trait is always something the CALLER knows and can say out loud, never internal or agent-side information (CRM contents, what the agent should look up or say, grader notes)."
},
"is_sip_header": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Send this fact as a SIP header on the call instead of as something the caller says aloud. Use it only when the agent reads the value from call metadata; ordinary case facts stay spoken."
},
"trait_data_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What kind of fact `value` holds: yes/no, free text, a calendar date written as an ISO 8601 string, or a number. `value` is converted to this kind when saved, so '42' or 'yes' is accepted."
}
},
"description": "Model for a single trait.",
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "List of traits associated with this digital human"
},
"fluency": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Fluency level of the digital human's speech"
},
"language": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Enum for supported language types."
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Language of the digital human"
},
"num_runs": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Number of times this digital human is run per simulation run"
},
"extension": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Extension dialed as DTMF after connecting when this DH calls an inbound agent"
},
"test_name": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "User-facing label for this digital human"
},
"verbosity": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Verbosity level of the digital human's responses"
},
"created_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When this digital human was created"
},
"creativity": {
"anyOf": [
{
"type": [
"number",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Temperature setting"
},
"attack_plan": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Crescendo escalation ladder. NULL for non-red-team."
},
"attack_type": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Umbrella attack category. NULL for non-red-team."
},
"tested_path": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Ordered names of the workflow path steps this DH was generated from (Generate-From-Workflow only)."
},
"voice_speed": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Speed of the digital human's voice"
},
"phone_number": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Phone number for the digital human"
},
"attack_vector": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Attack tactic key from VECTOR_CATALOG. NULL for non-red-team."
},
"audio_quality": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Audio quality of the digital human's voice"
},
"interruptions": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Interruption configuration for the digital human"
},
"journey_steps": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"step": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "This leg's position in the journey, counting from 1. Legs run in this order, and the numbers across the list must run 1, 2, 3 with no gaps or repeats."
},
"intent": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the simulated customer does or wants on this leg, in one short sentence from the customer's side (e.g. 'Follow up about the late order'). Leave the channel out; modality carries it."
},
"modality": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Channel for this leg: a phone call, or an SMS exchange. One SMS leg covers the whole back-and-forth, the customer's text and the agent's reply."
},
"direction": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Who reaches out first on this leg, seen from the agent: inbound means the customer calls or texts the agent; outbound means the agent places the call or sends the first text. Leave unset to use the agent's own direction. An outbound SMS leg cannot directly follow another SMS leg."
},
"phone_number": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Number to call, text, or expect contact from on this leg only, overriding the agent's number. Leave unset to use the run's or the agent's number."
},
"unresponsive": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Make the customer deliberately not answer on this leg, to test whether the agent follows up: a voice leg goes to voicemail, and on an SMS leg the customer never texts."
},
"wait_seconds": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Delay before this leg starts, counted from when the previous leg finished; use it for 'an hour later' or 'the next day'. Values over 72 hours are cut to 72 hours."
},
"success_criteria": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the AGENT must have done for this leg to count as complete (e.g. 'the agent confirmed the new delivery date'). Describe the agent's outcome, not the customer's action."
},
"response_window_seconds": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How long this leg waits for the agent to act (place the call, send the first text) before it ends. Leave unset for the standard step deadline. Values over 72 hours are cut to 72 hours."
}
},
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Ordered journey steps for a multi-step (Customer Journey) digital human"
},
"websocket_url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "WebSocket URL for real-time communication"
},
"always_on_mode": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Whether always-on mode is enabled"
},
"hangup_phrases": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Phrases that trigger hangup"
},
"workflow_v2_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Source workflow_v2 UUID — set when this DH is generated from a workflow"
},
"allow_dtmf_tool": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Allow the digital human to use the DTMF tool"
},
"custom_voice_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "ElevenLabs voice_id of a cloned voice used for TTS, if assigned"
},
"silence_timeout": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Silence timeout in seconds"
},
"always_on_active": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When true, this DH actively receives inbound calls on phone_number"
},
"background_noise": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Type of background noise"
},
"livekit_metadata": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "LiveKit-specific configuration and metadata for this digital human"
},
"role_description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Description of the role for the digital human"
},
"success_criteria": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Success criteria for the digital human"
},
"endpointing_delay": {
"anyOf": [
{
"type": [
"number",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Delay for endpointing"
},
"enriched_playback": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Optional enriched playback stored as JSONB: a list of turn objects"
},
"allow_silence_tool": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Allow the digital human to use the silence tool"
},
"bluejay_as_code_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Stable code-addressable identifier"
},
"scripted_responses": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"match_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "How match_phrase is compared to the agent's turn. 'exact' is a fuzzy string comparison. Use it when you have the agent's literal line from a transcript, since it is stricter and costs no LLM call. 'context' asks an LLM whether the two utterances mean the same thing. Use it when the agent could phrase the same intent several ways."
},
"match_phrase": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "An utterance the AGENT would say, which releases this response, e.g. 'Can I have your account number?'. Matching compares utterance to utterance, so a description of what the agent is doing ('the agent finished answering and is inviting another question') never matches anything: the rule saves and silently never fires. Write the line you expect to hear. Empty string is only meaningful when the digital human has scripted_responses_ordered set, where it fires on the digital human's next turn regardless of what the agent said."
},
"occurrence_n": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How many times this response fires when occurrence_mode is first_n; after that it no longer fires. Leave unset with always."
},
"response_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Type of response: 'phrase', 'silence', 'dtmf', or 'audio'"
},
"response_value": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The response text (required for 'phrase' and 'dtmf', optional for 'silence', unused for 'audio')"
},
"occurrence_mode": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When to apply: 'always' or 'first_n'. Ignored when the digital human has scripted_responses_ordered set, where every step fires exactly once regardless."
},
"silence_duration": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "For a silence response, how many seconds the digital human stays silent. Only used when response_type is silence."
},
"scripted_response_audio_snippet_url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Skywatch bucket path of an uploaded audio file. AUDIO rows only — the agent downloads and plays this verbatim."
}
},
"description": "Model for a scripted response configuration.",
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "List of scripted responses for the digital human, in the order they were saved"
},
"allow_end_call_tool": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Allow the digital human to end the tool call"
},
"expected_tool_calls": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Name of the expected tool call"
},
"output": {
"anyOf": [
{},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Expected output returned by the tool call"
},
"parameters": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Expected parameters passed to the tool call"
}
},
"description": "Represents an expected tool call during a conversation.",
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Expected tool calls"
},
"hangup_instructions": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Freeform instructions for how/when to hang up"
},
"original_transcript": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The original transcript text attached to this digital human"
},
"speaks_first_config": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {
"mode": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How the digital human opens when speaks_first is on: custom says your message word for word; ai_generated lets the digital human compose its own opener. Left unset with speaks_first on, it becomes ai_generated."
},
"dynamic": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "With speaks_first on: wait up to 5s for the agent to open, and speak first only if it stays quiet. If the agent does open, the digital human yields and a custom message is DISCARDED, not spoken after the greeting, so on any agent that greets callers a dynamic custom opener is never heard. Turn it off to say the opener every time, at the top of the call and possibly over the greeting. Configs saved before this setting existed behave as dynamic."
},
"message": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The exact opening line the digital human says when mode is custom, e.g. 'Hi, I'm calling about my bill.'"
},
"speaks_first": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Turn on to have the digital human open the call instead of waiting for the agent's greeting. Turned off, it waits for the agent to speak first, and mode, message and dynamic are cleared."
}
},
"description": "Configuration for whether the digital human speaks first and how.\nStored as JSONB in Supabase (speaks_first_config).",
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Speaks first config: speaks_first, mode (custom|ai_generated), message (when custom), dynamic (wait for the agent, open only if quiet; defaults true)"
},
"workflow_path_index": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "0-based path index within enumerate_workflow_v2_paths output"
},
"formatted_transcript": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Structured transcript as [{\"role\": \"USER\"|\"AGENT\", \"utterance\": \"...\"}]"
},
"outbound_text_number": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Outbound text number"
},
"provider_request_data": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Per-digital-human variables handed to the provider when it originates the call"
},
"default_dtmf_or_voiced": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How the digital human gives numbers the agent asks for (account numbers, PINs, menu choices): voiced speaks them, dtmf presses them as keypad tones where the input allows it."
},
"system_prompt_rule_ids": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Ids of the system-prompt rules this digital human covers."
},
"background_noise_volume": {
"anyOf": [
{
"type": [
"number",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Volume of background noise"
},
"silence_tool_instructions": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Tool instructions; \"default\" or custom text"
},
"system_prompt_rule_quotes": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The quoted system-prompt rules this digital human covers."
},
"scripted_responses_ordered": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When true, scripted_responses run as a script in list order (each fires once, next one arms); when false any one fires whenever its match_phrase comes up"
},
"custom_background_noise_url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Bucket-relative path of the uploaded custom background noise audio when background_noise is 'custom'"
},
"follow_up_sms_success_criteria": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Criteria the captured follow-up SMS is graded against"
}
},
"description": "The full stored configuration: id, name, test_name, intent, success_criteria, tags, type, traits, scripted_responses, expected_tool_calls, language/accent/gender and the other voice and audio settings, speaks_first_config, interruptions, hangup settings, transcripts, journey_steps, phone_number and always-on state.",
"additionalProperties": true
},
"simulation_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Deprecated single-simulation form of simulation_ids; read simulation_ids instead."
},
"simulation_ids": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Ids of the simulations this digital human belongs to."
}
},
"description": "One digital human's stored configuration and the simulations it belongs to.",
"additionalProperties": true
},
"properties": {},
"description": "The digital humans that were created, each as {digital_human, simulation_ids}. Pass digital_human.id to get_digital_human, update_digital_humans or delete_digital_human.",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Update one or many digital humans in ONE call (PUT /v1/update-digital-humans).
Pass a single-item list to update one. Each item is {digital_human_id, update}:
`digital_human_id` picks the row, `update` carries only the fields to change —
intent, success_criteria, traits, expected_tool_calls, voice settings,
simulation_ids. Omitted fields keep their stored values. Most list fields you
pass REPLACE rather than append. Traits are different: when you send traits,
traits_mode defaults to "merge" (change only the listed trait_name rows; read
traits with list_digital_humans first). Set traits_mode="replace" to delete
every stored trait and keep only the list you send. Duplicate digital_human_id
values are rejected.
Pass update.phone_number="" to clear an assigned number and turn off
always_on_active. On a 409 ALWAYS_ON_PHONE_CONFLICT, retry that item with
update.override_conflict=True to move the number off the conflicting digital human.
Returns the updated rows in `updated` and per-item failures in `errors`; `error` is set
when any item failed, and unknown update fields are rejected.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Explain the meaning of this value, not just its name.
$defs › BulkDigitalHumanUpdate › digital_human_id
ID of the digital human to update
Clear enough to supply this argument.
$defs › StrictDigitalHumanUpdate › intent
The scenario the digital human enacts, in ONE OR TWO SENTENCES: what this caller wants, not how to behave. It fills one slot in a prompt that ALREADY renders traits, verbosity, fluency, a not-the-agent guardrail and end-of-call instructions, so restating those here is duplicate prompt. Anything shaped like 'if the agent says X, do Y' does not belong here — prose makes it non-deterministic. Move it: case facts the agent may ask for (member ID, DOB, order number) to `traits`; lines that must be said verbatim, a keypad entry, or a deliberate pause to `scripted_responses`; who opens the call to `speaks_first_config`; voice and call conditions to their own fields; and lower `creativity` for repeatability. If you reach for 'correctly', 'appropriately' or 'successfully' you are describing what the AGENT should do — that goes in `success_criteria`.
Clear enough to supply this argument.
$defs › SuccessCriterionInput › text
One pass/fail condition: an observable outcome of the AGENT that the transcript can settle (e.g. 'the agent booked a callback'). Each item is graded as its own check.
Clear enough to supply this argument.
$defs › SuccessCriterionInput › id
An existing criterion's id. Can be left out: every criterion in the list is saved as a new check with a new id.
Clear enough to supply this argument.
$defs › StrictDigitalHumanUpdate › name
Name of the digital human
Clear enough to supply this argument.
$defs › StrictDigitalHumanUpdate › tag
Tag for categorizing the digital human
Clear enough to supply this argument.
$defs › StrictDigitalHumanUpdate › tags
Full tag list, replacing the current tags; [] clears them. Takes precedence over `tag`, where an empty string leaves tags unchanged.
Clear enough to supply this argument.
$defs › StrictDigitalHumanUpdate › type
What kind of digital human this is. Set it instead of putting sentinel values in tags; tags are free-form labels. Legacy sentinel tags (e.g. 'voicemail-custom', or 'transcript_generated' + 'smart') still set it when this is omitted.
Controls whether the agent submits numerical values via DTMF or voice. 'voiced' = speak numbers (default), 'dtmf' = use DTMF tones for eligible numerical inputs
Seconds the digital human waits before it replies. Named patience in the UI, and accepted under either name.
Clear enough to supply this argument.
$defs › StrictDigitalHumanUpdate › creativity
How much the digital human varies its own wording (the model temperature for its speech). Lower it when you want the same call twice, for regression tests and anything compared run over run; keep it higher for exploratory or red-team cases.
When and how the digital human ends the call, in your own words. The built-in end-of-call behavior already handles ordinary goodbyes and any text here REPLACES it, so write instructions only for a condition it would miss. Send "default" to go back to the built-in behavior.
Array of simulation IDs to associate with this digital human. If provided, completely replaces existing associations.
Clear enough to supply this argument.
$defs › Trait › trait_name
The fact's name, as the agent would ask for it (e.g. member_id, date_of_birth, order_number). Trait names are shared across the organization, so reuse an existing name rather than coining a variant. A trait is always something the CALLER knows and can say out loud, never internal or agent-side information (CRM contents, what the agent should look up or say, grader notes).
Clear enough to supply this argument.
$defs › Trait › trait_data_type
What kind of fact `value` holds: yes/no, free text, a calendar date written as an ISO 8601 string, or a number. `value` is converted to this kind when saved, so '42' or 'yes' is accepted.
Clear enough to supply this argument.
$defs › Trait › value
The concrete value this caller gives (stored as JSONB). Fixing it here is what makes the call repeatable — leave it out of `intent` prose, where the model would improvise a different one each run.
Clear enough to supply this argument.
$defs › Trait › is_sip_header
Send this fact as a SIP header on the call instead of as something the caller says aloud. Use it only when the agent reads the value from call metadata; ordinary case facts stay spoken.
Clear enough to supply this argument.
$defs › StrictDigitalHumanUpdate › traits_mode
How `traits` apply when you send traits on an update. Omitted or "merge" upserts only the listed traits by trait_name and keeps every other stored trait. "replace" deletes all stored traits first, then writes only the list — use this to remove traits or to set the full trait set from scratch.
Clear enough to supply this argument.
$defs › SimpleInterruptionConfig › type
How readily the digital human talks over the agent while the agent is still speaking, from never (none) to most often (high).
Clear enough to supply this argument.
$defs › KeywordsInterruptionConfig › type
Selects keyword interruptions: the digital human cuts in only when the agent says one of the keywords in keyword_responses.
Clear enough to supply this argument.
$defs › KeywordResponse › keyword
A word or phrase in the agent's speech that makes the digital human cut in, e.g. 'warranty'.
Clear enough to supply this argument.
$defs › KeywordResponse › response
What the digital human says when it cuts in on that keyword.
Clear enough to supply this argument.
$defs › KeywordResponse › probability
Chance the digital human actually cuts in each time the keyword comes up; lower it to make the interruption occasional.
How match_phrase is compared to the agent's turn. 'exact' is a fuzzy string comparison. Use it when you have the agent's literal line from a transcript, since it is stricter and costs no LLM call. 'context' asks an LLM whether the two utterances mean the same thing. Use it when the agent could phrase the same intent several ways.
Clear enough to supply this argument.
$defs › ScriptedResponse › match_phrase
An utterance the AGENT would say, which releases this response, e.g. 'Can I have your account number?'. Matching compares utterance to utterance, so a description of what the agent is doing ('the agent finished answering and is inviting another question') never matches anything: the rule saves and silently never fires. Write the line you expect to hear. Empty string is only meaningful when the digital human has scripted_responses_ordered set, where it fires on the digital human's next turn regardless of what the agent said.
Clear enough to supply this argument.
$defs › ScriptedResponse › response_type
Type of response: 'phrase', 'silence', 'dtmf', or 'audio'
Clear enough to supply this argument.
$defs › ScriptedResponse › response_value
The response text (required for 'phrase' and 'dtmf', optional for 'silence', unused for 'audio')
Skywatch bucket path of an uploaded audio file. AUDIO rows only — the agent downloads and plays this verbatim.
Clear enough to supply this argument.
$defs › ScriptedResponse › occurrence_mode
When to apply: 'always' or 'first_n'. Ignored when the digital human has scripted_responses_ordered set, where every step fires exactly once regardless.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › ScriptedResponse › occurrence_n
How many times this response fires when occurrence_mode is first_n; after that it no longer fires. Leave unset with always.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › ScriptedResponse › silence_duration
For a silence response, how many seconds the digital human stays silent. Only used when response_type is silence.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Run scripted_responses as a script in list order: only the next unfired one is armed, each fires once, and a blank match_phrase fires on the digital human's next turn. Turned off, any scripted response fires whenever its match_phrase comes up.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Who this caller is and how they come across, e.g. 'retiree on a family plan, not comfortable with phone menus'. What they are calling about belongs in `intent`, the facts they can recite in `traits`, how they sound in language/accent/fluency/verbosity. Never internal or agent-side information: the digital human only knows what a real caller would know.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › SpeaksFirstConfig › speaks_first
Turn on to have the digital human open the call instead of waiting for the agent's greeting. Turned off, it waits for the agent to speak first, and mode, message and dynamic are cleared.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › SpeaksFirstConfig › mode
How the digital human opens when speaks_first is on: custom says your message word for word; ai_generated lets the digital human compose its own opener. Left unset with speaks_first on, it becomes ai_generated.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › SpeaksFirstConfig › message
The exact opening line the digital human says when mode is custom, e.g. 'Hi, I'm calling about my bill.'
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › SpeaksFirstConfig › dynamic
With speaks_first on: wait up to 5s for the agent to open, and speak first only if it stays quiet. If the agent does open, the digital human yields and a custom message is DISCARDED, not spoken after the greeting, so on any agent that greets callers a dynamic custom opener is never heard. Turn it off to say the opener every time, at the top of the call and possibly over the greeting. Configs saved before this setting existed behave as dynamic.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The original_transcript already split into turns, each with a role (USER for the caller, AGENT for the agent) and an utterance. Send it alongside original_transcript to skip Bluejay's LLM formatting step.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Variables this digital human hands the voice platform when the call is placed: Bland request_data, Vapi variableValues or Retell dynamic variables. They override the agent's template values. Sending it replaces the stored set; send {} to clear it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › StrictDigitalHumanUpdate › always_on_mode
Make this an always-on digital human: it answers calls arriving on its phone_number at any time, not only when a run dials out. Digital humans in an always-on simulation need it on.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Whether this always-on digital human is live on phone_number and picks up calls arriving there. Turned off, the number stays assigned but is not answered.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › StrictDigitalHumanUpdate › test_name
Short label identifying this test case in lists and run results. It must be unique in the organization; a label another digital human uses is rejected. Different from name, the caller's own name.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › step
This leg's position in the journey, counting from 1. Legs run in this order, and the numbers across the list must run 1, 2, 3 with no gaps or repeats.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › intent
What the simulated customer does or wants on this leg, in one short sentence from the customer's side (e.g. 'Follow up about the late order'). Leave the channel out; modality carries it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › success_criteria
What the AGENT must have done for this leg to count as complete (e.g. 'the agent confirmed the new delivery date'). Describe the agent's outcome, not the customer's action.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › modality
Channel for this leg: a phone call, or an SMS exchange. One SMS leg covers the whole back-and-forth, the customer's text and the agent's reply.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › direction
Who reaches out first on this leg, seen from the agent: inbound means the customer calls or texts the agent; outbound means the agent places the call or sends the first text. Leave unset to use the agent's own direction. An outbound SMS leg cannot directly follow another SMS leg.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › wait_seconds
Delay before this leg starts, counted from when the previous leg finished; use it for 'an hour later' or 'the next day'. Values over 72 hours are cut to 72 hours.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › response_window_seconds
How long this leg waits for the agent to act (place the call, send the first text) before it ends. Leave unset for the standard step deadline. Values over 72 hours are cut to 72 hours.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › unresponsive
Make the customer deliberately not answer on this leg, to test whether the agent follows up: a voice leg goes to voicemail, and on an SMS leg the customer never texts.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › JourneyStep › phone_number
Number to call, text, or expect contact from on this leg only, overriding the agent's number. Leave unset to use the run's or the agent's number.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Take phone_number over from another always-on digital human that is live on it. Send it when retrying an item that failed with 409 ALWAYS_ON_PHONE_CONFLICT; the other digital human loses the number.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Ids of the agent version's locked system-prompt rules this digital human tests. generate_digital_humans fills them in when it generates with system_prompt.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Which path through that workflow this digital human walks, counting from 0 in the order Bluejay enumerates the workflow's paths.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › StrictDigitalHumanUpdate › tested_path
Names of the workflow steps along the path this digital human walks, in order. Recorded when a digital human is generated from a workflow path.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › StrictDigitalHumanUpdate › attack_vector
For a red-team digital human, the attack tactic it uses, as a tactic key such as partial_info_bluff, sympathy_pressure or authority_impersonation. An unknown key is dropped.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › StrictDigitalHumanUpdate › attack_type
For a red-team digital human, its broad attack family. Normally derived from attack_vector. A value you send is kept if it is recon, or if no vector decides the family and it is one of social_engineering, prompt_injection, text_native, audio_native or content_harm.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › StrictDigitalHumanUpdate › attack_plan
For a red-team digital human, its escalation plan: the objective, the condition that counts as a breach (breach_predicate), and the ladder of escalating steps.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"errors": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"description": "Items that failed; every other item was still updated. Each has digital_human_id, status_code (e.g. 404 not found, 409 ALWAYS_ON_PHONE_CONFLICT) and detail (why it failed).",
"additionalProperties": true
},
"updated_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"string",
"null"
]
},
"description": "Ids of the digital humans that were updated; read one back with get_digital_human."
},
"updated_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "How many digital humans were updated."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "update_digital_humans",
"title": "Update digital humans",
"description": "Update one or many digital humans in ONE call (PUT /v1/update-digital-humans).\n\nPass a single-item list to update one. Each item is {digital_human_id, update}:\n`digital_human_id` picks the row, `update` carries only the fields to change —\nintent, success_criteria, traits, expected_tool_calls, voice settings,\nsimulation_ids. Omitted fields keep their stored values. Most list fields you\npass REPLACE rather than append. Traits are different: when you send traits,\ntraits_mode defaults to \"merge\" (change only the listed trait_name rows; read\ntraits with list_digital_humans first). Set traits_mode=\"replace\" to delete\nevery stored trait and keep only the list you send. Duplicate digital_human_id\nvalues are rejected.\n\nPass update.phone_number=\"\" to clear an assigned number and turn off\nalways_on_active. On a 409 ALWAYS_ON_PHONE_CONFLICT, retry that item with\nupdate.override_conflict=True to move the number off the conflicting digital human.\n\nReturns the updated rows in `updated` and per-item failures in `errors`; `error` is set\nwhen any item failed, and unknown update fields are rejected.\n",
"inputSchema": {
"type": "object",
"$defs": {
"Trait": {
"type": "object",
"title": "Trait",
"required": [
"trait_name",
"trait_data_type",
"value"
],
"properties": {
"value": {
"title": "Value",
"description": "The concrete value this caller gives (stored as JSONB). Fixing it here is what makes the call repeatable — leave it out of `intent` prose, where the model would improvise a different one each run."
},
"trait_name": {
"type": "string",
"title": "Trait Name",
"description": "The fact's name, as the agent would ask for it (e.g. member_id, date_of_birth, order_number). Trait names are shared across the organization, so reuse an existing name rather than coining a variant. A trait is always something the CALLER knows and can say out loud, never internal or agent-side information (CRM contents, what the agent should look up or say, grader notes)."
},
"is_sip_header": {
"type": "boolean",
"title": "Is Sip Header",
"default": false,
"description": "Send this fact as a SIP header on the call instead of as something the caller says aloud. Use it only when the agent reads the value from call metadata; ordinary case facts stay spoken."
},
"trait_data_type": {
"$ref": "#/$defs/TraitDataType",
"description": "What kind of fact `value` holds: yes/no, free text, a calendar date written as an ISO 8601 string, or a number. `value` is converted to this kind when saved, so '42' or 'yes' is accepted."
}
},
"description": "Model for a single trait."
},
"MatchType": {
"enum": [
"exact",
"context"
],
"type": "string",
"title": "MatchType",
"description": "Enum for scripted response match types."
},
"AccentType": {
"enum": [
"multilingual",
"american",
"american2",
"mature",
"southern",
"italian",
"indian",
"british",
"australian",
"scottish",
"irish",
"welsh",
"mexican",
"spanish",
"portuguese",
"french",
"turkish",
"japanese",
"hindi",
"arabic",
"egyptian",
"levantine",
"hebrew",
"russian",
"chinese",
"german",
"korean",
"urdu",
"telugu",
"tamil",
"malayalam",
"kannada",
"marathi",
"gujarati",
"vietnamese",
"cantonese",
"tagalog",
"greek",
"autodetect",
"watson",
"watsonbritish",
"watsonaustralian",
"watsoncanadian"
],
"type": "string",
"title": "AccentType",
"description": "Enum for accent options."
},
"GenderType": {
"enum": [
"male",
"female"
],
"type": "string",
"title": "GenderType",
"description": "Enum for gender options."
},
"FluencyType": {
"enum": [
"beginner",
"intermediate",
"native"
],
"type": "string",
"title": "FluencyType",
"description": "Enum for fluency level options."
},
"JourneyStep": {
"type": "object",
"title": "JourneyStep",
"required": [
"step"
],
"properties": {
"step": {
"type": "integer",
"title": "Step",
"minimum": 0,
"description": "This leg's position in the journey, counting from 1. Legs run in this order, and the numbers across the list must run 1, 2, 3 with no gaps or repeats."
},
"intent": {
"type": "string",
"title": "Intent",
"default": "",
"description": "What the simulated customer does or wants on this leg, in one short sentence from the customer's side (e.g. 'Follow up about the late order'). Leave the channel out; modality carries it."
},
"modality": {
"enum": [
"voice",
"sms"
],
"type": "string",
"title": "Modality",
"default": "voice",
"description": "Channel for this leg: a phone call, or an SMS exchange. One SMS leg covers the whole back-and-forth, the customer's text and the agent's reply."
},
"direction": {
"anyOf": [
{
"enum": [
"inbound",
"outbound"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Direction",
"default": null,
"description": "Who reaches out first on this leg, seen from the agent: inbound means the customer calls or texts the agent; outbound means the agent places the call or sends the first text. Leave unset to use the agent's own direction. An outbound SMS leg cannot directly follow another SMS leg."
},
"phone_number": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Phone Number",
"default": null,
"description": "Number to call, text, or expect contact from on this leg only, overriding the agent's number. Leave unset to use the run's or the agent's number."
},
"unresponsive": {
"type": "boolean",
"title": "Unresponsive",
"default": false,
"description": "Make the customer deliberately not answer on this leg, to test whether the agent follows up: a voice leg goes to voicemail, and on an SMS leg the customer never texts."
},
"wait_seconds": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Wait Seconds",
"default": null,
"description": "Delay before this leg starts, counted from when the previous leg finished; use it for 'an hour later' or 'the next day'. Values over 72 hours are cut to 72 hours."
},
"success_criteria": {
"type": "string",
"title": "Success Criteria",
"default": "",
"description": "What the AGENT must have done for this leg to count as complete (e.g. 'the agent confirmed the new delivery date'). Describe the agent's outcome, not the customer's action."
},
"response_window_seconds": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Response Window Seconds",
"default": null,
"description": "How long this leg waits for the agent to act (place the call, send the first text) before it ends. Leave unset for the standard step deadline. Values over 72 hours are cut to 72 hours."
}
}
},
"LanguageType": {
"enum": [
"en",
"es",
"pt",
"ja",
"tr",
"hi",
"ar",
"he",
"ru",
"zh",
"ml",
"fr",
"yue",
"vi",
"de",
"ko",
"ur",
"te",
"ta",
"mal",
"kn",
"mr",
"gu",
"tl",
"el",
"ad"
],
"type": "string",
"title": "LanguageType",
"description": "Enum for supported language types."
},
"ResponseType": {
"enum": [
"phrase",
"silence",
"dtmf",
"audio"
],
"type": "string",
"title": "ResponseType",
"description": "Enum for scripted response types."
},
"TraitDataType": {
"enum": [
"BOOLEAN",
"STRING",
"DATE",
"NUMBER"
],
"type": "string",
"title": "TraitDataType",
"description": "Enum for trait data types."
},
"VerbosityType": {
"enum": [
"low",
"medium",
"high"
],
"type": "string",
"title": "VerbosityType",
"description": "Enum for verbosity level options."
},
"OccurrenceMode": {
"enum": [
"always",
"first_n"
],
"type": "string",
"title": "OccurrenceMode",
"description": "Enum for scripted response occurrence modes."
},
"VoiceSpeedType": {
"enum": [
"slowest",
"slow",
"normal",
"fast",
"fastest"
],
"type": "string",
"title": "VoiceSpeedType",
"description": "Enum for voice speed options."
},
"KeywordResponse": {
"type": "object",
"title": "KeywordResponse",
"required": [
"keyword",
"response"
],
"properties": {
"keyword": {
"type": "string",
"title": "Keyword",
"description": "A word or phrase in the agent's speech that makes the digital human cut in, e.g. 'warranty'."
},
"response": {
"type": "string",
"title": "Response",
"description": "What the digital human says when it cuts in on that keyword."
},
"probability": {
"type": "number",
"title": "Probability",
"default": 1,
"maximum": 1,
"minimum": 0,
"description": "Chance the digital human actually cuts in each time the keyword comes up; lower it to make the interruption occasional."
}
},
"description": "Model for a keyword response configuration."
},
"AudioQualityType": {
"enum": [
"high",
"medium",
"low",
"horrible"
],
"type": "string",
"title": "AudioQualityType",
"description": "Enum for audio quality options."
},
"DigitalHumanType": {
"enum": [
"voicemail_custom",
"voicemail_ai",
"replay_smart",
"replay_strict",
"red_team",
"scenario",
"workflow",
"persona",
"journey"
],
"type": "string",
"title": "DigitalHumanType",
"description": "What kind of digital human this is. Stored in test_cases.type; tags are free-form labels."
},
"DtmfOrVoicedType": {
"enum": [
"voiced",
"dtmf"
],
"type": "string",
"title": "DtmfOrVoicedType",
"description": "Enum for DTMF vs voiced input mode."
},
"ExpectedToolCall": {
"type": "object",
"title": "ExpectedToolCall",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "Name of the expected tool call"
},
"output": {
"anyOf": [
{},
{
"type": "null"
}
],
"title": "Output",
"default": null,
"description": "Expected output returned by the tool call"
},
"parameters": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Parameters",
"default": null,
"description": "Expected parameters passed to the tool call"
}
},
"description": "Represents an expected tool call during a conversation."
},
"ScriptedResponse": {
"type": "object",
"title": "ScriptedResponse",
"required": [
"match_type",
"match_phrase",
"response_type",
"occurrence_mode"
],
"properties": {
"match_type": {
"$ref": "#/$defs/MatchType",
"description": "How match_phrase is compared to the agent's turn. 'exact' is a fuzzy string comparison. Use it when you have the agent's literal line from a transcript, since it is stricter and costs no LLM call. 'context' asks an LLM whether the two utterances mean the same thing. Use it when the agent could phrase the same intent several ways."
},
"match_phrase": {
"type": "string",
"title": "Match Phrase",
"description": "An utterance the AGENT would say, which releases this response, e.g. 'Can I have your account number?'. Matching compares utterance to utterance, so a description of what the agent is doing ('the agent finished answering and is inviting another question') never matches anything: the rule saves and silently never fires. Write the line you expect to hear. Empty string is only meaningful when the digital human has scripted_responses_ordered set, where it fires on the digital human's next turn regardless of what the agent said."
},
"occurrence_n": {
"anyOf": [
{
"type": "integer",
"exclusiveMinimum": 0
},
{
"type": "null"
}
],
"title": "Occurrence N",
"default": null,
"description": "How many times this response fires when occurrence_mode is first_n; after that it no longer fires. Leave unset with always."
},
"response_type": {
"$ref": "#/$defs/ResponseType",
"description": "Type of response: 'phrase', 'silence', 'dtmf', or 'audio'"
},
"response_value": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Response Value",
"default": null,
"description": "The response text (required for 'phrase' and 'dtmf', optional for 'silence', unused for 'audio')"
},
"occurrence_mode": {
"$ref": "#/$defs/OccurrenceMode",
"description": "When to apply: 'always' or 'first_n'. Ignored when the digital human has scripted_responses_ordered set, where every step fires exactly once regardless."
},
"silence_duration": {
"anyOf": [
{
"type": "integer",
"exclusiveMinimum": 0
},
{
"type": "null"
}
],
"title": "Silence Duration",
"default": null,
"description": "For a silence response, how many seconds the digital human stays silent. Only used when response_type is silence."
},
"scripted_response_audio_snippet_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Scripted Response Audio Snippet Url",
"default": null,
"description": "Skywatch bucket path of an uploaded audio file. AUDIO rows only — the agent downloads and plays this verbatim."
}
},
"description": "Model for a scripted response configuration."
},
"SpeaksFirstConfig": {
"type": "object",
"title": "SpeaksFirstConfig",
"required": [
"speaks_first"
],
"properties": {
"mode": {
"anyOf": [
{
"enum": [
"custom",
"ai_generated"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Mode",
"default": null,
"description": "How the digital human opens when speaks_first is on: custom says your message word for word; ai_generated lets the digital human compose its own opener. Left unset with speaks_first on, it becomes ai_generated."
},
"dynamic": {
"type": "boolean",
"title": "Dynamic",
"default": true,
"description": "With speaks_first on: wait up to 5s for the agent to open, and speak first only if it stays quiet. If the agent does open, the digital human yields and a custom message is DISCARDED, not spoken after the greeting, so on any agent that greets callers a dynamic custom opener is never heard. Turn it off to say the opener every time, at the top of the call and possibly over the greeting. Configs saved before this setting existed behave as dynamic."
},
"message": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Message",
"default": null,
"description": "The exact opening line the digital human says when mode is custom, e.g. 'Hi, I'm calling about my bill.'"
},
"speaks_first": {
"type": "boolean",
"title": "Speaks First",
"description": "Turn on to have the digital human open the call instead of waiting for the agent's greeting. Turned off, it waits for the agent to speak first, and mode, message and dynamic are cleared."
}
},
"description": "Configuration for whether the digital human speaks first and how.\nStored as JSONB in Supabase (speaks_first_config)."
},
"BackgroundNoiseType": {
"enum": [
"none",
"office",
"talking",
"traffic",
"cafe",
"park",
"tv",
"noisy_restaurant",
"hospital",
"airport",
"birdsong",
"bus_station",
"car_interior",
"city_night",
"city_traffic",
"construction",
"driving",
"factory",
"hotel_lobby",
"hotel_restaurant",
"keyboard_typing",
"light_rain",
"night_insects",
"office_open_plan",
"playground",
"pub",
"quiet_home",
"rain",
"restaurant_busy",
"restaurant_party",
"road_traffic",
"school",
"shopping_centre",
"street",
"subway_station",
"subway_train",
"supermarket",
"thunderstorm",
"train_station",
"urban",
"urban_park",
"wind",
"kitchen",
"living_room",
"meeting_room",
"small_office",
"cafeteria",
"restaurant",
"town_square",
"bus_ride",
"babble_light",
"babble_crowd",
"custom"
],
"type": "string",
"title": "BackgroundNoiseType",
"description": "Enum for background noise options."
},
"SuccessCriterionInput": {
"type": "object",
"title": "SuccessCriterionInput",
"required": [
"text"
],
"properties": {
"id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Id",
"default": null,
"description": "An existing criterion's id. Can be left out: every criterion in the list is saved as a new check with a new id."
},
"text": {
"type": "string",
"title": "Text",
"minLength": 1,
"description": "One pass/fail condition: an observable outcome of the AGENT that the transcript can settle (e.g. 'the agent booked a callback'). Each item is graded as its own check."
}
}
},
"BulkDigitalHumanUpdate": {
"type": "object",
"title": "BulkDigitalHumanUpdate",
"required": [
"digital_human_id",
"update"
],
"properties": {
"update": {
"$ref": "#/$defs/StrictDigitalHumanUpdate",
"description": "Only the fields to change on this digital human; everything omitted keeps its stored value"
},
"digital_human_id": {
"type": "integer",
"title": "Digital Human Id",
"description": "ID of the digital human to update"
}
}
},
"SimpleInterruptionConfig": {
"type": "object",
"title": "Default",
"required": [
"type"
],
"properties": {
"type": {
"enum": [
"none",
"low",
"medium",
"high"
],
"type": "string",
"title": "Type",
"description": "How readily the digital human talks over the agent while the agent is still speaking, from never (none) to most often (high)."
}
},
"description": "Simple interruption configuration with predefined levels."
},
"StrictDigitalHumanUpdate": {
"type": "object",
"title": "StrictDigitalHumanUpdate",
"properties": {
"tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tag",
"default": null,
"description": "Tag for categorizing the digital human"
},
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Name",
"default": null,
"description": "Name of the digital human"
},
"tags": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Tags",
"default": null,
"description": "Full tag list, replacing the current tags; [] clears them. Takes precedence over `tag`, where an empty string leaves tags unchanged."
},
"type": {
"anyOf": [
{
"$ref": "#/$defs/DigitalHumanType"
},
{
"type": "null"
}
],
"default": null,
"description": "What kind of digital human this is. Set it instead of putting sentinel values in tags; tags are free-form labels. Legacy sentinel tags (e.g. 'voicemail-custom', or 'transcript_generated' + 'smart') still set it when this is omitted."
},
"accent": {
"anyOf": [
{
"$ref": "#/$defs/AccentType"
},
{
"type": "null"
}
],
"default": null,
"description": "Accent of the digital human"
},
"gender": {
"anyOf": [
{
"$ref": "#/$defs/GenderType"
},
{
"type": "null"
}
],
"default": null,
"description": "Gender of the digital human"
},
"intent": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Intent",
"default": null,
"description": "The scenario the digital human enacts, in ONE OR TWO SENTENCES: what this caller wants, not how to behave. It fills one slot in a prompt that ALREADY renders traits, verbosity, fluency, a not-the-agent guardrail and end-of-call instructions, so restating those here is duplicate prompt. Anything shaped like 'if the agent says X, do Y' does not belong here — prose makes it non-deterministic. Move it: case facts the agent may ask for (member ID, DOB, order number) to `traits`; lines that must be said verbatim, a keypad entry, or a deliberate pause to `scripted_responses`; who opens the call to `speaks_first_config`; voice and call conditions to their own fields; and lower `creativity` for repeatability. If you reach for 'correctly', 'appropriately' or 'successfully' you are describing what the AGENT should do — that goes in `success_criteria`."
},
"traits": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/Trait"
}
},
{
"type": "null"
}
],
"title": "Traits",
"default": null,
"description": "Case facts THIS CALLER holds and can recite when the agent asks — member ID, DOB, order number, policy number, zip. Traits are the determinism lever: any case-specific value written into `intent` prose should be a trait instead. NOT a place for internal or agent-side information (what the CRM holds, what the agent should say or look up, expected tool arguments, grader notes) — a caller cannot know those, and the schema has no notion of an internal trait. If provided, updates the listed traits. Unlisted traits stay unless traits_mode is \"replace\". Call list_digital_humans or get_digital_human first to read stored traits."
},
"fluency": {
"anyOf": [
{
"$ref": "#/$defs/FluencyType"
},
{
"type": "null"
}
],
"default": null,
"description": "Fluency level of the digital human's speech"
},
"language": {
"anyOf": [
{
"$ref": "#/$defs/LanguageType"
},
{
"type": "null"
}
],
"default": null,
"description": "Language the digital human speaks"
},
"num_runs": {
"anyOf": [
{
"type": "integer",
"minimum": 1
},
{
"type": "null"
}
],
"title": "Num Runs",
"default": null,
"description": "How many separate calls this digital human makes each time its simulation runs. Raise it to see how consistently the agent handles the same case."
},
"extension": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Extension",
"default": null,
"description": "Extension dialed as DTMF after connecting when this DH calls an inbound agent. Send null or an empty string to clear it."
},
"test_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Test Name",
"default": null,
"description": "Short label identifying this test case in lists and run results. It must be unique in the organization; a label another digital human uses is rejected. Different from name, the caller's own name."
},
"verbosity": {
"anyOf": [
{
"$ref": "#/$defs/VerbosityType"
},
{
"type": "null"
}
],
"default": null,
"description": "Verbosity level of the digital human's responses"
},
"creativity": {
"anyOf": [
{
"type": "number",
"maximum": 2,
"minimum": 0
},
{
"type": "null"
}
],
"title": "Creativity",
"default": null,
"description": "How much the digital human varies its own wording (the model temperature for its speech). Lower it when you want the same call twice, for regression tests and anything compared run over run; keep it higher for exploratory or red-team cases."
},
"attack_plan": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Attack Plan",
"default": null,
"description": "For a red-team digital human, its escalation plan: the objective, the condition that counts as a breach (breach_predicate), and the ladder of escalating steps."
},
"attack_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Attack Type",
"default": null,
"description": "For a red-team digital human, its broad attack family. Normally derived from attack_vector. A value you send is kept if it is recon, or if no vector decides the family and it is one of social_engineering, prompt_injection, text_native, audio_native or content_harm."
},
"tested_path": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Tested Path",
"default": null,
"description": "Names of the workflow steps along the path this digital human walks, in order. Recorded when a digital human is generated from a workflow path."
},
"traits_mode": {
"anyOf": [
{
"enum": [
"replace",
"merge"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Traits Mode",
"default": null,
"description": "How `traits` apply when you send traits on an update. Omitted or \"merge\" upserts only the listed traits by trait_name and keeps every other stored trait. \"replace\" deletes all stored traits first, then writes only the list — use this to remove traits or to set the full trait set from scratch."
},
"voice_speed": {
"anyOf": [
{
"$ref": "#/$defs/VoiceSpeedType"
},
{
"type": "null"
}
],
"default": null,
"description": "Speed of the digital human's voice"
},
"phone_number": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Phone Number",
"default": null,
"description": "Phone number for the digital human"
},
"attack_vector": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Attack Vector",
"default": null,
"description": "For a red-team digital human, the attack tactic it uses, as a tactic key such as partial_info_bluff, sympathy_pressure or authority_impersonation. An unknown key is dropped."
},
"audio_quality": {
"anyOf": [
{
"$ref": "#/$defs/AudioQualityType"
},
{
"type": "null"
}
],
"default": null,
"description": "Audio quality of the digital human's voice"
},
"interruptions": {
"anyOf": [
{
"$ref": "#/$defs/SimpleInterruptionConfig"
},
{
"$ref": "#/$defs/KeywordsInterruptionConfig"
},
{
"$ref": "#/$defs/ContextualInterruptionConfig"
},
{
"type": "null"
}
],
"title": "Interruptions",
"default": null,
"description": "Interruption configuration for the digital human. If provided, completely replaces existing interruption config."
},
"journey_steps": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/JourneyStep"
}
},
{
"type": "null"
}
],
"title": "Journey Steps",
"default": null,
"description": "Ordered journey steps. If provided, completely replaces existing journey steps."
},
"always_on_mode": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Always On Mode",
"default": null,
"description": "Make this an always-on digital human: it answers calls arriving on its phone_number at any time, not only when a run dials out. Digital humans in an always-on simulation need it on."
},
"hangup_phrases": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Hangup Phrases",
"default": null,
"description": "Phrases that trigger hangup"
},
"simulation_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "integer"
}
},
{
"type": "null"
}
],
"title": "Simulation Ids",
"default": null,
"description": "Array of simulation IDs to associate with this digital human. If provided, completely replaces existing associations."
},
"workflow_v2_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Workflow V2 Id",
"default": null,
"description": "The scenario-builder workflow (id from list_workflows) this digital human walks a path of. Set together with workflow_path_index and tested_path."
},
"allow_dtmf_tool": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Allow Dtmf Tool",
"default": null,
"description": "Allow the digital human to use the DTMF tool"
},
"custom_voice_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Custom Voice Id",
"default": null,
"description": "ElevenLabs voice_id of a cloned voice. Send empty string or null to clear and revert to the stock accent voice."
},
"silence_timeout": {
"anyOf": [
{
"type": "integer",
"minimum": 15
},
{
"type": "null"
}
],
"title": "Silence Timeout",
"default": null,
"description": "Silence timeout in seconds"
},
"always_on_active": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Always On Active",
"default": null,
"description": "Whether this always-on digital human is live on phone_number and picks up calls arriving there. Turned off, the number stays assigned but is not answered."
},
"background_noise": {
"anyOf": [
{
"$ref": "#/$defs/BackgroundNoiseType"
},
{
"type": "null"
}
],
"default": null,
"description": "Type of background noise"
},
"livekit_metadata": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Livekit Metadata",
"default": null,
"description": "Key-value metadata kept with this digital human for agents connected over LiveKit. Sending it replaces the stored metadata."
},
"role_description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Role Description",
"default": null,
"description": "Who this caller is and how they come across, e.g. 'retiree on a family plan, not comfortable with phone menus'. What they are calling about belongs in `intent`, the facts they can recite in `traits`, how they sound in language/accent/fluency/verbosity. Never internal or agent-side information: the digital human only knows what a real caller would know."
},
"success_criteria": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/SuccessCriterionInput"
}
]
}
},
{
"type": "null"
}
],
"title": "Success Criteria",
"default": null,
"description": "The pass/fail condition for this one test. v1: a string. Also accepts [{id, text}, ...] — sending the field replaces the whole list."
},
"endpointing_delay": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "Endpointing Delay",
"default": null,
"description": "Seconds the digital human waits before it replies. Named patience in the UI, and accepted under either name."
},
"enriched_playback": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
{
"type": "null"
}
],
"title": "Enriched Playback",
"default": null,
"description": "Optional enriched playback stored as JSONB: a list of turn objects"
},
"override_conflict": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Override Conflict",
"default": false,
"description": "Take phone_number over from another always-on digital human that is live on it. Send it when retrying an item that failed with 409 ALWAYS_ON_PHONE_CONFLICT; the other digital human loses the number."
},
"allow_silence_tool": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Allow Silence Tool",
"default": null,
"description": "Allow the digital human to use the silence tool"
},
"scripted_responses": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/ScriptedResponse"
}
},
{
"type": "null"
}
],
"title": "Scripted Responses",
"default": null,
"description": "The 'if the agent says X, the caller does Y' rules for this test, as data instead of prose — a verbatim line, a keypad entry (DTMF), or a deliberate silence. Writing the same rule into `intent` makes it advisory; putting it here makes it deterministic. If provided, completely replaces existing scripted responses."
},
"allow_end_call_tool": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Allow End Call Tool",
"default": null,
"description": "Allow the digital human to end the tool call"
},
"expected_tool_calls": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/ExpectedToolCall"
}
},
{
"type": "null"
}
],
"title": "Expected Tool Calls",
"default": null,
"description": "Expected tool call outputs"
},
"hangup_instructions": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Hangup Instructions",
"default": null,
"description": "When and how the digital human ends the call, in your own words. The built-in end-of-call behavior already handles ordinary goodbyes and any text here REPLACES it, so write instructions only for a condition it would miss. Send \"default\" to go back to the built-in behavior."
},
"original_transcript": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Original Transcript",
"default": null,
"description": "Original transcript text. If changed from the current value, utterances are re-extracted and the intent is regenerated."
},
"speaks_first_config": {
"anyOf": [
{
"$ref": "#/$defs/SpeaksFirstConfig"
},
{
"type": "null"
}
],
"default": null,
"description": "Who opens the call, and the caller's opening line when it must be fixed — owns the opener so `intent` does not have to describe it. Read the `dynamic` field before setting a custom message: on an agent that greets callers, a dynamic custom opener is discarded. If provided, completely replaces existing speaks first config."
},
"workflow_path_index": {
"anyOf": [
{
"type": "integer",
"minimum": 0
},
{
"type": "null"
}
],
"title": "Workflow Path Index",
"default": null,
"description": "Which path through that workflow this digital human walks, counting from 0 in the order Bluejay enumerates the workflow's paths."
},
"formatted_transcript": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
{
"type": "null"
}
],
"title": "Formatted Transcript",
"default": null,
"description": "The original_transcript already split into turns, each with a role (USER for the caller, AGENT for the agent) and an utterance. Send it alongside original_transcript to skip Bluejay's LLM formatting step."
},
"outbound_text_number": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Outbound Text Number",
"default": null,
"description": "Outbound text number"
},
"provider_request_data": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Provider Request Data",
"default": null,
"description": "Variables this digital human hands the voice platform when the call is placed: Bland request_data, Vapi variableValues or Retell dynamic variables. They override the agent's template values. Sending it replaces the stored set; send {} to clear it."
},
"default_dtmf_or_voiced": {
"anyOf": [
{
"$ref": "#/$defs/DtmfOrVoicedType"
},
{
"type": "null"
}
],
"default": null,
"description": "Controls whether the agent submits numerical values via DTMF or voice. 'voiced' = speak numbers (default), 'dtmf' = use DTMF tones for eligible numerical inputs"
},
"system_prompt_rule_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "System Prompt Rule Ids",
"default": null,
"description": "Ids of the agent version's locked system-prompt rules this digital human tests. generate_digital_humans fills them in when it generates with system_prompt."
},
"background_noise_volume": {
"anyOf": [
{
"type": "number",
"maximum": 1,
"minimum": 0
},
{
"type": "null"
}
],
"title": "Background Noise Volume",
"default": null,
"description": "Volume of background noise"
},
"silence_tool_instructions": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Silence Tool Instructions",
"default": null,
"description": "Tool instructions; set to \"default\" for built-in behavior or custom text"
},
"system_prompt_rule_quotes": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "System Prompt Rule Quotes",
"default": null,
"description": "The wording of the rules this digital human tests, quoted from the agent's prompt and shown on its card."
},
"scripted_responses_ordered": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Scripted Responses Ordered",
"default": null,
"description": "Run scripted_responses as a script in list order: only the next unfired one is armed, each fires once, and a blank match_phrase fires on the digital human's next turn. Turned off, any scripted response fires whenever its match_phrase comes up."
},
"custom_background_noise_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Custom Background Noise Url",
"default": null,
"description": "Bucket-relative path of the uploaded custom background noise audio; required when background_noise is 'custom'"
},
"follow_up_sms_success_criteria": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Follow Up Sms Success Criteria",
"default": null,
"description": "Criteria the captured follow-up SMS is graded against"
}
},
"additionalProperties": false
},
"KeywordsInterruptionConfig": {
"type": "object",
"title": "Keywords",
"required": [
"type",
"keyword_responses"
],
"properties": {
"type": {
"type": "string",
"const": "keywords",
"title": "Type",
"description": "Selects keyword interruptions: the digital human cuts in only when the agent says one of the keywords in keyword_responses."
},
"keyword_responses": {
"type": "array",
"items": {
"$ref": "#/$defs/KeywordResponse"
},
"title": "Keyword Responses",
"description": "The keywords to listen for in the agent's speech, each with what the digital human says when it cuts in."
}
},
"description": "Keywords-based interruption configuration."
},
"ContextualInterruptionConfig": {
"type": "object",
"title": "Contextual",
"required": [
"type",
"contextual_prompt"
],
"properties": {
"type": {
"type": "string",
"const": "contextual",
"title": "Type",
"description": "Type discriminator for contextual interruption"
},
"contextual_prompt": {
"type": "string",
"title": "Contextual Prompt",
"description": "Contextual prompt for LLM-based interruptions"
}
},
"description": "Contextual/LLM-based interruption configuration."
}
},
"title": "update_digital_humansArguments",
"required": [
"updates"
],
"properties": {
"updates": {
"type": "array",
"items": {
"$ref": "#/$defs/BulkDigitalHumanUpdate"
},
"title": "Updates",
"description": "One entry per digital human to change: its digital_human_id and an update holding only the fields to change. Each digital_human_id may appear once per call."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"errors": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"description": "Items that failed; every other item was still updated. Each has digital_human_id, status_code (e.g. 404 not found, 409 ALWAYS_ON_PHONE_CONFLICT) and detail (why it failed).",
"additionalProperties": true
},
"updated_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"string",
"null"
]
},
"description": "Ids of the digital humans that were updated; read one back with get_digital_human."
},
"updated_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "How many digital humans were updated."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Overwrite the simulation membership of up to 100 digital humans in ONE call.
Membership-only wrapper over update_digital_humans. This REPLACES, not
appends: each listed digital human ends up in exactly `simulation_ids`, and
is removed from every simulation not in that list. Pass [] to detach them
from all simulations. Their other settings are untouched.
Returns updated_count, updated_ids and per-item errors (one digital human
can fail, e.g. not found, while the rest are updated).
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
digital_human_ids
The digital humans to re-assign (ids from list_digital_humans). A repeated id is sent once.
Clear enough to supply this argument.
simulation_ids
The complete set of simulations (ids from list_simulations) every listed digital human belongs to afterwards. Pass [] to detach them from every simulation.
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"errors": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"description": "Items that failed; every other item was still updated. Each has digital_human_id, status_code (e.g. 404 not found, 409 ALWAYS_ON_PHONE_CONFLICT) and detail (why it failed).",
"additionalProperties": true
},
"updated_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"string",
"null"
]
},
"description": "Ids of the digital humans that were updated; read one back with get_digital_human."
},
"updated_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "How many digital humans were updated."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "bulk_set_digital_human_simulations",
"title": "Bulk set digital human simulations",
"description": "Overwrite the simulation membership of up to 100 digital humans in ONE call.\n\nMembership-only wrapper over update_digital_humans. This REPLACES, not\nappends: each listed digital human ends up in exactly `simulation_ids`, and\nis removed from every simulation not in that list. Pass [] to detach them\nfrom all simulations. Their other settings are untouched.\n\nReturns updated_count, updated_ids and per-item errors (one digital human\ncan fail, e.g. not found, while the rest are updated).\n",
"inputSchema": {
"type": "object",
"title": "bulk_set_digital_human_simulationsArguments",
"required": [
"digital_human_ids",
"simulation_ids"
],
"properties": {
"simulation_ids": {
"type": "array",
"items": {
"type": "integer"
},
"title": "Simulation Ids",
"description": "The complete set of simulations (ids from list_simulations) every listed digital human belongs to afterwards. Pass [] to detach them from every simulation."
},
"digital_human_ids": {
"type": "array",
"items": {
"type": "integer"
},
"title": "Digital Human Ids",
"description": "The digital humans to re-assign (ids from list_digital_humans). A repeated id is sent once."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"errors": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"description": "Items that failed; every other item was still updated. Each has digital_human_id, status_code (e.g. 404 not found, 409 ALWAYS_ON_PHONE_CONFLICT) and detail (why it failed).",
"additionalProperties": true
},
"updated_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"string",
"null"
]
},
"description": "Ids of the digital humans that were updated; read one back with get_digital_human."
},
"updated_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "How many digital humans were updated."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Read one digital human's complete stored configuration (GET /v1/digital-human/{digital_human_id}). Read-only.
Returns digital_human with everything list_digital_humans abbreviates:
intent, success_criteria, traits, scripted_responses, expected_tool_calls,
voice and audio settings, speaks_first_config, interruptions, hangup
settings, transcripts, journey_steps, phone number and always-on state,
plus simulation_ids (the simulations it belongs to). Read it before
update_digital_humans to see the values you are about to change. For the
calls it has made, use get_digital_human_run_history.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
digital_human_id
The digital human to read: its id, from list_digital_humans or create_digital_humans.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Every call one digital human has made, newest first, via Bluejay GET /v1/digital-human/{digital_human_id}/run-history.
Returns totals (simulations, simulation_runs, calls, passed, failed, success_rate) over all
calls, plus one page of calls with simulation, agent, run id, duration and outcome
(true passed, false failed, null not graded). limit max 1000; page with offset until
offset + limit >= totals.calls. Use get_simulation_result with a call_id for its transcript.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
digital_human_id
The digital human whose calls to list: its id, from list_digital_humans or get_digital_human.
Clear enough to supply this argument.
limit
How many calls to return in this page.
Clear enough to supply this argument.
offset
How many of the newest calls to skip. Page by adding limit until offset + limit reaches totals.calls.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Generate a batch of new digital humans for an agent with an LLM and save them (POST /v1/generate-digital-humans).
Writes new digital humans to the org, each given a random phone number from
the org's pool (the org needs at least one), and attaches them to
simulation_id when given. goal_adherence can also add goals to the agent.
Requires an active usage entitlement. Generation quality is bounded by the
agent context it reads, so make sure the agent's description and workflow
are accurate first. Returns the saved digital_humans and a warning when the
request was cut to the per-call maximum.
Three rules a good digital human follows (docs: /key-concepts/digital-humans/best-practices):
1. intent and success_criteria stay one or two sentences. Detail that grows them belongs
elsewhere: configuration for the caller, a custom metric for the grading.
2. Every "if the agent says X, the caller does Y" moves out of prose into a field —
traits for case facts the caller recites, scripted_responses for verbatim lines / DTMF /
silence, speaks_first_config for the opener, and lower creativity for repeatability.
3. Ground the case in the agent's real context (get_agent, get_workflow_summary) so the
scenario resembles a call this agent actually takes.
system_prompt generates from the agent version's locked prompt rules instead of a brief. Each
rule is tested from both sides, so full coverage is two digital humans per rule: one caller the
agent must help, one it must push back on. Pass an even number; a lower one covers fewer rules
rather than half-testing every rule.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent under test (id from list_agents). Generation reads this agent's prompt.
Clear enough to supply this argument.
count
How many digital humans to generate when no mode count is given: it is then used as load_testing. Ignored once any of goal_adherence, workflow_adherence, replay_transcript, load_testing, system_prompt or red_teaming is set, since each of those carries its own count.
Clear enough to supply this argument.
simulation_id
Simulation (id from list_simulations) to attach the generated digital humans to. It must belong to agent_id.
Clear enough to supply this argument.
prompt_id
The agent version to generate from (id from list_prompts). Left out, the agent's latest version is used.
Clear enough to supply this argument.
knowledge_base_id
Accepted for older callers but not read by generation; leave it out.
Clear enough to supply this argument.
$defs › GoalAdherence › goal
A goal callers bring to this agent, in one or two sentences from the caller's side (e.g. 'reschedule an existing appointment'). A goal the agent does not list yet is added to the agent's goals.
Clear enough to supply this argument.
$defs › GoalAdherence › num_calls
How many digital humans to generate for this goal.
Clear enough to supply this argument.
workflow_adherence
Map of legacy workflow id to how many digital humans should follow that workflow. These are the older workflows, not the scenario-builder workflows from list_workflows; unknown ids are skipped.
Clear enough to supply this argument.
$defs › ReplayTranscriptFromText › transcript
The full text of a past call to rebuild as a digital human; Bluejay splits it into caller and agent turns itself.
Pass/fail condition for the replayed call. Left out, Bluejay writes one from the transcript and the agent's prompt.
Clear enough to supply this argument.
$defs › ReplayTranscriptFromText › mode
How closely the digital human follows the original call: strict says the caller's original lines exactly; smart reuses them where they still fit and improvises when the agent goes a different way; persona keeps only the caller's situation and goal and speaks in its own words.
Pass/fail condition for the replayed call. Left out, Bluejay writes one from the transcript and the agent's prompt.
Clear enough to supply this argument.
$defs › ReplayTranscriptFromConversation › mode
How closely the digital human follows the original call: strict says the caller's original lines exactly; smart reuses them where they still fit and improvises when the agent goes a different way; persona keeps only the caller's situation and goal and speaks in its own words.
Clear enough to supply this argument.
load_testing
How many load-test digital humans to make: copies of one generic caller scenario, for running the agent at volume.
Clear enough to supply this argument.
system_prompt
Number of digital humans to generate from the agent version's locked system-prompt rules. Each rule is tested from both sides, so this is two per rule and must be even: one caller the agent must help, one it must push back on. A lower number covers fewer rules rather than half-testing every rule.
Clear enough to supply this argument.
red_teaming
How many red-team digital humans to make: adversarial callers that try to push the agent outside its rules.
Clear enough to supply this argument.
$defs › Trait › trait_name
The fact's name, as the agent would ask for it (e.g. member_id, date_of_birth, order_number). Trait names are shared across the organization, so reuse an existing name rather than coining a variant. A trait is always something the CALLER knows and can say out loud, never internal or agent-side information (CRM contents, what the agent should look up or say, grader notes).
Clear enough to supply this argument.
$defs › Trait › trait_data_type
What kind of fact `value` holds: yes/no, free text, a calendar date written as an ISO 8601 string, or a number. `value` is converted to this kind when saved, so '42' or 'yes' is accepted.
Clear enough to supply this argument.
$defs › Trait › value
The concrete value this caller gives (stored as JSONB). Fixing it here is what makes the call repeatable — leave it out of `intent` prose, where the model would improvise a different one each run.
Clear enough to supply this argument.
$defs › Trait › is_sip_header
Send this fact as a SIP header on the call instead of as something the caller says aloud. Use it only when the agent reads the value from call metadata; ordinary case facts stay spoken.
Clear enough to supply this argument.
num_runs
How many times each generated digital human runs every time its simulation runs.
Clear enough to supply this argument.
language
Adds a trait named language with this value to every generated digital human. Their voice itself is generated with language auto-detect.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Status code of the generation, as a string."
},
"success": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when generation finished."
},
"warning": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Set when the request asked for more digital humans than the per-call maximum and was cut down."
},
"digital_humans": {
"type": [
"array",
"object",
"null"
],
"items": {},
"properties": {},
"description": "The digital humans that were generated and saved, each with id, name, intent, success_criteria, tags, traits and phone_number. Pass an id to get_digital_human or update_digital_humans.",
"additionalProperties": true
},
"test_scenarios": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The scenario behind each generated digital human, in the same order: intent, success criteria and, for transcript replays, original_transcript and formatted_transcript."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "generate_digital_humans",
"title": "Generate digital humans",
"description": "Generate a batch of new digital humans for an agent with an LLM and save them (POST /v1/generate-digital-humans).\n\nWrites new digital humans to the org, each given a random phone number from\nthe org's pool (the org needs at least one), and attaches them to\nsimulation_id when given. goal_adherence can also add goals to the agent.\nRequires an active usage entitlement. Generation quality is bounded by the\nagent context it reads, so make sure the agent's description and workflow\nare accurate first. Returns the saved digital_humans and a warning when the\nrequest was cut to the per-call maximum.\n\nThree rules a good digital human follows (docs: /key-concepts/digital-humans/best-practices):\n1. intent and success_criteria stay one or two sentences. Detail that grows them belongs\n elsewhere: configuration for the caller, a custom metric for the grading.\n2. Every \"if the agent says X, the caller does Y\" moves out of prose into a field —\n traits for case facts the caller recites, scripted_responses for verbatim lines / DTMF /\n silence, speaks_first_config for the opener, and lower creativity for repeatability.\n3. Ground the case in the agent's real context (get_agent, get_workflow_summary) so the\n scenario resembles a call this agent actually takes.\n\nsystem_prompt generates from the agent version's locked prompt rules instead of a brief. Each\nrule is tested from both sides, so full coverage is two digital humans per rule: one caller the\nagent must help, one it must push back on. Pass an even number; a lower one covers fewer rules\nrather than half-testing every rule.\n",
"inputSchema": {
"type": "object",
"$defs": {
"Trait": {
"type": "object",
"title": "Trait",
"required": [
"trait_name",
"trait_data_type",
"value"
],
"properties": {
"value": {
"title": "Value",
"description": "The concrete value this caller gives (stored as JSONB). Fixing it here is what makes the call repeatable — leave it out of `intent` prose, where the model would improvise a different one each run."
},
"trait_name": {
"type": "string",
"title": "Trait Name",
"description": "The fact's name, as the agent would ask for it (e.g. member_id, date_of_birth, order_number). Trait names are shared across the organization, so reuse an existing name rather than coining a variant. A trait is always something the CALLER knows and can say out loud, never internal or agent-side information (CRM contents, what the agent should look up or say, grader notes)."
},
"is_sip_header": {
"type": "boolean",
"title": "Is Sip Header",
"default": false,
"description": "Send this fact as a SIP header on the call instead of as something the caller says aloud. Use it only when the agent reads the value from call metadata; ordinary case facts stay spoken."
},
"trait_data_type": {
"$ref": "#/$defs/TraitDataType",
"description": "What kind of fact `value` holds: yes/no, free text, a calendar date written as an ISO 8601 string, or a number. `value` is converted to this kind when saved, so '42' or 'yes' is accepted."
}
},
"description": "Model for a single trait."
},
"GoalAdherence": {
"type": "object",
"title": "GoalAdherence",
"required": [
"goal",
"num_calls"
],
"properties": {
"goal": {
"type": "string",
"title": "Goal",
"description": "A goal callers bring to this agent, in one or two sentences from the caller's side (e.g. 'reschedule an existing appointment'). A goal the agent does not list yet is added to the agent's goals."
},
"num_calls": {
"type": "integer",
"title": "Num Calls",
"description": "How many digital humans to generate for this goal."
}
},
"description": "Goal adherence scenario for batch digital human generation."
},
"TraitDataType": {
"enum": [
"BOOLEAN",
"STRING",
"DATE",
"NUMBER"
],
"type": "string",
"title": "TraitDataType",
"description": "Enum for trait data types."
},
"ReplayTranscriptFromText": {
"type": "object",
"title": "Replay Transcript From Text",
"required": [
"transcript"
],
"properties": {
"mode": {
"enum": [
"strict",
"smart",
"persona"
],
"type": "string",
"title": "Mode",
"default": "smart",
"description": "How closely the digital human follows the original call: strict says the caller's original lines exactly; smart reuses them where they still fit and improvises when the agent goes a different way; persona keeps only the caller's situation and goal and speaks in its own words."
},
"transcript": {
"type": "string",
"title": "Transcript",
"description": "The full text of a past call to rebuild as a digital human; Bluejay splits it into caller and agent turns itself."
},
"success_criteria": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Success Criteria",
"default": null,
"description": "Pass/fail condition for the replayed call. Left out, Bluejay writes one from the transcript and the agent's prompt."
}
},
"description": "Replay transcript by providing the transcript text directly."
},
"ReplayTranscriptFromConversation": {
"type": "object",
"title": "Replay Transcript From Conversation ID",
"required": [
"conversation_id"
],
"properties": {
"mode": {
"enum": [
"strict",
"smart",
"persona"
],
"type": "string",
"title": "Mode",
"default": "smart",
"description": "How closely the digital human follows the original call: strict says the caller's original lines exactly; smart reuses them where they still fit and improvises when the agent goes a different way; persona keeps only the caller's situation and goal and speaks in its own words."
},
"conversation_id": {
"type": "string",
"title": "Conversation Id",
"description": "A production conversation to replay (id from list_conversations); its transcript is loaded for you."
},
"success_criteria": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Success Criteria",
"default": null,
"description": "Pass/fail condition for the replayed call. Left out, Bluejay writes one from the transcript and the agent's prompt."
}
},
"description": "Replay transcript by referencing an existing conversation ID."
}
},
"title": "generate_digital_humansArguments",
"required": [
"agent_id",
"count"
],
"properties": {
"count": {
"type": "integer",
"title": "Count",
"description": "How many digital humans to generate when no mode count is given: it is then used as load_testing. Ignored once any of goal_adherence, workflow_adherence, replay_transcript, load_testing, system_prompt or red_teaming is set, since each of those carries its own count."
},
"traits": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/Trait"
}
},
{
"type": "null"
}
],
"title": "Traits",
"default": null,
"description": "Case facts applied to EVERY generated digital human — the fixtures the whole batch shares (e.g. a test account number). Per-caller facts belong on the individual digital human, and neither place takes internal or agent-side information: a trait is always something a real caller could recite."
},
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "The agent under test (id from list_agents). Generation reads this agent's prompt."
},
"language": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Language",
"default": null,
"description": "Adds a trait named language with this value to every generated digital human. Their voice itself is generated with language auto-detect."
},
"num_runs": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Num Runs",
"default": null,
"description": "How many times each generated digital human runs every time its simulation runs."
},
"prompt_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Prompt Id",
"default": null,
"description": "The agent version to generate from (id from list_prompts). Left out, the agent's latest version is used."
},
"red_teaming": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Red Teaming",
"default": null,
"description": "How many red-team digital humans to make: adversarial callers that try to push the agent outside its rules."
},
"load_testing": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Load Testing",
"default": null,
"description": "How many load-test digital humans to make: copies of one generic caller scenario, for running the agent at volume."
},
"simulation_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Simulation Id",
"default": null,
"description": "Simulation (id from list_simulations) to attach the generated digital humans to. It must belong to agent_id."
},
"system_prompt": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "System Prompt",
"default": null,
"description": "Number of digital humans to generate from the agent version's locked system-prompt rules. Each rule is tested from both sides, so this is two per rule and must be even: one caller the agent must help, one it must push back on. A lower number covers fewer rules rather than half-testing every rule."
},
"goal_adherence": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/GoalAdherence"
}
},
{
"type": "null"
}
],
"title": "Goal Adherence",
"default": null,
"description": "Caller goals to generate digital humans for, each with how many to make. A goal the agent does not list yet is also added to the agent's goals."
},
"knowledge_base_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Knowledge Base Id",
"default": null,
"description": "Accepted for older callers but not read by generation; leave it out."
},
"replay_transcript": {
"anyOf": [
{
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/$defs/ReplayTranscriptFromText"
},
{
"$ref": "#/$defs/ReplayTranscriptFromConversation"
}
]
}
},
{
"type": "null"
}
],
"title": "Replay Transcript",
"default": null,
"description": "Past calls to rebuild as digital humans. Each entry gives either the transcript text or a production conversation_id (from list_conversations), plus how closely to replay it."
},
"workflow_adherence": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "integer"
}
},
{
"type": "null"
}
],
"title": "Workflow Adherence",
"default": null,
"description": "Map of legacy workflow id to how many digital humans should follow that workflow. These are the older workflows, not the scenario-builder workflows from list_workflows; unknown ids are skipped."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Status code of the generation, as a string."
},
"success": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when generation finished."
},
"warning": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Set when the request asked for more digital humans than the per-call maximum and was cut down."
},
"digital_humans": {
"type": [
"array",
"object",
"null"
],
"items": {},
"properties": {},
"description": "The digital humans that were generated and saved, each with id, name, intent, success_criteria, tags, traits and phone_number. Pass an id to get_digital_human or update_digital_humans.",
"additionalProperties": true
},
"test_scenarios": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The scenario behind each generated digital human, in the same order: intent, success criteria and, for transcript replays, original_transcript and formatted_transcript."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Delete one digital human (DELETE /v1/digital-human/{digital_human_id}).
Moves it to Recently Deleted: it drops out of every simulation it belonged
to at once, and any simulation left with no digital humans has its schedule
turned off. It can be restored from
Recently Deleted in the app for 30 days; after that it is purged for good.
A digital human that is already deleted or not found returns an error.
Returns deleted=true and digital_human_id, plus the deleted digital human's
last stored configuration (id, name, intent, success_criteria, tags, voice
settings, traits and the rest) at the top level.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
digital_human_id
The digital human to delete: its id, from list_digital_humans or get_digital_human.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Create a new digital human as a full server-side copy of an existing one (POST /v1/digital-human/{id}/duplicate).
Copies the cloned voice, custom/ambience background noise, interruption and
speaks-first configs, transcripts, audio quirks, traits, scripted responses
and expected tool calls, without re-validating them. The original is not
changed. The copy starts without a phone number and with always-on
inactive: assign one with update_digital_humans(phone_number=...,
always_on_active=True).
Returns digital_human_id (the new copy's id), source_digital_human_id, and
the copy's full configuration under digital_human with its simulation_ids.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
digital_human_id
The digital human to copy: its id, from list_digital_humans or get_digital_human.
Clear enough to supply this argument.
name
Name for the copy. Left out or blank, the copy is named "<original name> (Copy)".
Clear enough to supply this argument.
simulation_ids
Simulations (ids from list_simulations) the copy belongs to. Left out, the copy joins the same simulations as the original; pass [] to leave it in none.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
List digital humans in your organization via Bluejay GET /v1/digital-humans (paginated).
Digital humans are org-wide and exist independently of simulations, so the
default listing is every digital human in the org — use it to discover existing
ones before creating new ones. `simulation_id` narrows the listing to the
digital humans already attached to that one simulation; that filtered form
ignores page/page_size and returns only id/intent/success_criteria/traits per row.
`type` keeps only digital humans of that type, `tag` only those carrying that exact tag.
Otherwise returns per-DH summaries (with traits) plus total_count/page/total_pages; page
through until page == total_pages (page_size max 100). Use get_digital_human
for one DH's full config.
The description explains the capability, when to use it, and what to expect.
Inputs85/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page
Page number (1-based)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page_size
Max digital humans per page
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
simulation_id
Only list the digital humans attached to this simulation (id from list_simulations). This form returns every match at once and ignores page, page_size, type and tag.
Clear enough to supply this argument.
type
Only digital humans of this type
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"properties": {
"page": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The page returned (1-based)."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"page_size": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Page size used."
},
"total_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Digital humans matching the filters across all pages."
},
"total_pages": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Number of pages; keep paging until page equals this."
},
"digital_humans": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"null"
],
"properties": {
"id": {
"type": [
"integer",
"string",
"number",
"null"
],
"description": "The digital human's id."
},
"intent": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What this simulated caller wants."
},
"traits": {
"type": [
"array",
"object",
"null"
],
"description": "Case facts it carries, each with trait_name, trait_data_type, value and is_sip_header."
},
"success_criteria": {
"type": [
"string",
"array",
"integer",
"number",
"object",
"null"
],
"description": "The pass/fail condition for its calls."
}
},
"additionalProperties": true
},
"description": "One summary per digital human: id, name, test_name, intent, success_criteria, tags, type, phone_number, voice and audio settings, creativity, created_at and traits. With simulation_id, only id, intent, success_criteria and traits, and no paging keys. Pass an id to get_digital_human for the full configuration."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "list_digital_humans",
"title": "List digital humans",
"description": "List digital humans in your organization via Bluejay GET /v1/digital-humans (paginated).\n\nDigital humans are org-wide and exist independently of simulations, so the\ndefault listing is every digital human in the org — use it to discover existing\nones before creating new ones. `simulation_id` narrows the listing to the\ndigital humans already attached to that one simulation; that filtered form\nignores page/page_size and returns only id/intent/success_criteria/traits per row.\n`type` keeps only digital humans of that type, `tag` only those carrying that exact tag.\nOtherwise returns per-DH summaries (with traits) plus total_count/page/total_pages; page\nthrough until page == total_pages (page_size max 100). Use get_digital_human\nfor one DH's full config.\n",
"inputSchema": {
"type": "object",
"$defs": {
"DigitalHumanType": {
"enum": [
"voicemail_custom",
"voicemail_ai",
"replay_smart",
"replay_strict",
"red_team",
"scenario",
"workflow",
"persona",
"journey"
],
"type": "string",
"title": "DigitalHumanType",
"description": "What kind of digital human this is. Stored in test_cases.type; tags are free-form labels."
}
},
"title": "list_digital_humansArguments",
"properties": {
"tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Tag",
"default": null,
"description": "Only digital humans carrying this exact tag"
},
"page": {
"type": "integer",
"title": "Page",
"default": 1,
"description": "Page number (1-based)"
},
"type": {
"anyOf": [
{
"$ref": "#/$defs/DigitalHumanType"
},
{
"type": "null"
}
],
"default": null,
"description": "Only digital humans of this type"
},
"page_size": {
"type": "integer",
"title": "Page Size",
"default": 20,
"description": "Max digital humans per page"
},
"simulation_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Simulation Id",
"default": null,
"description": "Only list the digital humans attached to this simulation (id from list_simulations). This form returns every match at once and ignores page, page_size, type and tag."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"page": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The page returned (1-based)."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"page_size": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Page size used."
},
"total_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Digital humans matching the filters across all pages."
},
"total_pages": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Number of pages; keep paging until page equals this."
},
"digital_humans": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"null"
],
"properties": {
"id": {
"type": [
"integer",
"string",
"number",
"null"
],
"description": "The digital human's id."
},
"intent": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What this simulated caller wants."
},
"traits": {
"type": [
"array",
"object",
"null"
],
"description": "Case facts it carries, each with trait_name, trait_data_type, value and is_sip_header."
},
"success_criteria": {
"type": [
"string",
"array",
"integer",
"number",
"object",
"null"
],
"description": "The pass/fail condition for its calls."
}
},
"additionalProperties": true
},
"description": "One summary per digital human: id, name, test_name, intent, success_criteria, tags, type, phone_number, voice and audio settings, creativity, created_at and traits. With simulation_id, only id, intent, success_criteria and traits, and no paging keys. Pass an id to get_digital_human for the full configuration."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
List every valid language, accent and gender combination for a digital human's voice. Read-only.
Call this before setting language/accent/gender on create_digital_humans or
update_digital_humans: those three fields must form a valid combination
(e.g. language "en" pairs with accent "american", not "mexican").
Returns voice_options: for each language code, its display name and the
accents it supports, each with the genders (male/female) available. The
catalog is static and makes no API call.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"voice_options": {
"type": [
"object",
"array",
"null"
],
"description": "The catalog keyed by language code, e.g. {\"en\": {\"name\": \"English\", \"accents\": {\"american\": [\"male\", \"female\"], ...}}, ...}: each language has a display name and, per accent, the genders available. Use a language code, one of its accents and one of that accent's genders together."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "get_voice_options",
"title": "Get voice options",
"description": "List every valid language, accent and gender combination for a digital human's voice. Read-only.\n\nCall this before setting language/accent/gender on create_digital_humans or\nupdate_digital_humans: those three fields must form a valid combination\n(e.g. language \"en\" pairs with accent \"american\", not \"mexican\").\n\nReturns voice_options: for each language code, its display name and the\naccents it supports, each with the genders (male/female) available. The\ncatalog is static and makes no API call.\n",
"inputSchema": {
"type": "object",
"title": "get_voice_optionsArguments",
"properties": {}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"voice_options": {
"type": [
"object",
"array",
"null"
],
"description": "The catalog keyed by language code, e.g. {\"en\": {\"name\": \"English\", \"accents\": {\"american\": [\"male\", \"female\"], ...}}, ...}: each language has a display name and, per accent, the genders available. Use a language code, one of its accents and one of that accent's genders together."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Mint a signed upload URL via Bluejay POST /v1/custom-background-noises/upload-url.
Returns upload_url (HTTP PUT the raw MP3/WAV bytes to it, e.g.
curl -X PUT --upload-file noise.mp3 -H "Content-Type: audio/mpeg" <upload_url>)
and storage_path. After uploading, register the file with
create_custom_background_noise so digital humans can reference it.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
filename
Name of the audio file you are about to upload, ending in .mp3 or .wav (other formats are rejected). Only its last path segment is kept, with unsafe characters replaced.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"upload_url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "One-time signed URL; HTTP PUT the raw audio bytes to it."
},
"storage_path": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Where the file will live once uploaded. Pass it to create_custom_background_noise to add the file to the library."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_custom_background_noise_upload_url",
"title": "Create custom background noise upload URL",
"description": "Mint a signed upload URL via Bluejay POST /v1/custom-background-noises/upload-url.\n\nReturns upload_url (HTTP PUT the raw MP3/WAV bytes to it, e.g.\ncurl -X PUT --upload-file noise.mp3 -H \"Content-Type: audio/mpeg\" <upload_url>)\nand storage_path. After uploading, register the file with\ncreate_custom_background_noise so digital humans can reference it.\n",
"inputSchema": {
"type": "object",
"title": "create_custom_background_noise_upload_urlArguments",
"required": [
"filename"
],
"properties": {
"filename": {
"type": "string",
"title": "Filename",
"description": "Name of the audio file you are about to upload, ending in .mp3 or .wav (other formats are rejected). Only its last path segment is kept, with unsafe characters replaced."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"upload_url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "One-time signed URL; HTTP PUT the raw audio bytes to it."
},
"storage_path": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Where the file will live once uploaded. Pass it to create_custom_background_noise to add the file to the library."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Add an uploaded audio file to the org's custom background noise library (POST /v1/custom-background-noises).
Prerequisite: get an upload_url and storage_path from
create_custom_background_noise_upload_url and PUT the audio there first.
The library holds at most 20 noises per org (a full library is rejected),
and the same file cannot be added twice.
Returns noise, the new entry (id, name, storage_path). Set a digital
human's custom_background_noise_url to that storage_path, with
background_noise="custom", to use it.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
name
Display name for the noise in the library and the background-noise picker, e.g. 'Busy call center'.
Clear enough to supply this argument.
storage_path
The storage_path returned by create_custom_background_noise_upload_url, after the audio has been uploaded to its upload_url. It must be a path under your organization's own upload area.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"noise": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The noise's id in the library."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Display name of the noise."
},
"created_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When the noise was added (ISO 8601)."
},
"created_by": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The user who added it."
},
"usage_count": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How many digital humans currently use this noise. Only the library listing fills it in."
},
"storage_path": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Set a digital human's custom_background_noise_url to this, with background_noise=\"custom\"."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The organization that owns the noise."
}
},
"description": "One entry in the org's custom background noise library; storage_path is what custom_background_noise_url takes.",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_custom_background_noise",
"title": "Create custom background noise",
"description": "Add an uploaded audio file to the org's custom background noise library (POST /v1/custom-background-noises).\n\nPrerequisite: get an upload_url and storage_path from\ncreate_custom_background_noise_upload_url and PUT the audio there first.\nThe library holds at most 20 noises per org (a full library is rejected),\nand the same file cannot be added twice.\n\nReturns noise, the new entry (id, name, storage_path). Set a digital\nhuman's custom_background_noise_url to that storage_path, with\nbackground_noise=\"custom\", to use it.\n",
"inputSchema": {
"type": "object",
"title": "create_custom_background_noiseArguments",
"required": [
"name",
"storage_path"
],
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "Display name for the noise in the library and the background-noise picker, e.g. 'Busy call center'."
},
"storage_path": {
"type": "string",
"title": "Storage Path",
"description": "The storage_path returned by create_custom_background_noise_upload_url, after the audio has been uploaded to its upload_url. It must be a path under your organization's own upload area."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"noise": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The noise's id in the library."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Display name of the noise."
},
"created_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When the noise was added (ISO 8601)."
},
"created_by": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The user who added it."
},
"usage_count": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How many digital humans currently use this noise. Only the library listing fills it in."
},
"storage_path": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Set a digital human's custom_background_noise_url to this, with background_noise=\"custom\"."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The organization that owns the noise."
}
},
"description": "One entry in the org's custom background noise library; storage_path is what custom_background_noise_url takes.",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
List the org's custom background noise library (GET /v1/custom-background-noises). Read-only.
Returns noises: each entry's id, name, storage_path, who added it and when,
and usage_count (how many digital humans currently use it). Each
storage_path is a valid custom_background_noise_url for
create_digital_humans / update_digital_humans with background_noise="custom".
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Start a simulation run now: each selected digital human calls, texts or messages the agent under test.
This spends credits: confirm with the user first, naming the digital human count and, for voice,
the maximum call minutes (digital humans x runs x the simulation's max_call_duration in minutes).
This places real phone/SIP calls, or sends real SMS or HTTP messages, to the customer's agent
and spends Bluejay credits for every conversation; it fails when the org is out of credits.
Once queued it runs to completion (end_conversations stops conversations in flight). Confirm
the simulation, digital humans and run count with the user first. The simulation needs at
least one digital human, and a phone agent needs a number on each digital human.
`channel` picks the endpoint: "voice" (POST /v1/queue-simulation-run), "sms"
(/v1/queue-sms-simulation-run) or "http_text" (/v1/queue-http-text-simulation-run). Email
agents use queue_email_simulation_run. simulation_id, digital_human_ids, prompt_id,
knowledge_base_id and runs_per_digital_human apply on every channel. The dialing overrides
(phone_number, sip_uri, livekit_*, pipecat_*) are voice-only, and
terminate_overlapping_simulations is SMS-only; passing one on the wrong channel is rejected
rather than ignored.
Returns simulation_run_id (poll get_simulation_results with it), simulation_result_ids (one
per conversation), agent_id, status, and run_url on voice runs.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
simulation_id
The simulation to run: its id from list_simulations or create_simulation.
Clear enough to supply this argument.
channel
How the digital humans reach the agent; it must match the agent: voice for phone, SIP and other voice connections, sms for agents reached by text message, http_text for agents behind an HTTP text webhook.
Clear enough to supply this argument.
digital_human_ids
Digital humans to run, by id from list_digital_humans (with this simulation_id); each must belong to the simulation. Omitted, every digital human in the simulation runs.
Clear enough to supply this argument.
prompt_id
Agent version to test in this run instead of the simulation's default: a version uuid from list_prompt_versions for the simulation's agent.
Clear enough to supply this argument.
knowledge_base_id
Knowledge base uuid to use for this run instead of the simulation's default.
Clear enough to supply this argument.
phone_number
Phone number to call for this run instead of the agent's, e.g. +14155550123.
Clear enough to supply this argument.
sip_uri
SIP URI to dial for this run instead of the agent's, e.g. sip:[email protected].
Clear enough to supply this argument.
livekit_agent_name
LiveKit agents only: name of the agent to dispatch in your LiveKit project for this run; an empty string uses your default agent.
Clear enough to supply this argument.
livekit_metadata
LiveKit agents only: metadata object passed to the LiveKit room.
Clear enough to supply this argument.
pipecat_agent_name
Pipecat agents only: name of the Pipecat agent to use for this run.
Clear enough to supply this argument.
pipecat_agent_configuration
Pipecat agents only: configuration object passed to the Pipecat agent.
Clear enough to supply this argument.
pipecat_room_properties
Pipecat agents only: room properties object for the Pipecat session.
Clear enough to supply this argument.
terminate_overlapping_simulations
SMS only: true ends any open conversation between the same pair of phone numbers before this run starts. Omitted, false.
Clear enough to supply this argument.
runs_per_digital_human
Conversations to start per digital human in this run. Omitted, the simulation's runs_per_digital_human, else 1.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Status of the request, \"success\" when queued."
},
"run_url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Link to the run in the Bluejay app"
},
"agent_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The agent under test."
},
"simulation_run_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Id of the new run; poll get_simulation_results with it until the run's status is COMPLETED."
},
"simulation_result_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "One id per queued conversation, for get_simulation_result or end_conversations.",
"additionalProperties": true
},
"terminated_conversations": {
"type": [
"array",
"object",
"null"
],
"description": "SMS runs with terminate_overlapping_simulations: the open conversations that were ended."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "queue_simulation_run",
"title": "Queue simulation run",
"description": "Start a simulation run now: each selected digital human calls, texts or messages the agent under test.\nThis spends credits: confirm with the user first, naming the digital human count and, for voice,\nthe maximum call minutes (digital humans x runs x the simulation's max_call_duration in minutes).\n\nThis places real phone/SIP calls, or sends real SMS or HTTP messages, to the customer's agent\nand spends Bluejay credits for every conversation; it fails when the org is out of credits.\nOnce queued it runs to completion (end_conversations stops conversations in flight). Confirm\nthe simulation, digital humans and run count with the user first. The simulation needs at\nleast one digital human, and a phone agent needs a number on each digital human.\n\n`channel` picks the endpoint: \"voice\" (POST /v1/queue-simulation-run), \"sms\"\n(/v1/queue-sms-simulation-run) or \"http_text\" (/v1/queue-http-text-simulation-run). Email\nagents use queue_email_simulation_run. simulation_id, digital_human_ids, prompt_id,\nknowledge_base_id and runs_per_digital_human apply on every channel. The dialing overrides\n(phone_number, sip_uri, livekit_*, pipecat_*) are voice-only, and\nterminate_overlapping_simulations is SMS-only; passing one on the wrong channel is rejected\nrather than ignored.\n\nReturns simulation_run_id (poll get_simulation_results with it), simulation_result_ids (one\nper conversation), agent_id, status, and run_url on voice runs.\n",
"inputSchema": {
"type": "object",
"title": "queue_simulation_runArguments",
"required": [
"simulation_id"
],
"properties": {
"channel": {
"enum": [
"voice",
"sms",
"http_text"
],
"type": "string",
"title": "Channel",
"default": "voice",
"description": "How the digital humans reach the agent; it must match the agent: voice for phone, SIP and other voice connections, sms for agents reached by text message, http_text for agents behind an HTTP text webhook."
},
"sip_uri": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Sip Uri",
"default": null,
"description": "SIP URI to dial for this run instead of the agent's, e.g. sip:[email protected]."
},
"prompt_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Prompt Id",
"default": null,
"description": "Agent version to test in this run instead of the simulation's default: a version uuid from list_prompt_versions for the simulation's agent."
},
"phone_number": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Phone Number",
"default": null,
"description": "Phone number to call for this run instead of the agent's, e.g. +14155550123."
},
"simulation_id": {
"type": "string",
"title": "Simulation Id",
"description": "The simulation to run: its id from list_simulations or create_simulation."
},
"livekit_metadata": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Livekit Metadata",
"default": null,
"description": "LiveKit agents only: metadata object passed to the LiveKit room."
},
"digital_human_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Digital Human Ids",
"default": null,
"description": "Digital humans to run, by id from list_digital_humans (with this simulation_id); each must belong to the simulation. Omitted, every digital human in the simulation runs."
},
"knowledge_base_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Knowledge Base Id",
"default": null,
"description": "Knowledge base uuid to use for this run instead of the simulation's default."
},
"livekit_agent_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Livekit Agent Name",
"default": null,
"description": "LiveKit agents only: name of the agent to dispatch in your LiveKit project for this run; an empty string uses your default agent."
},
"pipecat_agent_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Pipecat Agent Name",
"default": null,
"description": "Pipecat agents only: name of the Pipecat agent to use for this run."
},
"runs_per_digital_human": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Runs Per Digital Human",
"default": null,
"description": "Conversations to start per digital human in this run. Omitted, the simulation's runs_per_digital_human, else 1."
},
"pipecat_room_properties": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Pipecat Room Properties",
"default": null,
"description": "Pipecat agents only: room properties object for the Pipecat session."
},
"pipecat_agent_configuration": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Pipecat Agent Configuration",
"default": null,
"description": "Pipecat agents only: configuration object passed to the Pipecat agent."
},
"terminate_overlapping_simulations": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Terminate Overlapping Simulations",
"default": null,
"description": "SMS only: true ends any open conversation between the same pair of phone numbers before this run starts. Omitted, false."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Status of the request, \"success\" when queued."
},
"run_url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Link to the run in the Bluejay app"
},
"agent_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The agent under test."
},
"simulation_run_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Id of the new run; poll get_simulation_results with it until the run's status is COMPLETED."
},
"simulation_result_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "One id per queued conversation, for get_simulation_result or end_conversations.",
"additionalProperties": true
},
"terminated_conversations": {
"type": [
"array",
"object",
"null"
],
"description": "SMS runs with terminate_overlapping_simulations: the open conversations that were ended."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Start an email simulation run now: each selected digital human emails the agent's inbox and keeps the thread going.
Calls POST /v1/queue-email-simulation-run. Only for agents with mode EMAIL and an
email_address (see add_agent); any other agent is rejected. This sends real email to the
customer's agent from Bluejay's sending domain (bluejaysims.com) and spends Bluejay credits
for every conversation; it fails when the org is out of credits. A digital human that is
already in an open email conversation is refused, so each runs once per run. Confirm the
simulation and digital humans with the user first. Phone, SIP, SMS and HTTP agents use
queue_simulation_run.
Returns simulation_run_id (poll get_simulation_results with it), simulation_result_ids (one
per conversation, for get_simulation_result or get_simulation_transcript), agent_id and status.
The description explains the capability, when to use it, and what to expect.
Inputs80/100
Resolve the mismatch between this description and its schema constraints.
simulation_id
The simulation to run: its id from list_simulations or create_simulation.
Clear enough to supply this argument.
digital_human_ids
Digital humans to run, by id from list_digital_humans (with this simulation_id); each must belong to the simulation. Omitted, every digital human in the simulation runs.
Clear enough to supply this argument.
prompt_id
Agent version to test in this run instead of the simulation's default: a version uuid from list_prompt_versions for the simulation's agent.
Clear enough to supply this argument.
knowledge_base_id
Knowledge base uuid to use for this run instead of the simulation's default.
Clear enough to supply this argument.
runs_per_digital_human
Conversations to start per digital human in this run. Omitted, the simulation's runs_per_digital_human, else 1. Email runs always hold one conversation per digital human.
Resolve the mismatch between this description and its schema constraints.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Status of the request, \"success\" when queued."
},
"agent_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The agent under test."
},
"simulation_run_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Id of the new run; poll get_simulation_results with it until the run's status is COMPLETED."
},
"simulation_result_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "One id per queued conversation, for get_simulation_result or end_conversations.",
"additionalProperties": true
},
"terminated_conversations": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "SMS runs with terminate_overlapping_simulations: the open conversations between the same pair of phone numbers that were ended. Always null for email runs."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "queue_email_simulation_run",
"title": "Queue email simulation run",
"description": "Start an email simulation run now: each selected digital human emails the agent's inbox and keeps the thread going.\n\nCalls POST /v1/queue-email-simulation-run. Only for agents with mode EMAIL and an\nemail_address (see add_agent); any other agent is rejected. This sends real email to the\ncustomer's agent from Bluejay's sending domain (bluejaysims.com) and spends Bluejay credits\nfor every conversation; it fails when the org is out of credits. A digital human that is\nalready in an open email conversation is refused, so each runs once per run. Confirm the\nsimulation and digital humans with the user first. Phone, SIP, SMS and HTTP agents use\nqueue_simulation_run.\n\nReturns simulation_run_id (poll get_simulation_results with it), simulation_result_ids (one\nper conversation, for get_simulation_result or get_simulation_transcript), agent_id and status.\n",
"inputSchema": {
"type": "object",
"title": "queue_email_simulation_runArguments",
"required": [
"simulation_id"
],
"properties": {
"prompt_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Prompt Id",
"default": null,
"description": "Agent version to test in this run instead of the simulation's default: a version uuid from list_prompt_versions for the simulation's agent."
},
"simulation_id": {
"type": "string",
"title": "Simulation Id",
"description": "The simulation to run: its id from list_simulations or create_simulation."
},
"digital_human_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Digital Human Ids",
"default": null,
"description": "Digital humans to run, by id from list_digital_humans (with this simulation_id); each must belong to the simulation. Omitted, every digital human in the simulation runs."
},
"knowledge_base_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Knowledge Base Id",
"default": null,
"description": "Knowledge base uuid to use for this run instead of the simulation's default."
},
"runs_per_digital_human": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Runs Per Digital Human",
"default": null,
"description": "Conversations to start per digital human in this run. Omitted, the simulation's runs_per_digital_human, else 1. Email runs always hold one conversation per digital human."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Status of the request, \"success\" when queued."
},
"agent_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The agent under test."
},
"simulation_run_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Id of the new run; poll get_simulation_results with it until the run's status is COMPLETED."
},
"simulation_result_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "One id per queued conversation, for get_simulation_result or end_conversations.",
"additionalProperties": true
},
"terminated_conversations": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "SMS runs with terminate_overlapping_simulations: the open conversations between the same pair of phone numbers that were ended. Always null for email runs."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Read one page of a simulation run's outcome: the run summary plus a slim row per conversation. Read-only.
Calls GET /v1/retrieve-simulation-results/{simulation_run_id}. simulation_run holds the
run's status (RUNNING until every conversation is final, then COMPLETED), total_tests,
tests_completed, tests_passed, eval_failed, tests_failed (infra and dropped calls only),
success_rate (0-100) and run_url. Each simulation_results row has id, digital_human_id,
status, duration, start_time, end_time, trace_ids, evaluations (avg_agent_latency, num_turns,
goal_success, goal_reasoning) and tool_calls (names only).
Transcripts, audio, metric reasoning and expected-vs-actual tool payloads are left out: pass
a row's id to get_simulation_transcript or get_simulation_result for those. Page with limit
and offset until a page comes back shorter than limit.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
simulation_run_id
The run to read: simulation_run_id from queue_simulation_run, or a run id from get_simulation_runs.
Clear enough to supply this argument.
limit
Conversations per page, up to 100; out-of-range values are clamped.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
offset
How many conversations to skip, for the next page: add limit each time.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Read everything stored for one simulated conversation (GET /v1/retrieve-simulation-result/{test_result_id}). Read-only.
simulation_result carries the conversation's status, digital_human_id, duration, start and
end times, transcript (or a presigned transcript_url when it is not stored inline),
audio_url, events, latency, evaluations, every metric result (builtin and custom, with value,
reasoning and not_applicable), tool_calls with expected vs actual parameters and outputs, and
trace_ids. credits_used is what the conversation cost (null until usage is priced). `data`
repeats the whole body. For only the words spoken, get_simulation_transcript is lighter.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
test_result_id
The conversation to read: a result id from get_simulation_results, or an entry of simulation_result_ids from queue_simulation_run.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Read what was actually said on one simulation conversation. Read-only.
Returns the turns themselves — ``[{"speaker": ..., "utterance": ...}, ...]`` in spoken
order — so a transcript can be quoted or tabled without fetching a URL, plus the
digital_human_id. `test_result_id` is the `id` of a row from get_simulation_results. A
conversation with no stored transcript returns an error. For metrics, audio and tool calls,
use get_simulation_result.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
test_result_id
The conversation to read: a result id from get_simulation_results, or an entry of simulation_result_ids from queue_simulation_run.
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"transcript": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"speaker": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Who spoke, as stored (e.g. agent or user)."
},
"utterance": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What they said."
}
},
"description": "One turn.",
"additionalProperties": true
},
"description": "The turns in spoken order; silent turns are dropped."
},
"digital_human_id": {
"type": [
"integer",
"string",
"number",
"null"
],
"description": "The digital human that held this conversation."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "get_simulation_transcript",
"title": "Get simulation transcript",
"description": "Read what was actually said on one simulation conversation. Read-only.\n\nReturns the turns themselves — ``[{\"speaker\": ..., \"utterance\": ...}, ...]`` in spoken\norder — so a transcript can be quoted or tabled without fetching a URL, plus the\ndigital_human_id. `test_result_id` is the `id` of a row from get_simulation_results. A\nconversation with no stored transcript returns an error. For metrics, audio and tool calls,\nuse get_simulation_result.\n",
"inputSchema": {
"type": "object",
"title": "get_simulation_transcriptArguments",
"required": [
"test_result_id"
],
"properties": {
"test_result_id": {
"type": "string",
"title": "Test Result Id",
"description": "The conversation to read: a result id from get_simulation_results, or an entry of simulation_result_ids from queue_simulation_run."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"transcript": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"speaker": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Who spoke, as stored (e.g. agent or user)."
},
"utterance": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What they said."
}
},
"description": "One turn.",
"additionalProperties": true
},
"description": "The turns in spoken order; silent turns are dropped."
},
"digital_human_id": {
"type": [
"integer",
"string",
"number",
"null"
],
"description": "The digital human that held this conversation."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Count simulated conversations (each is one digital human's pass through a simulation run).
Returns `total` and `runs` (distinct simulation runs) for everything matching the filters.
Set group_by for counts per group, which is what a "how many" question about simulations needs:
- 'status': how they ended. Only COMPLETED ones carry a real verdict; NO_ANSWER, NO_CONNECTION,
SYSTEM_ERROR and the like never really happened, so report them apart.
- 'agent', 'simulation', 'run', 'digital_human', 'day': as named. Every group also carries `runs`,
so "how many simulation runs per agent" is group_by='agent', reading `runs`.
- 'metric_value' with metric_name: how one metric came out. The goal metric is usually named
'success'; its 'true' share of `total` is the pass rate. Not-applicable results are counted
apart and human corrections win, as in the app.
Filter with simulation_run_ids for one run, simulation_ids for one simulation (group_by='run' to
compare its runs) or agent_ids for one agent (group_by='simulation' for its simulations). Agent,
simulation and run groups come back with their `name`; runs also with `started_at`.
`last` is 1day, 3days, 7days, 30days, 90days or all, by when the conversation was created.
Left out, it is all time when a run, simulation or agent filter is set, otherwise the last 7
days; the response's `since` says which, so state the window you used. Get agent ids from
list_agents, simulation ids from list_simulations and run ids from get_simulation_runs. For one
run's conversations themselves, use get_simulation_results.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
status
Only conversations that ended in these statuses, e.g. COMPLETED, NO_ANSWER, SYSTEM_ERROR
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
agent_ids
Only these agents' conversations, by Bluejay agent id from list_agents
Clear enough to supply this argument.
simulation_ids
Only these simulations' conversations, by id from list_simulations
Clear enough to supply this argument.
simulation_run_ids
Only these runs' conversations, by run id from get_simulation_runs or queue_simulation_run
Clear enough to supply this argument.
group_by
Dimension to split the counts by; omit for totals only. metric_value needs metric_name or metric_id
Clear enough to supply this argument.
metric_name
With group_by=metric_value: the metric to break down, by name, e.g. success for the goal metric
Clear enough to supply this argument.
metric_id
With group_by=metric_value: the metric's uuid (from list_custom_metrics), instead of metric_name
Clear enough to supply this argument.
last
By when the conversation was created. Omitted: all time when filtering by a run, simulation or agent, otherwise the last 7 days
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
List the dashboards in your organization that your workspaces can see, newest first.
Read-only. Returns 'dashboards', each with id, name, description, data_type and the 'url' that opens it in the
app. Widgets are not included; get_dashboard returns a dashboard with its widgets.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
Input documentation gives an agent enough context to populate the arguments.
data_type
Only return dashboards for one kind of data: 'observability' (live production calls) or 'simulation' (simulation runs). Omit to return both.
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"dashboards": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The dashboard's id; pass it as dashboard_id to GET /v1/dashboards/{dashboard_id}, POST /v1/widgets, POST /v1/widgets/{widget_id}/duplicate, PUT /v1/dashboards/{dashboard_id}/layout and the other dashboard routes."
},
"url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Link that opens the dashboard in the Bluejay app; give this to the user instead of building one. Null when the app URL is not configured."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The dashboard's name."
},
"agent_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The agent this dashboard is tied to; null when it is not tied to one."
},
"data_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the dashboard charts: 'observability' (live calls) or 'simulation' (simulation runs)."
},
"created_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When the dashboard was created, as an ISO 8601 timestamp."
},
"created_by": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Id of the user who created the dashboard, when known."
},
"is_curated": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True for a curated dashboard; dashboards created through this API are false."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The dashboard's description; null when it has none."
},
"organization_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The organization that owns the dashboard."
}
},
"description": "A dashboard: a named set of widgets charting observability or simulation data. Widgets are not included.",
"additionalProperties": true
},
"properties": {},
"description": "A list. Each item: A dashboard: a named set of widgets charting observability or simulation data. Widgets are not included.",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "list_dashboards",
"title": "List dashboards",
"description": "List the dashboards in your organization that your workspaces can see, newest first.\n\nRead-only. Returns 'dashboards', each with id, name, description, data_type and the 'url' that opens it in the\napp. Widgets are not included; get_dashboard returns a dashboard with its widgets.",
"inputSchema": {
"type": "object",
"title": "list_dashboardsArguments",
"properties": {
"data_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Data Type",
"default": null,
"description": "Only return dashboards for one kind of data: 'observability' (live production calls) or 'simulation' (simulation runs). Omit to return both."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"dashboards": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The dashboard's id; pass it as dashboard_id to GET /v1/dashboards/{dashboard_id}, POST /v1/widgets, POST /v1/widgets/{widget_id}/duplicate, PUT /v1/dashboards/{dashboard_id}/layout and the other dashboard routes."
},
"url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Link that opens the dashboard in the Bluejay app; give this to the user instead of building one. Null when the app URL is not configured."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The dashboard's name."
},
"agent_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The agent this dashboard is tied to; null when it is not tied to one."
},
"data_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the dashboard charts: 'observability' (live calls) or 'simulation' (simulation runs)."
},
"created_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When the dashboard was created, as an ISO 8601 timestamp."
},
"created_by": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Id of the user who created the dashboard, when known."
},
"is_curated": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True for a curated dashboard; dashboards created through this API are false."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The dashboard's description; null when it has none."
},
"organization_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The organization that owns the dashboard."
}
},
"description": "A dashboard: a named set of widgets charting observability or simulation data. Widgets are not included.",
"additionalProperties": true
},
"properties": {},
"description": "A list. Each item: A dashboard: a named set of widgets charting observability or simulation data. Widgets are not included.",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Create an empty dashboard in your current workspace, then fill it with widgets via create_widget. Returns the
new dashboard: its id (the dashboard_id create_widget takes), name, data_type and 'url', the link to give the
user. Never construct that link yourself; simulation and observability dashboards live on different pages.
A dashboard is only useful if its widgets answer different questions. Aim for six, and do not
stop at two variations of call count. Cover volume over time, outcome quality, latency,
and at least one breakdown that splits the same data by a dimension. Call list_custom_metrics,
list_labels, list_agents and list_simulations first so the widgets use what this org actually
records. A workable default, dropping any part the org has no data for:
1. call volume over time (line, metric 'call_count', time_bucket 'day')
2. volume split by agent or label (bar, group_by 'agent' or 'labels')
3. pass rate per custom metric (bar, metric 'custom_metric', aggregation 'breakdown')
4. goal completion (bar or pie, metric 'goal')
5. latency percentiles (line, metric 'latency', aggregation ['p50','p90','p95'])
6. a KPI or table for the single number or row list the user cares most about
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
The dashboard's title in the Bluejay app; surrounding whitespace is trimmed.
Clear enough to supply this argument.
description
Optional text saying what the dashboard is for.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
data_type
What the dashboard charts: 'observability' for live production calls or 'simulation' for simulation runs. It decides which app page the dashboard opens on and cannot be changed later.
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The dashboard's id; pass it as dashboard_id to get_dashboard, create_widget, duplicate_widget, update_dashboard_layout and the other dashboard routes."
},
"url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Link that opens the dashboard in the Bluejay app; give this to the user instead of building one. Null when the app URL is not configured."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The dashboard's name."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"agent_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The agent this dashboard is tied to; null when it is not tied to one."
},
"data_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the dashboard charts: 'observability' (live calls) or 'simulation' (simulation runs)."
},
"created_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When the dashboard was created, as an ISO 8601 timestamp."
},
"created_by": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Id of the user who created the dashboard, when known."
},
"is_curated": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True for a curated dashboard; dashboards created through this API are false."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The dashboard's description; null when it has none."
},
"organization_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The organization that owns the dashboard."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_dashboard",
"title": "Create dashboard",
"description": "Create an empty dashboard in your current workspace, then fill it with widgets via create_widget. Returns the\nnew dashboard: its id (the dashboard_id create_widget takes), name, data_type and 'url', the link to give the\nuser. Never construct that link yourself; simulation and observability dashboards live on different pages.\n\nA dashboard is only useful if its widgets answer different questions. Aim for six, and do not\nstop at two variations of call count. Cover volume over time, outcome quality, latency,\nand at least one breakdown that splits the same data by a dimension. Call list_custom_metrics,\nlist_labels, list_agents and list_simulations first so the widgets use what this org actually\nrecords. A workable default, dropping any part the org has no data for:\n 1. call volume over time (line, metric 'call_count', time_bucket 'day')\n 2. volume split by agent or label (bar, group_by 'agent' or 'labels')\n 3. pass rate per custom metric (bar, metric 'custom_metric', aggregation 'breakdown')\n 4. goal completion (bar or pie, metric 'goal')\n 5. latency percentiles (line, metric 'latency', aggregation ['p50','p90','p95'])\n 6. a KPI or table for the single number or row list the user cares most about\n",
"inputSchema": {
"type": "object",
"title": "create_dashboardArguments",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "The dashboard's title in the Bluejay app; surrounding whitespace is trimmed."
},
"data_type": {
"type": "string",
"title": "Data Type",
"default": "observability",
"description": "What the dashboard charts: 'observability' for live production calls or 'simulation' for simulation runs. It decides which app page the dashboard opens on and cannot be changed later."
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description",
"default": null,
"description": "Optional text saying what the dashboard is for."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The dashboard's id; pass it as dashboard_id to get_dashboard, create_widget, duplicate_widget, update_dashboard_layout and the other dashboard routes."
},
"url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Link that opens the dashboard in the Bluejay app; give this to the user instead of building one. Null when the app URL is not configured."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The dashboard's name."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"agent_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The agent this dashboard is tied to; null when it is not tied to one."
},
"data_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the dashboard charts: 'observability' (live calls) or 'simulation' (simulation runs)."
},
"created_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When the dashboard was created, as an ISO 8601 timestamp."
},
"created_by": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Id of the user who created the dashboard, when known."
},
"is_curated": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True for a curated dashboard; dashboards created through this API are false."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The dashboard's description; null when it has none."
},
"organization_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The organization that owns the dashboard."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Fetch one dashboard with everything on it: its id, name, description, data_type and 'url', plus 'widgets',
each with its chart configuration, metrics and layout, ordered by position.
Read-only. It returns configuration, not chart data; the app renders the charts.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
dashboard_id
The dashboard to fetch, from list_dashboards or create_dashboard.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Rename a dashboard and/or change its description, overwriting the current value. At least one field required.
An omitted field keeps its value; an empty description clears it. Widgets and data_type are untouched. Needs
edit access to the dashboard. Returns the updated dashboard with its 'url'.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Input documentation gives an agent enough context to populate the arguments.
dashboard_id
The dashboard to change, from list_dashboards.
Clear enough to supply this argument.
name
The dashboard's new title. Omit to keep the current one.
Clear enough to supply this argument.
description
The dashboard's new description; an empty string clears it. Omit to keep the current one.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Permanently delete a dashboard and every widget on it, with their metrics. This cannot be undone; to keep a
widget, copy it to another dashboard with duplicate_widget first.
A default dashboard cannot be deleted. Needs edit access to the dashboard. Returns success, deleted and
dashboard_id.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Duplicate a dashboard: creates '<name> (Copy)' with its own copy of every widget, laid out the same way. The copies are independent of the originals.
The copy lands in the source dashboard's workspace and the source is unchanged. Needs edit access to the source.
Returns the new dashboard: id, name, description, data_type and 'url'. Call get_dashboard with the new id to see
its widgets.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Input documentation gives an agent enough context to populate the arguments.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The dashboard's id; pass it as dashboard_id to get_dashboard, create_widget, duplicate_widget, update_dashboard_layout and the other dashboard routes."
},
"url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Link that opens the dashboard in the Bluejay app; give this to the user instead of building one. Null when the app URL is not configured."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The dashboard's name."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"agent_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The agent this dashboard is tied to; null when it is not tied to one."
},
"data_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the dashboard charts: 'observability' (live calls) or 'simulation' (simulation runs)."
},
"created_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When the dashboard was created, as an ISO 8601 timestamp."
},
"created_by": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Id of the user who created the dashboard, when known."
},
"is_curated": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True for a curated dashboard; dashboards created through this API are false."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The dashboard's description; null when it has none."
},
"organization_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The organization that owns the dashboard."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "duplicate_dashboard",
"title": "Duplicate dashboard",
"description": "Duplicate a dashboard: creates '<name> (Copy)' with its own copy of every widget, laid out the same way. The copies are independent of the originals.\n\nThe copy lands in the source dashboard's workspace and the source is unchanged. Needs edit access to the source.\nReturns the new dashboard: id, name, description, data_type and 'url'. Call get_dashboard with the new id to see\nits widgets.",
"inputSchema": {
"type": "object",
"title": "duplicate_dashboardArguments",
"required": [
"dashboard_id"
],
"properties": {
"dashboard_id": {
"type": "string",
"title": "Dashboard Id",
"description": "The dashboard to copy, from list_dashboards."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The dashboard's id; pass it as dashboard_id to get_dashboard, create_widget, duplicate_widget, update_dashboard_layout and the other dashboard routes."
},
"url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Link that opens the dashboard in the Bluejay app; give this to the user instead of building one. Null when the app URL is not configured."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The dashboard's name."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"agent_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The agent this dashboard is tied to; null when it is not tied to one."
},
"data_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the dashboard charts: 'observability' (live calls) or 'simulation' (simulation runs)."
},
"created_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When the dashboard was created, as an ISO 8601 timestamp."
},
"created_by": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Id of the user who created the dashboard, when known."
},
"is_curated": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True for a curated dashboard; dashboards created through this API are false."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The dashboard's description; null when it has none."
},
"organization_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The organization that owns the dashboard."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Set widget positions on a dashboard, overwriting the position and size of each widget listed. Widgets that
are not on this dashboard are ignored, and widgets not listed keep their place. Needs edit access to the
dashboard. Returns success.
layouts is a list of {"widget_id": "<uuid>", "layout": {"x": <row, 1-based>, "y": <column 1-6>,
"w": <width in columns 1-6>, "h": <height in 50px steps, 2-18>}}. The names are older than the grid: x is the row and y is the column. The dashboard is six
columns wide, and h counts 50px steps, so h=6 is 300px and the range 2..18 is 100px..900px.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Input documentation gives an agent enough context to populate the arguments.
dashboard_id
The dashboard whose widgets to arrange, from list_dashboards or create_dashboard.
Clear enough to supply this argument.
layouts
One entry per widget to place: {"widget_id": "<id from get_dashboard or create_widget>", "layout": {"x": <row, 1-based>, "y": <column 1-6>, "w": <width in columns 1-6>, "h": <height in 50px steps, 2-18>}}. Widgets you leave out keep their place; widgets not on this dashboard are ignored.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"success": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "True when the request was applied: the dashboard or widget was deleted, or the layouts were saved."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "update_dashboard_layout",
"title": "Update dashboard layout",
"description": "Set widget positions on a dashboard, overwriting the position and size of each widget listed. Widgets that\nare not on this dashboard are ignored, and widgets not listed keep their place. Needs edit access to the\ndashboard. Returns success.\n\nlayouts is a list of {\"widget_id\": \"<uuid>\", \"layout\": {\"x\": <row, 1-based>, \"y\": <column 1-6>,\n\"w\": <width in columns 1-6>, \"h\": <height in 50px steps, 2-18>}}. The names are older than the grid: x is the row and y is the column. The dashboard is six\ncolumns wide, and h counts 50px steps, so h=6 is 300px and the range 2..18 is 100px..900px.",
"inputSchema": {
"type": "object",
"title": "update_dashboard_layoutArguments",
"required": [
"dashboard_id",
"layouts"
],
"properties": {
"layouts": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"title": "Layouts",
"description": "One entry per widget to place: {\"widget_id\": \"<id from get_dashboard or create_widget>\", \"layout\": {\"x\": <row, 1-based>, \"y\": <column 1-6>, \"w\": <width in columns 1-6>, \"h\": <height in 50px steps, 2-18>}}. Widgets you leave out keep their place; widgets not on this dashboard are ignored."
},
"dashboard_id": {
"type": "string",
"title": "Dashboard Id",
"description": "The dashboard whose widgets to arrange, from list_dashboards or create_dashboard."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"success": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "True when the request was applied: the dashboard or widget was deleted, or the layouts were saved."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
List every widget in your organization that your workspaces can see, across all dashboards, newest first.
Read-only. Returns 'widgets', each with its id, name, chart_type, data_type, chart options and widget_metrics.
Neither the layout nor the dashboard a widget sits on is included; get_dashboard returns a dashboard's widgets
in place.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
data_type
Only return widgets for one kind of data: 'observability' (live production calls) or 'simulation' (simulation runs). Omit to return both.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Create a widget (a chart configuration) on a dashboard. A widget belongs to exactly one
dashboard; to show the same chart on two dashboards, create it twice or use duplicate_widget.
Needs edit access to the dashboard, which must be in your current workspace. The widget is created without a
layout; set its position and size with update_dashboard_layout. Only configuration is stored; the app renders
the chart data. Returns the new widget: id, name, chart_type, data_type, its chart options and widget_metrics.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
name
The widget's title on the dashboard; surrounding whitespace is trimmed.
Clear enough to supply this argument.
chart_type
How the widget draws its data: 'line', 'bar', 'pie', 'table' (a list of rows), 'kpi' (a single number), 'pivot_table' or 'histogram'.
Clear enough to supply this argument.
dashboard_id
The dashboard the widget goes on, from create_dashboard or list_dashboards; a widget lives on exactly one dashboard. You need edit access to it, and it must be in your current workspace.
Clear enough to supply this argument.
metrics
What the widget plots; required unless chart_type is 'table'. Each item is {"metric": <key>, ...}: 'call_count'; 'latency'; 'custom_metric' with custom_metric_id from list_custom_metrics; 'goal' with goal (the goal text); 'tool_call' with tool_call_id; or 'trace_attribute' with metadata_path and metadata_type. Add threshold_operator ('lt', 'lte', 'gt', 'gte') and threshold_value to chart the share of conversations meeting that condition instead of the metric's own value.
Clear enough to supply this argument.
description
Optional text saying what the widget shows.
Clear enough to supply this argument.
chart_mode
'time_series' plots over time, bucketed by time_bucket; 'categorical' plots one value per category.
Clear enough to supply this argument.
data_type
What the widget reads: 'observability' (live production calls) or 'simulation' (simulation runs); use the dashboard's data_type. It cannot be changed later.
Clear enough to supply this argument.
bar_mode
For bar charts with several series: 'stacked' or 'side_by_side'.
Clear enough to supply this argument.
aggregation
How each metric is summarized, any of 'count', 'average', 'sum', 'percent_of_total', 'p50', 'p90', 'p95', 'p99', 'percentiles', 'breakdown', 'distribution'; e.g. ['p50', 'p90', 'p95'] for latency or ['breakdown'] for a custom metric's pass rate.
Clear enough to supply this argument.
time_bucket
Bucket size for time-series charts: 'hour', 'day', 'week' or 'month'.
Clear enough to supply this argument.
group_by
Split the data into one series per value: 'agent', 'labels', 'tool_call', 'age', 'gender', 'simulation' (needs simulation_ids), or 'metadata:<path>' for a conversation metadata field (dot notation for nested keys). Omit for no split.
Clear enough to supply this argument.
simulation_ids
Bluejay simulation ids, from list_simulations; required when group_by is 'simulation'.
Clear enough to supply this argument.
show_indeterminate
Also count conversations where the metric has no result, shown as an 'N/A' category.
Clear enough to supply this argument.
filters
Extra filters, on top of the dashboard's agents, labels and time range, that restrict which conversations the widget counts. Each item is a filter object in the shape the Bluejay logs page uses.
Clear enough to supply this argument.
column_visibility
Observability table widgets only: {"<column>": true|false} to show or hide columns of the conversations table. Ignored for other widgets.
Clear enough to supply this argument.
color_overrides
Per-series/per-slice colours as {"<label the chart draws>": "#rrggbb"}. Labels are matched case-insensitively; omitted labels keep the default palette.
Clear enough to supply this argument.
center_label
Chart options. Pie: {"slice": "<label>", "clamp_pct": <0..50 exclusive>, "label": "<caption>"} for the donut hole; slice omitted uses the largest slice, and clamp_pct collapses the rounding edges, so 1 turns 99.6% into '>99%' and 0.4% into '<1%'. Numeric line or bar chart or histogram: {"benchmark": <number>} draws a dashed reference line at that value. KPI: {"compare_previous": false} hides the change against the previous period. {"unit": "pts"} is shown after values on metrics that have no unit of their own.
Clear enough to supply this argument.
show_legend
Draw the colour key under pie, bar and line charts. Omit to draw it.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Fetch one widget's configuration with its metrics: id, name, description, chart_type, chart_mode, data_type,
aggregation, time_bucket, group_by, filters, chart options and widget_metrics.
Read-only. Neither the layout nor the dashboard it sits on is included; get_dashboard returns widgets with their
layout. Read this before update_widget, which replaces the whole configuration.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
widget_id
The widget to fetch, from get_dashboard, list_widgets or create_widget.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Replace a widget's configuration and metrics (full replace, same field semantics as create_widget).
Always send the complete desired config — metrics replace the existing set. data_type cannot change.
An omitted description, chart_mode, bar_mode, aggregation, time_bucket, group_by or simulation_ids is cleared,
and show_indeterminate resets to false. filters, column_visibility, color_overrides, center_label and show_legend
are the exception: omit one and the widget keeps what it already has.
Read the current config with get_widget first. Needs edit access to the widget. Overwrites the stored
configuration; returns the updated widget with its widget_metrics.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
widget_id
The widget to change, from get_dashboard, list_widgets or create_widget.
Clear enough to supply this argument.
name
The widget's title; required, so pass the current name to keep it.
Clear enough to supply this argument.
chart_type
How the widget draws its data: 'line', 'bar', 'pie', 'table' (a list of rows), 'kpi' (a single number), 'pivot_table' or 'histogram'. Required, so pass the current value to keep it.
Clear enough to supply this argument.
metrics
The complete metric list; it replaces every existing metric, so resend the ones to keep. What the widget plots; required unless chart_type is 'table'. Each item is {"metric": <key>, ...}: 'call_count'; 'latency'; 'custom_metric' with custom_metric_id from list_custom_metrics; 'goal' with goal (the goal text); 'tool_call' with tool_call_id; or 'trace_attribute' with metadata_path and metadata_type. Add threshold_operator ('lt', 'lte', 'gt', 'gte') and threshold_value to chart the share of conversations meeting that condition instead of the metric's own value.
Clear enough to supply this argument.
description
Text saying what the widget shows. Omit to clear it.
Clear enough to supply this argument.
chart_mode
'time_series' plots over time, bucketed by time_bucket; 'categorical' plots one value per category. Omit to clear it.
Clear enough to supply this argument.
bar_mode
For bar charts with several series: 'stacked' or 'side_by_side'. Omit to clear it.
Clear enough to supply this argument.
aggregation
How each metric is summarized, any of 'count', 'average', 'sum', 'percent_of_total', 'p50', 'p90', 'p95', 'p99', 'percentiles', 'breakdown', 'distribution'; e.g. ['p50', 'p90', 'p95'] for latency or ['breakdown'] for a custom metric's pass rate. Omit to clear it.
Clear enough to supply this argument.
time_bucket
Bucket size for time-series charts: 'hour', 'day', 'week' or 'month'. Omit to clear it.
Clear enough to supply this argument.
group_by
Split the data into one series per value: 'agent', 'labels', 'tool_call', 'age', 'gender', 'simulation' (needs simulation_ids), or 'metadata:<path>' for a conversation metadata field (dot notation for nested keys). Omit to clear it.
Clear enough to supply this argument.
simulation_ids
Bluejay simulation ids, from list_simulations; required when group_by is 'simulation'. Omit to clear it.
Clear enough to supply this argument.
show_indeterminate
Also count conversations where the metric has no result, shown as an 'N/A' category. Omitting it resets it to false.
Clear enough to supply this argument.
filters
Extra filters, on top of the dashboard's agents, labels and time range, that restrict which conversations the widget counts. Each item is a filter object in the shape the Bluejay logs page uses. Omit to keep the current filters; pass [] to remove them.
Clear enough to supply this argument.
column_visibility
Observability table widgets only: {"<column>": true|false} to show or hide columns of the conversations table. Ignored for other widgets. Omit to keep the current setting.
Clear enough to supply this argument.
color_overrides
Per-series/per-slice colours as {"<label the chart draws>": "#rrggbb"}. Labels are matched case-insensitively; omitted labels keep the default palette. Omit to keep the current setting.
Clear enough to supply this argument.
center_label
Chart options. Pie: {"slice": "<label>", "clamp_pct": <0..50 exclusive>, "label": "<caption>"} for the donut hole; slice omitted uses the largest slice, and clamp_pct collapses the rounding edges, so 1 turns 99.6% into '>99%' and 0.4% into '<1%'. Numeric line or bar chart or histogram: {"benchmark": <number>} draws a dashed reference line at that value. KPI: {"compare_previous": false} hides the change against the previous period. {"unit": "pts"} is shown after values on metrics that have no unit of their own. Omit to keep the current setting.
Clear enough to supply this argument.
show_legend
Draw the colour key under pie, bar and line charts. Omit to keep the current setting.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Permanently delete a widget: it is removed from its dashboard and its metrics are deleted. This cannot be
undone; copy it first with duplicate_widget to keep it.
The dashboard and its other widgets are untouched. Needs edit access to the widget. Returns success, deleted and
widget_id.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
widget_id
The widget to delete, from get_dashboard or list_widgets.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the widget was deleted."
},
"success": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "True when the request was applied: the dashboard or widget was deleted, or the layouts were saved."
},
"widget_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The id of the deleted widget."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "delete_widget",
"title": "Delete widget",
"description": "Permanently delete a widget: it is removed from its dashboard and its metrics are deleted. This cannot be\nundone; copy it first with duplicate_widget to keep it.\n\nThe dashboard and its other widgets are untouched. Needs edit access to the widget. Returns success, deleted and\nwidget_id.",
"inputSchema": {
"type": "object",
"title": "delete_widgetArguments",
"required": [
"widget_id"
],
"properties": {
"widget_id": {
"type": "string",
"title": "Widget Id",
"description": "The widget to delete, from get_dashboard or list_widgets."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the widget was deleted."
},
"success": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "True when the request was applied: the dashboard or widget was deleted, or the layouts were saved."
},
"widget_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The id of the deleted widget."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Duplicate a widget ('Copy of <name>') with its metrics onto dashboard_id, which may be a
different dashboard from the one the source widget is on. The copy is independent of the source.
The source is unchanged. The copy has no layout, so it does not land on top of the source; place it with
update_dashboard_layout. Returns the new widget: its id, name, chart configuration and widget_metrics.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
widget_id
The widget to copy, from get_dashboard or list_widgets.
Clear enough to supply this argument.
dashboard_id
The dashboard the copy goes on, from list_dashboards. It may differ from the source widget's dashboard, but you need edit access to it and it must be in your current workspace.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Create an empty folder in your organization for grouping agents in the Bluejay app.
The folder is created in your current workspace; put agents in it with move_agent_to_folder. Fails if another
folder in the organization already has this name. Returns the new folder's id, name, organization_id and
created_at.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
name
Name for the new folder, as shown in the Bluejay app's agent list. It must not match the name of another folder in your organization.
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's id (a UUID); pass it as folder_id to get_folder, update_folder, delete_folder or move_agent_to_folder."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's name, unique within the organization."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the folder was created, as an ISO 8601 timestamp; empty when unknown."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The organization that owns the folder."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_folder",
"title": "Create folder",
"description": "Create an empty folder in your organization for grouping agents in the Bluejay app.\n\nThe folder is created in your current workspace; put agents in it with move_agent_to_folder. Fails if another\nfolder in the organization already has this name. Returns the new folder's id, name, organization_id and\ncreated_at.",
"inputSchema": {
"type": "object",
"title": "create_folderArguments",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "Name for the new folder, as shown in the Bluejay app's agent list. It must not match the name of another folder in your organization."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's id (a UUID); pass it as folder_id to get_folder, update_folder, delete_folder or move_agent_to_folder."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's name, unique within the organization."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the folder was created, as an ISO 8601 timestamp; empty when unknown."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The organization that owns the folder."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Fetch one folder by id: its id, name, organization_id and created_at (also nested under 'data').
Read-only. It does not list the agents in the folder. Fails when the folder belongs to another organization or
to a workspace you cannot read.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
Input documentation gives an agent enough context to populate the arguments.
folder_id
The folder to fetch: its id (a UUID), from list_folders or create_folder.
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's id (a UUID); pass it as folder_id to get_folder, update_folder, delete_folder or move_agent_to_folder."
},
"data": {
"type": [
"object",
"array",
"null"
],
"description": "The same folder record as the top-level fields, nested."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's name, unique within the organization."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the folder was created, as an ISO 8601 timestamp; empty when unknown."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The organization that owns the folder."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "get_folder",
"title": "Get folder",
"description": "Fetch one folder by id: its id, name, organization_id and created_at (also nested under 'data').\n\nRead-only. It does not list the agents in the folder. Fails when the folder belongs to another organization or\nto a workspace you cannot read.",
"inputSchema": {
"type": "object",
"title": "get_folderArguments",
"required": [
"folder_id"
],
"properties": {
"folder_id": {
"type": "string",
"title": "Folder Id",
"description": "The folder to fetch: its id (a UUID), from list_folders or create_folder."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's id (a UUID); pass it as folder_id to get_folder, update_folder, delete_folder or move_agent_to_folder."
},
"data": {
"type": [
"object",
"array",
"null"
],
"description": "The same folder record as the top-level fields, nested."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's name, unique within the organization."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the folder was created, as an ISO 8601 timestamp; empty when unknown."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The organization that owns the folder."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List the agent folders in your organization, limited to the workspaces you can see.
Read-only. Returns 'folders', each with id, name, organization_id and created_at; pass an id to get_folder,
update_folder, delete_folder or move_agent_to_folder.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"folders": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's id (a UUID); pass it as folder_id to GET /v1/folder/{folder_id}, PUT /v1/update-folder/{folder_id}, DELETE /v1/folder/{folder_id} or PUT /v1/folders/move-agent."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's name, unique within the organization."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the folder was created, as an ISO 8601 timestamp; empty when unknown."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The organization that owns the folder."
}
},
"description": "A folder that groups agents in the Bluejay app's agent list.",
"additionalProperties": true
},
"properties": {},
"description": "A list. Each item: A folder that groups agents in the Bluejay app's agent list.",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "list_folders",
"title": "List agent folders",
"description": "List the agent folders in your organization, limited to the workspaces you can see.\n\nRead-only. Returns 'folders', each with id, name, organization_id and created_at; pass an id to get_folder,\nupdate_folder, delete_folder or move_agent_to_folder.",
"inputSchema": {
"type": "object",
"title": "list_foldersArguments",
"properties": {}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"folders": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's id (a UUID); pass it as folder_id to GET /v1/folder/{folder_id}, PUT /v1/update-folder/{folder_id}, DELETE /v1/folder/{folder_id} or PUT /v1/folders/move-agent."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's name, unique within the organization."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the folder was created, as an ISO 8601 timestamp; empty when unknown."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The organization that owns the folder."
}
},
"description": "A folder that groups agents in the Bluejay app's agent list.",
"additionalProperties": true
},
"properties": {},
"description": "A list. Each item: A folder that groups agents in the Bluejay app's agent list.",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Rename a folder, overwriting its current name.
Only the name changes; the agents in the folder stay where they are. Needs edit access to the folder's
workspace, and fails if another folder in your organization already has the new name. Returns the updated
folder's id, name, organization_id and created_at.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
folder_id
The folder to rename: its id (a UUID), from list_folders.
Clear enough to supply this argument.
name
The folder's new name. It must not match another folder in your organization.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's id (a UUID); pass it as folder_id to get_folder, update_folder, delete_folder or move_agent_to_folder."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's name, unique within the organization."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the folder was created, as an ISO 8601 timestamp; empty when unknown."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The organization that owns the folder."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "update_folder",
"title": "Update folder",
"description": "Rename a folder, overwriting its current name.\n\nOnly the name changes; the agents in the folder stay where they are. Needs edit access to the folder's\nworkspace, and fails if another folder in your organization already has the new name. Returns the updated\nfolder's id, name, organization_id and created_at.",
"inputSchema": {
"type": "object",
"title": "update_folderArguments",
"required": [
"folder_id",
"name"
],
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "The folder's new name. It must not match another folder in your organization."
},
"folder_id": {
"type": "string",
"title": "Folder Id",
"description": "The folder to rename: its id (a UUID), from list_folders."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's id (a UUID); pass it as folder_id to get_folder, update_folder, delete_folder or move_agent_to_folder."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The folder's name, unique within the organization."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the folder was created, as an ISO 8601 timestamp; empty when unknown."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The organization that owns the folder."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Permanently delete a folder. This cannot be undone.
The agents in it are not deleted: each one is first moved out to the root (no folder). Needs edit access to
the folder's workspace. Returns deleted, folder_id and status.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
folder_id
The folder to delete: its id (a UUID), from list_folders.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "'success' when the folder was deleted."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the folder was deleted."
},
"folder_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The id of the deleted folder."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "delete_folder",
"title": "Delete folder",
"description": "Permanently delete a folder. This cannot be undone.\n\nThe agents in it are not deleted: each one is first moved out to the root (no folder). Needs edit access to\nthe folder's workspace. Returns deleted, folder_id and status.",
"inputSchema": {
"type": "object",
"title": "delete_folderArguments",
"required": [
"folder_id"
],
"properties": {
"folder_id": {
"type": "string",
"title": "Folder Id",
"description": "The folder to delete: its id (a UUID), from list_folders."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "'success' when the folder was deleted."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the folder was deleted."
},
"folder_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The id of the deleted folder."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Put an agent in a folder, replacing the folder it was in, or move it to the root when folder_id is omitted.
Only the agent's folder changes; nothing else about the agent is touched. Needs edit access to the agent and
the folder. Returns agent_id, folder_id (null at the root) and status.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent to move: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
folder_id
The folder to put the agent in, from list_folders or create_folder; it must be in the agent's workspace. Omit or pass null to take the agent out of every folder (back to the root).
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "'success' when the agent was moved."
},
"agent_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The id of the agent that was moved."
},
"folder_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The folder the agent is now in; null when it was moved to the root."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "move_agent_to_folder",
"title": "Move agent to folder",
"description": "Put an agent in a folder, replacing the folder it was in, or move it to the root when folder_id is omitted.\n\nOnly the agent's folder changes; nothing else about the agent is touched. Needs edit access to the agent and\nthe folder. Returns agent_id, folder_id (null at the root) and status.",
"inputSchema": {
"type": "object",
"title": "move_agent_to_folderArguments",
"required": [
"agent_id"
],
"properties": {
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "The agent to move: its Bluejay agent id, from list_agents."
},
"folder_id": {
"anyOf": [
{
"type": "string",
"format": "uuid"
},
{
"type": "null"
}
],
"title": "Folder Id",
"default": null,
"description": "The folder to put the agent in, from list_folders or create_folder; it must be in the agent's workspace. Omit or pass null to take the agent out of every folder (back to the root)."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "'success' when the agent was moved."
},
"agent_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The id of the agent that was moved."
},
"folder_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The folder the agent is now in; null when it was moved to the root."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Save a new prompt version for an agent (POST /v1/agents/{agent_id}/versions).
Creates the agent's next version number with prompt_text as its prompt; existing versions are not
changed. The new version takes the latest label from the previous latest version, and an agent's
first version also gets production. Your own labels are attached too, but a label that already sits
on another version of this agent makes the whole call fail with a conflict: create the version
without it, then move the label here with add_prompt_version_labels and override_label.
The agent must be editable.
Returns the created version at the top level: id (its prompt_id), version, prompt_text,
commit_message, labels, metadata and agent_id.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent that owns the versions: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
prompt_text
The complete prompt text for the new version. It is stored as given, not merged with earlier versions.
Clear enough to supply this argument.
commit_message
Short note on what changed, shown in the version history; saved as 'new version' when omitted.
Clear enough to supply this argument.
labels
Your own labels to put on the new version, e.g. staging. latest is added automatically, and production too on the agent's first version. A label already on another version of this agent fails the call.
Clear enough to supply this argument.
metadata
Free-form JSON object stored with the version, e.g. the source commit or author; saved as {} when omitted.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The version's uuid: the prompt_id of get_prompt and delete_prompt."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"labels": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Labels on this version, e.g. latest and production."
},
"version": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The version number: the version of get_prompt_version and delete_prompt_version."
},
"agent_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The agent that owns this version."
},
"metadata": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Free-form JSON stored with this version."
},
"prompt_text": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The full prompt text stored in this version."
},
"commit_message": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The note saved with this version."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_prompt_version",
"title": "Create prompt version",
"description": "Save a new prompt version for an agent (POST /v1/agents/{agent_id}/versions).\n\nCreates the agent's next version number with prompt_text as its prompt; existing versions are not\nchanged. The new version takes the latest label from the previous latest version, and an agent's\nfirst version also gets production. Your own labels are attached too, but a label that already sits\non another version of this agent makes the whole call fail with a conflict: create the version\nwithout it, then move the label here with add_prompt_version_labels and override_label.\nThe agent must be editable.\n\nReturns the created version at the top level: id (its prompt_id), version, prompt_text,\ncommit_message, labels, metadata and agent_id.\n",
"inputSchema": {
"type": "object",
"title": "create_prompt_versionArguments",
"required": [
"agent_id",
"prompt_text"
],
"properties": {
"labels": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Labels",
"default": null,
"description": "Your own labels to put on the new version, e.g. staging. latest is added automatically, and production too on the agent's first version. A label already on another version of this agent fails the call."
},
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "The agent that owns the versions: its Bluejay agent id, from list_agents."
},
"metadata": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Metadata",
"default": null,
"description": "Free-form JSON object stored with the version, e.g. the source commit or author; saved as {} when omitted."
},
"prompt_text": {
"type": "string",
"title": "Prompt Text",
"description": "The complete prompt text for the new version. It is stored as given, not merged with earlier versions."
},
"commit_message": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Commit Message",
"default": null,
"description": "Short note on what changed, shown in the version history; saved as 'new version' when omitted."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The version's uuid: the prompt_id of get_prompt and delete_prompt."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"labels": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Labels on this version, e.g. latest and production."
},
"version": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The version number: the version of get_prompt_version and delete_prompt_version."
},
"agent_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The agent that owns this version."
},
"metadata": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Free-form JSON stored with this version."
},
"prompt_text": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The full prompt text stored in this version."
},
"commit_message": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The note saved with this version."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Fetch one prompt version of an agent by its uuid (GET /v1/agents/{agent_id}/versions/{prompt_id}).
Read-only. Use it when you hold a version's id; use get_prompt_version when you know its version
number instead. Returns the version at the top level: id, version, prompt_text, commit_message,
labels (e.g. latest, production), metadata and agent_id, and the same object again under data.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent that owns the versions: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
prompt_id
The version's uuid: the id field from list_prompt_versions or create_prompt_version.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
List an agent's prompt versions, newest first (GET /v1/agents/{agent_id}/versions).
Read-only. Filter to one version number or to the versions carrying a label, and cap the count with
limit. Returns versions: each with its id (prompt_id), version number, prompt_text, commit_message,
labels (e.g. latest, production) and metadata. Use the version number with get_prompt_version,
add_prompt_version_labels or delete_prompt_version.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent that owns the versions: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
label
Only return versions that carry this label, e.g. production, latest or one of your own; the text must match exactly. Omit for all versions.
Clear enough to supply this argument.
version
Return only this version number; when set, label and limit are ignored. Omit to list versions.
Clear enough to supply this argument.
limit
Most versions to return, counted from the newest; 50 when omitted.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"versions": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The version's uuid: the prompt_id of GET /v1/agents/{agent_id}/versions/{prompt_id} and DELETE /v1/agents/{agent_id}/versions/{prompt_id}."
},
"labels": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Labels on this version, e.g. latest and production."
},
"version": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The version number: the version of GET /v1/agents/{agent_id}/versions/{version} and DELETE /v1/agents/{agent_id}/versions/{version}."
},
"agent_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The agent that owns this version."
},
"metadata": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Free-form JSON stored with this version."
},
"prompt_text": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The full prompt text stored in this version."
},
"commit_message": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The note saved with this version."
}
},
"description": "One prompt version of an agent: its prompt text, version number and the labels on it.",
"additionalProperties": true
},
"properties": {},
"description": "A list. Each item: One prompt version of an agent: its prompt text, version number and the labels on it.",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "list_prompt_versions",
"title": "List agent prompt versions",
"description": "List an agent's prompt versions, newest first (GET /v1/agents/{agent_id}/versions).\n\nRead-only. Filter to one version number or to the versions carrying a label, and cap the count with\nlimit. Returns versions: each with its id (prompt_id), version number, prompt_text, commit_message,\nlabels (e.g. latest, production) and metadata. Use the version number with get_prompt_version,\nadd_prompt_version_labels or delete_prompt_version.\n",
"inputSchema": {
"type": "object",
"title": "list_prompt_versionsArguments",
"required": [
"agent_id"
],
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Label",
"default": null,
"description": "Only return versions that carry this label, e.g. production, latest or one of your own; the text must match exactly. Omit for all versions."
},
"limit": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Limit",
"default": null,
"description": "Most versions to return, counted from the newest; 50 when omitted."
},
"version": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Version",
"default": null,
"description": "Return only this version number; when set, label and limit are ignored. Omit to list versions."
},
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "The agent that owns the versions: its Bluejay agent id, from list_agents."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"versions": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The version's uuid: the prompt_id of GET /v1/agents/{agent_id}/versions/{prompt_id} and DELETE /v1/agents/{agent_id}/versions/{prompt_id}."
},
"labels": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Labels on this version, e.g. latest and production."
},
"version": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The version number: the version of GET /v1/agents/{agent_id}/versions/{version} and DELETE /v1/agents/{agent_id}/versions/{version}."
},
"agent_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The agent that owns this version."
},
"metadata": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Free-form JSON stored with this version."
},
"prompt_text": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The full prompt text stored in this version."
},
"commit_message": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The note saved with this version."
}
},
"description": "One prompt version of an agent: its prompt text, version number and the labels on it.",
"additionalProperties": true
},
"properties": {},
"description": "A list. Each item: One prompt version of an agent: its prompt text, version number and the labels on it.",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
List an agent's prompt versions, optionally only those carrying one label (GET /v1/agents/{agent_id}/versions).
Read-only; changes nothing. An agent keeps one prompt per version, so each item here is a prompt
version: its id, version number, prompt_text, commit_message, labels and metadata. Pass
label='production' to find the prompt that is live. Returns prompts, newest first, at most 50.
list_prompt_versions reads the same data and can also pick one version number or set the limit.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent that owns the versions: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
label
Only return versions that carry this label, e.g. production, latest or one of your own; the text must match exactly. Omit for all versions.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"prompts": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The version's uuid: the prompt_id of GET /v1/agents/{agent_id}/versions/{prompt_id} and DELETE /v1/agents/{agent_id}/versions/{prompt_id}."
},
"labels": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Labels on this version, e.g. latest and production."
},
"version": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The version number: the version of GET /v1/agents/{agent_id}/versions/{version} and DELETE /v1/agents/{agent_id}/versions/{version}."
},
"agent_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The agent that owns this version."
},
"metadata": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Free-form JSON stored with this version."
},
"prompt_text": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The full prompt text stored in this version."
},
"commit_message": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The note saved with this version."
}
},
"description": "One prompt version of an agent: its prompt text, version number and the labels on it.",
"additionalProperties": true
},
"properties": {},
"description": "A list. Each item: One prompt version of an agent: its prompt text, version number and the labels on it.",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "list_prompts",
"title": "List prompt versions by label",
"description": "List an agent's prompt versions, optionally only those carrying one label (GET /v1/agents/{agent_id}/versions).\n\nRead-only; changes nothing. An agent keeps one prompt per version, so each item here is a prompt\nversion: its id, version number, prompt_text, commit_message, labels and metadata. Pass\nlabel='production' to find the prompt that is live. Returns prompts, newest first, at most 50.\nlist_prompt_versions reads the same data and can also pick one version number or set the limit.\n",
"inputSchema": {
"type": "object",
"title": "list_promptsArguments",
"required": [
"agent_id"
],
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Label",
"default": null,
"description": "Only return versions that carry this label, e.g. production, latest or one of your own; the text must match exactly. Omit for all versions."
},
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "The agent that owns the versions: its Bluejay agent id, from list_agents."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"prompts": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The version's uuid: the prompt_id of GET /v1/agents/{agent_id}/versions/{prompt_id} and DELETE /v1/agents/{agent_id}/versions/{prompt_id}."
},
"labels": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Labels on this version, e.g. latest and production."
},
"version": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The version number: the version of GET /v1/agents/{agent_id}/versions/{version} and DELETE /v1/agents/{agent_id}/versions/{version}."
},
"agent_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The agent that owns this version."
},
"metadata": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Free-form JSON stored with this version."
},
"prompt_text": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The full prompt text stored in this version."
},
"commit_message": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The note saved with this version."
}
},
"description": "One prompt version of an agent: its prompt text, version number and the labels on it.",
"additionalProperties": true
},
"properties": {},
"description": "A list. Each item: One prompt version of an agent: its prompt text, version number and the labels on it.",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Fetch one prompt version of an agent by its version number (GET /v1/agents/{agent_id}/versions/{version}).
Read-only. Returns the version at the top level: id, version, prompt_text (the full prompt),
commit_message, labels (e.g. latest, production), metadata and agent_id, and the same object again
under data. Use get_prompt instead when you hold the version's uuid.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent that owns the versions: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
version
The version's number: the version field from list_prompt_versions or create_prompt_version.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Permanently delete one prompt version of an agent, addressed by its uuid (DELETE /v1/agents/{agent_id}/versions/{prompt_id}).
Irreversible: the version and its prompt text are removed outright (not kept in Recently Deleted).
Its labels are detached, not deleted. Refused when it is the agent's only version or carries the
production label (move production first with add_prompt_version_labels and override_label). If it
carried latest, latest moves to the highest remaining version. Confirm with the user before calling.
Returns deleted_id, deleted_version, new_latest_id, deleted=true and the prompt_id you passed.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent that owns the versions: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
prompt_id
The version's uuid: the id field from list_prompt_versions or create_prompt_version.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the version was deleted."
},
"prompt_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The prompt_id you passed."
},
"deleted_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Uuid of the version that was deleted."
},
"new_latest_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Uuid of the version that now carries latest when the deleted one had it; null otherwise."
},
"deleted_version": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Number of the version that was deleted."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "delete_prompt",
"title": "Delete prompt",
"description": "Permanently delete one prompt version of an agent, addressed by its uuid (DELETE /v1/agents/{agent_id}/versions/{prompt_id}).\n\nIrreversible: the version and its prompt text are removed outright (not kept in Recently Deleted).\nIts labels are detached, not deleted. Refused when it is the agent's only version or carries the\nproduction label (move production first with add_prompt_version_labels and override_label). If it\ncarried latest, latest moves to the highest remaining version. Confirm with the user before calling.\n\nReturns deleted_id, deleted_version, new_latest_id, deleted=true and the prompt_id you passed.\n",
"inputSchema": {
"type": "object",
"title": "delete_promptArguments",
"required": [
"agent_id",
"prompt_id"
],
"properties": {
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "The agent that owns the versions: its Bluejay agent id, from list_agents."
},
"prompt_id": {
"type": "string",
"title": "Prompt Id",
"description": "The version's uuid: the id field from list_prompt_versions or create_prompt_version."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the version was deleted."
},
"prompt_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The prompt_id you passed."
},
"deleted_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Uuid of the version that was deleted."
},
"new_latest_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Uuid of the version that now carries latest when the deleted one had it; null otherwise."
},
"deleted_version": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Number of the version that was deleted."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Permanently delete one prompt version of an agent, addressed by its number (DELETE /v1/agents/{agent_id}/versions/{version}).
Irreversible: the version and its prompt text are removed outright (not kept in Recently Deleted).
Its labels are detached, not deleted. Refused when it is the agent's only version or carries the
production label (move production first with add_prompt_version_labels and override_label). If it
carried latest, latest moves to the highest remaining version. Confirm with the user before calling.
Returns deleted_id, deleted_version, new_latest_id, deleted=true and the version you passed.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent that owns the versions: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
version
The version's number: the version field from list_prompt_versions or create_prompt_version.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the version was deleted."
},
"version": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The version number you passed."
},
"deleted_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Uuid of the version that was deleted."
},
"new_latest_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Uuid of the version that now carries latest when the deleted one had it; null otherwise."
},
"deleted_version": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Number of the version that was deleted."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "delete_prompt_version",
"title": "Delete prompt version",
"description": "Permanently delete one prompt version of an agent, addressed by its number (DELETE /v1/agents/{agent_id}/versions/{version}).\n\nIrreversible: the version and its prompt text are removed outright (not kept in Recently Deleted).\nIts labels are detached, not deleted. Refused when it is the agent's only version or carries the\nproduction label (move production first with add_prompt_version_labels and override_label). If it\ncarried latest, latest moves to the highest remaining version. Confirm with the user before calling.\n\nReturns deleted_id, deleted_version, new_latest_id, deleted=true and the version you passed.\n",
"inputSchema": {
"type": "object",
"title": "delete_prompt_versionArguments",
"required": [
"agent_id",
"version"
],
"properties": {
"version": {
"type": "integer",
"title": "Version",
"description": "The version's number: the version field from list_prompt_versions or create_prompt_version."
},
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "The agent that owns the versions: its Bluejay agent id, from list_agents."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the version was deleted."
},
"version": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The version number you passed."
},
"deleted_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Uuid of the version that was deleted."
},
"new_latest_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Uuid of the version that now carries latest when the deleted one had it; null otherwise."
},
"deleted_version": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Number of the version that was deleted."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Point labels at one prompt version of an agent (POST /v1/agents/{agent_id}/versions/{version}/labels).
A label names exactly one version per agent, so labels are how a version is promoted (production)
or tagged for lookup (e.g. staging). New label names are created; a label that already sits on
another version makes the call fail with a conflict unless override_label is 'true', in which case
it moves here and the other version loses it. Moving production changes which prompt is live. The
agent must be editable.
Returns labels: every label now on this version.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Resolve the mismatch between this description and its schema constraints.
agent_id
The agent that owns the versions: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
version
The version's number: the version field from list_prompt_versions or create_prompt_version.
Clear enough to supply this argument.
labels
Labels to add or remove, e.g. ['production'] or ['staging'], matched to existing labels ignoring case. Adding ignores latest, which is managed automatically, and an empty list adds nothing. Removing never detaches production (move it to another version instead) or latest from the newest version, and an empty list removes every other label.
Clear enough to supply this argument.
override_label
When adding: true moves a label that already sits on another version of this agent onto this one, which is how a version is promoted to production; false fails on such a conflict with 409. Ignored when removing.
Resolve the mismatch between this description and its schema constraints.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"labels": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "Every label on this version, e.g. latest and production.",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "add_prompt_version_labels",
"title": "Add prompt version labels",
"description": "Point labels at one prompt version of an agent (POST /v1/agents/{agent_id}/versions/{version}/labels).\n\nA label names exactly one version per agent, so labels are how a version is promoted (production)\nor tagged for lookup (e.g. staging). New label names are created; a label that already sits on\nanother version makes the call fail with a conflict unless override_label is 'true', in which case\nit moves here and the other version loses it. Moving production changes which prompt is live. The\nagent must be editable.\n\nReturns labels: every label now on this version.\n",
"inputSchema": {
"type": "object",
"title": "add_prompt_version_labelsArguments",
"required": [
"agent_id",
"version"
],
"properties": {
"labels": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Labels",
"default": null,
"description": "Labels to add or remove, e.g. ['production'] or ['staging'], matched to existing labels ignoring case. Adding ignores latest, which is managed automatically, and an empty list adds nothing. Removing never detaches production (move it to another version instead) or latest from the newest version, and an empty list removes every other label."
},
"version": {
"type": "integer",
"title": "Version",
"description": "The version's number: the version field from list_prompt_versions or create_prompt_version."
},
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "The agent that owns the versions: its Bluejay agent id, from list_agents."
},
"override_label": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Override Label",
"default": null,
"description": "When adding: true moves a label that already sits on another version of this agent onto this one, which is how a version is promoted to production; false fails on such a conflict with 409. Ignored when removing."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"labels": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "Every label on this version, e.g. latest and production.",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
List the labels on one prompt version of an agent (GET /v1/agents/{agent_id}/versions/{version}/labels).
Read-only. Returns labels, e.g. ['latest', 'production'], so you can tell whether this version is
the live (production) or newest (latest) one. Fails with not found when the version does not exist.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent that owns the versions: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
version
The version's number: the version field from list_prompt_versions or create_prompt_version.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"labels": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "Every label on this version, e.g. latest and production.",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "get_prompt_version_labels",
"title": "Get prompt version labels",
"description": "List the labels on one prompt version of an agent (GET /v1/agents/{agent_id}/versions/{version}/labels).\n\nRead-only. Returns labels, e.g. ['latest', 'production'], so you can tell whether this version is\nthe live (production) or newest (latest) one. Fails with not found when the version does not exist.\n",
"inputSchema": {
"type": "object",
"title": "get_prompt_version_labelsArguments",
"required": [
"agent_id",
"version"
],
"properties": {
"version": {
"type": "integer",
"title": "Version",
"description": "The version's number: the version field from list_prompt_versions or create_prompt_version."
},
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "The agent that owns the versions: its Bluejay agent id, from list_agents."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"labels": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "Every label on this version, e.g. latest and production.",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Detach labels from one prompt version of an agent (DELETE /v1/agents/{agent_id}/versions/{version}/labels).
The label names stay available for other versions. production is never removed this way (move it
to another version with add_prompt_version_labels instead), and latest always stays on the newest
version. The agent must be editable.
Caution: the API reads the labels to remove from the request body, but this tool sends them as query
parameters, so today the API ignores labels and detaches EVERY label on the version except
production (and latest on the newest version), whatever you pass. Confirm with the user before
calling. Returns labels (what is left on the version) and deleted=true.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Explain the meaning of this value, not just its name.
agent_id
The agent that owns the versions: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
version
The version's number: the version field from list_prompt_versions or create_prompt_version.
Clear enough to supply this argument.
labels
The labels you mean to remove. Currently not applied: the API ignores this value and detaches every label except production (see the tool description).
Clear enough to supply this argument.
override_label
Has no effect on removal; the API ignores it.
Explain the meaning of this value, not just its name.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"labels": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "Every label on this version, e.g. latest and production.",
"additionalProperties": true
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the request succeeded."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "delete_prompt_version_labels",
"title": "Delete prompt version labels",
"description": "Detach labels from one prompt version of an agent (DELETE /v1/agents/{agent_id}/versions/{version}/labels).\n\nThe label names stay available for other versions. production is never removed this way (move it\nto another version with add_prompt_version_labels instead), and latest always stays on the newest\nversion. The agent must be editable.\n\nCaution: the API reads the labels to remove from the request body, but this tool sends them as query\nparameters, so today the API ignores labels and detaches EVERY label on the version except\nproduction (and latest on the newest version), whatever you pass. Confirm with the user before\ncalling. Returns labels (what is left on the version) and deleted=true.\n",
"inputSchema": {
"type": "object",
"title": "delete_prompt_version_labelsArguments",
"required": [
"agent_id",
"version"
],
"properties": {
"labels": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Labels",
"default": null,
"description": "The labels you mean to remove. Currently not applied: the API ignores this value and detaches every label except production (see the tool description)."
},
"version": {
"type": "integer",
"title": "Version",
"description": "The version's number: the version field from list_prompt_versions or create_prompt_version."
},
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "The agent that owns the versions: its Bluejay agent id, from list_agents."
},
"override_label": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Override Label",
"default": null,
"description": "Has no effect on removal; the API ignores it."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"labels": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "Every label on this version, e.g. latest and production.",
"additionalProperties": true
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the request succeeded."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Create a free-standing label on an agent: a named tag not attached to any prompt version or knowledge base.
Labels tag an agent's conversations, and dashboards can split charts by them (widget group_by 'labels').
Needs edit access to the agent. Fails when the agent already has a label with this text (case-insensitive) or
the text is 'latest' or 'production'; the production label is moved between prompt versions, not created here.
Returns the new label: id, label_text, agent_id, created_at and color.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
agent_id
The agent that owns the label: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
label_text
The label's text, e.g. 'billing'. Must not match another label of this agent (case-insensitive), and 'latest' and 'production' are reserved.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The label's id (a UUID). For a free-standing label, pass it as label_id to get_label, update_label or delete_label."
},
"color": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The label's display colour, when one is set."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"agent_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The agent the label belongs to."
},
"prompt_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Deprecated alias of agent_version_id, kept for older clients."
},
"created_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When the label was created, as an ISO 8601 timestamp."
},
"label_text": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The label's text."
},
"agent_version_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The prompt version the label is attached to; null for a free-standing label."
},
"knowledge_base_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The knowledge base the label is attached to; null for a free-standing label."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_label",
"title": "Create label",
"description": "Create a free-standing label on an agent: a named tag not attached to any prompt version or knowledge base.\n\nLabels tag an agent's conversations, and dashboards can split charts by them (widget group_by 'labels').\nNeeds edit access to the agent. Fails when the agent already has a label with this text (case-insensitive) or\nthe text is 'latest' or 'production'; the production label is moved between prompt versions, not created here.\nReturns the new label: id, label_text, agent_id, created_at and color.",
"inputSchema": {
"type": "object",
"title": "create_labelArguments",
"required": [
"agent_id",
"label_text"
],
"properties": {
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "The agent that owns the label: its Bluejay agent id, from list_agents."
},
"label_text": {
"type": "string",
"title": "Label Text",
"description": "The label's text, e.g. 'billing'. Must not match another label of this agent (case-insensitive), and 'latest' and 'production' are reserved."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The label's id (a UUID). For a free-standing label, pass it as label_id to get_label, update_label or delete_label."
},
"color": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The label's display colour, when one is set."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"agent_id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "The agent the label belongs to."
},
"prompt_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Deprecated alias of agent_version_id, kept for older clients."
},
"created_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When the label was created, as an ISO 8601 timestamp."
},
"label_text": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The label's text."
},
"agent_version_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The prompt version the label is attached to; null for a free-standing label."
},
"knowledge_base_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The knowledge base the label is attached to; null for a free-standing label."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
List an agent's free-standing labels, optionally filtered by a text substring.
Read-only. Labels attached to a prompt version or knowledge base are left out (get_prompt_version_labels
covers prompt versions). Returns 'labels', each with id, label_text, agent_id, created_at and color; pass an
id to get_label, update_label or delete_label.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent that owns the label: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
q
Only return labels whose text contains this, ignoring case. Omit to list all of the agent's labels.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Fetch one free-standing label of an agent: its id, label_text, agent_id, created_at and color (also nested
under 'data').
Read-only. A label that belongs to a different agent, or is attached to a prompt version or knowledge base,
comes back as not found.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent that owns the label: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
label_id
The label to fetch: its id (a UUID), from list_labels or create_label.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Rename a free-standing label of an agent, overwriting its text. The label keeps its id.
Needs edit access to the agent. Fails for the 'latest' and 'production' labels, for labels attached to a
prompt version or knowledge base, and when another label of the agent already has the new text. Returns the
updated label: id, label_text, agent_id, created_at and color.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
agent_id
The agent that owns the label: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
label_id
The label to rename: its id (a UUID), from list_labels.
Clear enough to supply this argument.
label_text
The label's new text. Must not match another label of this agent (case-insensitive), and 'latest' and 'production' are reserved.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Permanently delete a free-standing label of an agent. This cannot be undone.
Needs edit access to the agent. The 'latest' and 'production' labels, and labels attached to a prompt version
or knowledge base, cannot be deleted here. Returns deleted, label_id and deleted_id.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent that owns the label: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
label_id
The label to delete: its id (a UUID), from list_labels.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Create one or many custom metrics in ONE call (POST /v1/create-custom-metrics).
Pass a single-item list to create one. Each item is a full metric definition;
response_type decides which of min_value/max_value, enum_options and json_schema
are required. Adds new metrics to the org and attaches each to the agents in its
agent_ids; existing metrics are not changed.
Returns metrics: each created metric with its new id (pass it to get_custom_metric,
update_custom_metric, create_lab or evaluate), name, prompt, metric_type,
response_type, settings, agent_ids, source and the rest of its stored configuration.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Input documentation gives an agent enough context to populate the arguments.
$defs › NewCustomMetric › name
Metric name, shown in results and dashboards
Clear enough to supply this argument.
$defs › NewCustomMetric › prompt
The LLM judge's instruction: what to look for in the conversation; omit for a metric_type that does not judge
Clear enough to supply this argument.
$defs › NewCustomMetric › response_type
Verdict shape the judge must return (pass_fail, quantitative, enum, json, ...)
Clear enough to supply this argument.
$defs › NewCustomMetric › agent_ids
Agents this metric is evaluated on; omit to leave it unattached
Clear enough to supply this argument.
$defs › NewCustomMetric › min_value
Low end of the score range; required when response_type is quantitative
Clear enough to supply this argument.
$defs › NewCustomMetric › max_value
High end of the score range; required when response_type is quantitative
Clear enough to supply this argument.
$defs › NewCustomMetric › enum_options
The allowed verdict strings; required when response_type is enum
Clear enough to supply this argument.
$defs › NewCustomMetric › json_schema
Schema of the object the judge must return; required when response_type is json
Clear enough to supply this argument.
$defs › NewCustomMetric › metric_type
Metric kind; omit for llm_judge. Set 'tool_call' to check for tool_names instead of judging, 'trace_span' to pass when the linked OpenTelemetry trace contains every span in settings.span_names (or none of them, with settings.condition 'does_not_contain'), or 'transfer_landed' to prove a handoff reached one of your digital humans
Clear enough to supply this argument.
$defs › NewCustomMetric › settings
Type-specific and gating configuration. Per-type keys such as the pattern a transcript_regex metric matches, a trace_span metric's {"span_names": [<span names to look for>], "condition": "contains" (default) | "does_not_contain"}, or a transfer_landed metric's {"receiver_test_case_id": <the digital human that answers the transferred call, a positive id and the only required key>, "window_seconds": <optional, how late that call may land, default 180, at most 900>}, plus two that any type accepts. `fire_conditions` evaluates the metric only when the conversation matches: {"join": "and"|"or", "groups": [{"join": ..., "conditions": [{"type": "metric", "metric_id": ..., "operator": "equals"|"greater_than"|..., "value": ...} | {"type": "tool_call", "tool_name": ...} | {"type": "workflow_node", "node_id": ...}]}]}. `composite` computes this metric from other metrics' results, with metric_type="composite" and no prompt: {"output_type": "quantitative"|"categorical", "variables": [{"metric_id": ..., "value_map": {label: number}}], "master_formula": ..., "rules": [{"output": ..., "conditions": {...}}]}, where master_formula is the one expression read for a quantitative output and rules are read for a categorical one, and value_map turns a categorical or boolean input into the number the formula can use. A formula reads each declared metric by its id in double quotes, e.g. round(100 * ("<metric id>" / 5)); a bare name is refused, and a rule condition names the metric_id it compares the same way. Every metric a gate or a composite reads must be one that always evaluates: referencing a composite, or a metric with its own fire conditions, is rejected because it may have no result to read.
Clear enough to supply this argument.
$defs › NewCustomMetric › tool_names
Tool names a tool_call metric checks for; requires metric_type='tool_call'
Clear enough to supply this argument.
$defs › NewCustomMetric › category
Grouping label used to organize metrics in the UI
Clear enough to supply this argument.
$defs › NewCustomMetric › tags
Free-form tags for filtering metrics
Clear enough to supply this argument.
$defs › NewCustomMetric › scoring_guidance
Extra rubric text appended to the judge prompt, e.g. how to weigh partial credit
Clear enough to supply this argument.
$defs › NewCustomMetric › eval_route
Which judge lane evaluates this metric: AUTO, TEXT (transcript) or AUDIO (recording)
Clear enough to supply this argument.
$defs › NewCustomMetric › model
Text judge model override; omit for gpt-6-luna
Clear enough to supply this argument.
$defs › NewCustomMetric › audio_model
Audio judge model override; omit for the org default
Clear enough to supply this argument.
$defs › NewCustomMetric › temperature
Judge sampling temperature
Clear enough to supply this argument.
$defs › NewCustomMetric › allow_not_applicable
When true the judge may answer not_applicable instead of forcing a verdict
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Fetch one custom metric's full definition by id (GET /v1/custom-metric/{metric_id}).
Read-only. Returns the metric at the top level: id, name, prompt (the judge's
instruction), summary, metric_type, response_type with min_value/max_value,
enum_options or json_schema, settings (type-specific config, fire_conditions,
composite), agent_ids it is attached to, scoring_guidance, eval_modality, model,
audio_model, temperature, allow_not_applicable, category, tags, source and
timestamps; and the same object again under data.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
Input documentation gives an agent enough context to populate the arguments.
metric_id
The metric's id (a uuid), from list_custom_metrics, create_custom_metrics, or a custom-metric alert's entity_field.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List custom metrics via GET /v1/custom-metrics.
Read-only. `agent_id` narrows the listing to the metrics attached to that one agent; omit
it for every metric in the org. page/page_size are 1-based pagination.
`source` ("custom" = the org's own, "standard" = Bluejay's builtins) filters the
org-wide listing; omit it for both. `total_count` is the number of matching
metrics across all pages, so a count needs one call with page_size=1.
Returns metrics (each with id, name, prompt, metric_type, response_type,
agent_ids, settings, source and the rest of its configuration), total_count and
total_pages. Use a metric's id with get_custom_metric, update_custom_metric or create_lab.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Only metrics attached to this agent: its Bluejay agent id (from list_agents). Omit for every metric in the org.
Clear enough to supply this argument.
page
Which page to return, counting from 1; 1 when omitted.
Clear enough to supply this argument.
page_size
Metrics per page, at most 100; 50 when omitted.
Clear enough to supply this argument.
source
Narrow the org-wide listing: custom for the org's own metrics, standard for Bluejay's builtins. Omit for both. Ignored when agent_id is set.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Change fields of one existing custom metric in place (PUT /v1/update-custom-metric/{metric_id}).
Partial update: only the fields you pass are written. Omitted fields keep their stored
value, and no field can be cleared to null with this tool. What you pass overwrites the
old value, which is not kept: settings replaces the whole settings object, agent_ids
replaces every agent attachment ([] detaches the metric from all agents), and moving
response_type off enum or json drops enum_options or json_schema. The change applies to
evaluations run after it; results already produced are not re-scored. Bluejay's standard
(builtin) metrics cannot be edited. Repeating the same call leaves the same end state.
Returns the updated metric at the top level: id, name, prompt, metric_type,
response_type, settings, agent_ids, source and the rest of its stored configuration.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
metric_id
The metric's id (a uuid), from list_custom_metrics, create_custom_metrics, or a custom-metric alert's entity_field.
Clear enough to supply this argument.
name
New display name, shown in results and dashboards.
Clear enough to supply this argument.
prompt
New instruction for the LLM judge: what to look for in the conversation (legacy alias: description).
Clear enough to supply this argument.
response_type
New verdict shape. Pair quantitative with min_value and max_value, enum with enum_options, json with json_schema; moving off enum or json drops the old enum_options or json_schema.
Clear enough to supply this argument.
agent_ids
Bluejay agent ids (from list_agents) to attach the metric to, replacing every current attachment; [] detaches it from all agents.
Clear enough to supply this argument.
min_value
New low end of a quantitative metric's score range.
Clear enough to supply this argument.
max_value
New high end of a quantitative metric's score range.
Clear enough to supply this argument.
category
New grouping label used to organize metrics in the UI.
Clear enough to supply this argument.
tags
New free-form tags, replacing the current ones.
Clear enough to supply this argument.
scoring_guidance
New rubric text appended to the judge prompt, e.g. how to weigh partial credit.
Clear enough to supply this argument.
model
Text judge model to use from now on.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
temperature
Judge sampling temperature to use from now on.
Clear enough to supply this argument.
enum_options
New allowed verdict strings for an enum metric, replacing the current list.
Clear enough to supply this argument.
tool_names
Tool names a tool_call metric checks for. Only used when the metric's settings hold no tool_names yet; to change existing ones send settings with a new tool_names list.
Clear enough to supply this argument.
json_schema
New schema of the object the judge must return, for a json metric.
Clear enough to supply this argument.
allow_not_applicable
true lets the judge answer not_applicable instead of forcing a verdict; false forces a verdict.
Clear enough to supply this argument.
metric_type
New metric kind, e.g. llm_judge, tool_call, trace_span, transcript_regex, transfer_landed or composite. Must be sent whenever the settings you send belong to a different kind than the metric has (legacy alias: type).
Clear enough to supply this argument.
settings
Replaces the metric's whole settings object, so include every key to keep. Same shape as settings on create_custom_metrics: per-kind keys (tool_call {tool_names}, trace_span {span_names, condition}, transfer_landed {receiver_test_case_id}) plus fire_conditions and composite.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Delete one or many custom metrics in ONE call (POST /v1/delete-custom-metrics).
Pass a single-item list to delete one. Deleting a metric removes its future
evaluations, not the results it already produced. Deleted metrics move to Recently
Deleted (restorable in the Bluejay app for 30 days, then purged for good), and their
agent attachments are removed at once; a restore does not re-attach them. Confirm
with the user before calling. Returns deleted_count and
deleted_metric_ids; every id must exist, be writable and not be a builtin, or
the whole call is rejected and nothing is deleted.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
custom_metric_ids
Ids (uuids) of the metrics to delete, from list_custom_metrics; a single id deletes one metric. Each id may appear once.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "How many metrics were deleted."
},
"deleted_metric_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "IDs of metrics that were deleted",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "delete_custom_metrics",
"title": "Delete custom metrics",
"description": "Delete one or many custom metrics in ONE call (POST /v1/delete-custom-metrics).\n\nPass a single-item list to delete one. Deleting a metric removes its future\nevaluations, not the results it already produced. Deleted metrics move to Recently\nDeleted (restorable in the Bluejay app for 30 days, then purged for good), and their\nagent attachments are removed at once; a restore does not re-attach them. Confirm\nwith the user before calling. Returns deleted_count and\ndeleted_metric_ids; every id must exist, be writable and not be a builtin, or\nthe whole call is rejected and nothing is deleted.\n",
"inputSchema": {
"type": "object",
"title": "delete_custom_metricsArguments",
"required": [
"custom_metric_ids"
],
"properties": {
"custom_metric_ids": {
"type": "array",
"items": {
"type": "string"
},
"title": "Custom Metric Ids",
"description": "Ids (uuids) of the metrics to delete, from list_custom_metrics; a single id deletes one metric. Each id may appear once."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "How many metrics were deleted."
},
"deleted_metric_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "IDs of metrics that were deleted",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Browse Bluejay's library of ready-made metric templates, newest first (GET /v1/custom-metric-templates).
Read-only. Templates are Bluejay-authored starting points, not metrics in your org;
to use one, pass its fields and its id as template_id to create_custom_metrics.
Returns templates (each with id, name, prompt, summary, category, response_type,
metric_type, settings, scoring_guidance and the rest of its definition) and total,
the number of matching templates across all pages.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page
Which page to return, counting from 1; 1 when omitted.
Clear enough to supply this argument.
page_size
Templates per page, at most 100; 24 when omitted.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
search
Text to look for in template names and prompts, ignoring case.
Clear enough to supply this argument.
category
Only templates in this library category; must match a template's category exactly.
Clear enough to supply this argument.
source
Currently ignored: the API does not filter templates by source (every template is Bluejay-authored).
Clear enough to supply this argument.
response_type
Only templates with this verdict shape, e.g. pass_fail, quantitative or enum.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Fetch one metric library template by id (GET /v1/custom-metric-template/{template_id}).
Read-only. Returns template: the Bluejay-authored definition (name, prompt, summary,
category, response_type, metric_type, settings, min_value/max_value, enum_options,
json_schema, scoring_guidance, model and other judge settings). To turn it into a
metric in your org, pass those fields with template_id to create_custom_metrics.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
template_id
The template's id (a uuid), from list_custom_metric_templates.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
List the organization's alerts (GET /v1/alerts), newest first, in the workspaces you can see.
Returns `alerts`: each alert's configuration (entity_type, entity_field, operator,
comparison_value, source_scope, notification_channels, agent and simulation scope) and its
state: in_alert (currently firing), trigger_count and last_triggered_at. For a custom_metric
alert, entity_field is the custom metric UUID; read the metric with get_custom_metric. To find
the custom metric firing the most alerts, keep entity_type == 'custom_metric' and sort by
trigger_count descending. Use get_alert_results to see the conversations an alert fired on.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
source_scope
Only return alerts whose source_scope is this value: observability, simulation, or all (alerts that fire from both sources). Omit to return every alert.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Get an alert's recent triggers (fired events) via GET /v1/alerts/{alert_id}/results. Read-only.
Use this to review what an alert has been firing on. Results are newest-first
and page-paginated. Each event resolves to the entity that caused it: for
simulation alerts the simulation + run (+ the sim conversation as test_result_id);
for observability alerts the call. ``actual_value`` / ``expected_value`` /
``operator_used`` describe the breach. Returns `results` plus total_count, page,
page_size, items_in_page and total_pages.
For a custom-metric alert, the resolved obs/sim conversations are the candidate
cases for false-alarm analysis: read the metric with get_custom_metric (the
alert's entity_field is the metric UUID), then pull the suspect cases into a
Metrics Lab with create_lab to inspect the metric's verdicts and improve it.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
alert_id
The alert whose fired events to read: its id, from list_alerts or create_alert.
Clear enough to supply this argument.
source
Only return events from simulation runs (simulation) or live calls (observability). Omit to read every source the alert is scoped to.
Clear enough to supply this argument.
page
Page to return, starting at 1. Omit for the first page.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Create an alert (POST /v1/create-alert) in your current workspace that watches one metric,
goal, metadata field or failure status across your agents' conversations, and sends real
notifications to notification_channels (email, Slack, webhook, PagerDuty, Better Stack,
incident.io) whenever it fires.
The condition compares each conversation's entity_field value with comparison_value using
operator. An observability or all alert fires when min_events matching conversations (or that
percent) land within threshold_time_interval seconds, or within the last sample_size
conversations. A simulation alert is judged per completed simulation run and fires when each of
the last threshold_time_interval runs met the condition.
Prerequisites: agent_ids must be your agents in this workspace, and simulation_id needs
source_scope 'simulation' and a simulation in this workspace.
Returns the stored alert at the top level: its id (pass as alert_id to update_alert,
delete_alert and get_alert_results) and the full resolved configuration, including the defaults
the API filled in, plus in_alert and trigger_count.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Input documentation gives an agent enough context to populate the arguments.
name
Name that identifies the alert, e.g. "Low CSAT on support agent".
Clear enough to supply this argument.
entity_type
What the alert watches: custom_metric (one of your custom metrics), standard_metric (a built-in metric), custom_goal, metadata_field (a conversation metadata key) or system_failure (simulation conversations ending in a given status). Decides what entity_field holds.
Clear enough to supply this argument.
entity_field
The exact thing watched, per entity_type: custom_metric takes the custom metric's UUID (from list_custom_metrics); standard_metric the built-in metric's UUID; metadata_field the metadata key as a dot path with no "metadata:" prefix; system_failure "status:<bucket>", the conversation status to count.
Clear enough to supply this argument.
operator
How each conversation's value is compared with comparison_value: equals, not_equals, greater_than, less_than, greater_than_or_equal, less_than_or_equal, contains or not_contains.
Clear enough to supply this argument.
comparison_value
The threshold to compare against, always as a string, e.g. "0.8", "true" or "billing".
Clear enough to supply this argument.
description
Free-text note on what the alert is for.
Clear enough to supply this argument.
is_enabled
false creates the alert paused. Omit to create it enabled.
Clear enough to supply this argument.
notification_channels
Where to send notifications when the alert fires, as a list of {"type", "target"}. type is email, slack, webhook, pagerduty, betterstack or incidentio; target is the email address, Slack channel, webhook URL or PagerDuty routing key, and is ignored for betterstack and incidentio, which use the organization's saved credentials. Omit for no notifications.
Clear enough to supply this argument.
applies_to_all_agents
true (the default) watches every agent's conversations; false limits the alert to agent_ids.
Clear enough to supply this argument.
agent_ids
Bluejay agent ids (from list_agents) the alert is limited to. Required when applies_to_all_agents is false.
Clear enough to supply this argument.
simulation_id
Limit a simulation alert to one simulation (id from list_simulations). Only valid when source_scope is simulation. Omit to watch all simulations.
Clear enough to supply this argument.
evaluation_scope
How a simulation alert is evaluated; per_simulation_run (judge each completed run) is the supported value.
Clear enough to supply this argument.
aggregation
How a simulation alert combines the conversation values in a run into one value: none, avg, max, min or count.
Clear enough to supply this argument.
threshold_time_interval
The window the alert is judged over. For observability or all alerts, seconds of recent conversations; for simulation alerts, the number K of recent completed runs, and it fires when all K met the condition. Omit for 600 seconds, or 1 run for a simulation alert.
Clear enough to supply this argument.
min_events
For observability or all alerts, how many conversations matching the condition within the window trip the alert: a count, or a percent of the window's conversations when min_events_type is percentage. Ignored (stored as null) for simulation alerts. Omit for 10.
Clear enough to supply this argument.
min_events_type
Whether min_events is a count of events (events) or a percent of conversations, 0 to 100 (percentage). Omit for events.
Clear enough to supply this argument.
source_scope
Which conversations fire the alert: observability (live calls sent to Bluejay), simulation (simulation runs) or all (both). Omit for all.
Clear enough to supply this argument.
sample_size
Evaluate over the most recent N conversations instead of a time window (minimum 30). NULL keeps the time-window behavior; the alert never fires with fewer than N conversations.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The alert's id; pass it as alert_id to update_alert, delete_alert or get_alert_results."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The alert's name."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"agents": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Agent ids the alert is limited to; null when applies_to_all_agents is true."
},
"in_alert": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Whether the alert is currently firing."
},
"operator": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "How each value is compared with comparison_value."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "ISO 8601 creation time."
},
"created_by": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "User id of the creator."
},
"is_enabled": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Whether the alert is evaluated; false means paused."
},
"min_events": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Matching events needed in the window to fire (count or percent, per min_events_type); null for simulation alerts."
},
"updated_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "ISO 8601 time of the last change."
},
"updated_by": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "User id of the last editor."
},
"aggregation": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How a simulation alert combines a run's conversation values: none, avg, max, min or count."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Free-text note about the alert."
},
"entity_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the alert watches: custom_metric, standard_metric, custom_goal, metadata_field or system_failure."
},
"sample_size": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Evaluated over the most recent N conversations instead of a time window; null uses the window."
},
"entity_field": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The watched metric UUID, metadata key or status bucket, per entity_type."
},
"source_scope": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Which conversations fire it: all, observability or simulation."
},
"simulation_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Simulation a simulation alert is limited to; null for all simulations."
},
"trigger_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "How many times the alert has fired."
},
"min_events_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "events (min_events is a count) or percentage."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Organization that owns the alert."
},
"simulation_name": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Name of simulation_id's simulation, if set."
},
"comparison_value": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The threshold value, as a string."
},
"evaluation_scope": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How a simulation alert is evaluated; per_simulation_run is the supported value."
},
"last_triggered_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "ISO 8601 time the alert last fired; null if never."
},
"applies_to_all_agents": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the alert watches every agent; false limits it to agents."
},
"notification_channels": {
"type": [
"array",
"object",
"null"
],
"items": {},
"properties": {},
"description": "Where notifications go, as a list of {type, target}: type is email, slack, webhook, pagerduty, betterstack or incidentio; target is the email address, Slack channel, webhook URL or PagerDuty routing key.",
"additionalProperties": true
},
"threshold_time_interval": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Window the alert is judged over: seconds for observability/all alerts, number of recent completed runs for simulation alerts."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_alert",
"title": "Create alert",
"description": "Create an alert (POST /v1/create-alert) in your current workspace that watches one metric,\ngoal, metadata field or failure status across your agents' conversations, and sends real\nnotifications to notification_channels (email, Slack, webhook, PagerDuty, Better Stack,\nincident.io) whenever it fires.\n\nThe condition compares each conversation's entity_field value with comparison_value using\noperator. An observability or all alert fires when min_events matching conversations (or that\npercent) land within threshold_time_interval seconds, or within the last sample_size\nconversations. A simulation alert is judged per completed simulation run and fires when each of\nthe last threshold_time_interval runs met the condition.\n\nPrerequisites: agent_ids must be your agents in this workspace, and simulation_id needs\nsource_scope 'simulation' and a simulation in this workspace.\n\nReturns the stored alert at the top level: its id (pass as alert_id to update_alert,\ndelete_alert and get_alert_results) and the full resolved configuration, including the defaults\nthe API filled in, plus in_alert and trigger_count.\n",
"inputSchema": {
"type": "object",
"title": "create_alertArguments",
"required": [
"name",
"entity_type",
"entity_field",
"operator",
"comparison_value"
],
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "Name that identifies the alert, e.g. \"Low CSAT on support agent\"."
},
"operator": {
"type": "string",
"title": "Operator",
"description": "How each conversation's value is compared with comparison_value: equals, not_equals, greater_than, less_than, greater_than_or_equal, less_than_or_equal, contains or not_contains."
},
"agent_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "integer"
}
},
{
"type": "null"
}
],
"title": "Agent Ids",
"default": null,
"description": "Bluejay agent ids (from list_agents) the alert is limited to. Required when applies_to_all_agents is false."
},
"is_enabled": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Is Enabled",
"default": null,
"description": "false creates the alert paused. Omit to create it enabled."
},
"min_events": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Min Events",
"default": null,
"description": "For observability or all alerts, how many conversations matching the condition within the window trip the alert: a count, or a percent of the window's conversations when min_events_type is percentage. Ignored (stored as null) for simulation alerts. Omit for 10."
},
"aggregation": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Aggregation",
"default": null,
"description": "How a simulation alert combines the conversation values in a run into one value: none, avg, max, min or count."
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description",
"default": null,
"description": "Free-text note on what the alert is for."
},
"entity_type": {
"type": "string",
"title": "Entity Type",
"description": "What the alert watches: custom_metric (one of your custom metrics), standard_metric (a built-in metric), custom_goal, metadata_field (a conversation metadata key) or system_failure (simulation conversations ending in a given status). Decides what entity_field holds."
},
"sample_size": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Sample Size",
"default": null,
"description": "Evaluate over the most recent N conversations instead of a time window (minimum 30). NULL keeps the time-window behavior; the alert never fires with fewer than N conversations."
},
"entity_field": {
"type": "string",
"title": "Entity Field",
"description": "The exact thing watched, per entity_type: custom_metric takes the custom metric's UUID (from list_custom_metrics); standard_metric the built-in metric's UUID; metadata_field the metadata key as a dot path with no \"metadata:\" prefix; system_failure \"status:<bucket>\", the conversation status to count."
},
"source_scope": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Source Scope",
"default": null,
"description": "Which conversations fire the alert: observability (live calls sent to Bluejay), simulation (simulation runs) or all (both). Omit for all."
},
"simulation_id": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Simulation Id",
"default": null,
"description": "Limit a simulation alert to one simulation (id from list_simulations). Only valid when source_scope is simulation. Omit to watch all simulations."
},
"min_events_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Min Events Type",
"default": null,
"description": "Whether min_events is a count of events (events) or a percent of conversations, 0 to 100 (percentage). Omit for events."
},
"comparison_value": {
"type": "string",
"title": "Comparison Value",
"description": "The threshold to compare against, always as a string, e.g. \"0.8\", \"true\" or \"billing\"."
},
"evaluation_scope": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Evaluation Scope",
"default": null,
"description": "How a simulation alert is evaluated; per_simulation_run (judge each completed run) is the supported value."
},
"applies_to_all_agents": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Applies To All Agents",
"default": null,
"description": "true (the default) watches every agent's conversations; false limits the alert to agent_ids."
},
"notification_channels": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
{
"type": "null"
}
],
"title": "Notification Channels",
"default": null,
"description": "Where to send notifications when the alert fires, as a list of {\"type\", \"target\"}. type is email, slack, webhook, pagerduty, betterstack or incidentio; target is the email address, Slack channel, webhook URL or PagerDuty routing key, and is ignored for betterstack and incidentio, which use the organization's saved credentials. Omit for no notifications."
},
"threshold_time_interval": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Threshold Time Interval",
"default": null,
"description": "The window the alert is judged over. For observability or all alerts, seconds of recent conversations; for simulation alerts, the number K of recent completed runs, and it fires when all K met the condition. Omit for 600 seconds, or 1 run for a simulation alert."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The alert's id; pass it as alert_id to update_alert, delete_alert or get_alert_results."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The alert's name."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"agents": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Agent ids the alert is limited to; null when applies_to_all_agents is true."
},
"in_alert": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Whether the alert is currently firing."
},
"operator": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "How each value is compared with comparison_value."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "ISO 8601 creation time."
},
"created_by": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "User id of the creator."
},
"is_enabled": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Whether the alert is evaluated; false means paused."
},
"min_events": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Matching events needed in the window to fire (count or percent, per min_events_type); null for simulation alerts."
},
"updated_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "ISO 8601 time of the last change."
},
"updated_by": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "User id of the last editor."
},
"aggregation": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How a simulation alert combines a run's conversation values: none, avg, max, min or count."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Free-text note about the alert."
},
"entity_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the alert watches: custom_metric, standard_metric, custom_goal, metadata_field or system_failure."
},
"sample_size": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Evaluated over the most recent N conversations instead of a time window; null uses the window."
},
"entity_field": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The watched metric UUID, metadata key or status bucket, per entity_type."
},
"source_scope": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Which conversations fire it: all, observability or simulation."
},
"simulation_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Simulation a simulation alert is limited to; null for all simulations."
},
"trigger_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "How many times the alert has fired."
},
"min_events_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "events (min_events is a count) or percentage."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Organization that owns the alert."
},
"simulation_name": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Name of simulation_id's simulation, if set."
},
"comparison_value": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The threshold value, as a string."
},
"evaluation_scope": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "How a simulation alert is evaluated; per_simulation_run is the supported value."
},
"last_triggered_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "ISO 8601 time the alert last fired; null if never."
},
"applies_to_all_agents": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the alert watches every agent; false limits it to agents."
},
"notification_channels": {
"type": [
"array",
"object",
"null"
],
"items": {},
"properties": {},
"description": "Where notifications go, as a list of {type, target}: type is email, slack, webhook, pagerduty, betterstack or incidentio; target is the email address, Slack channel, webhook URL or PagerDuty routing key.",
"additionalProperties": true
},
"threshold_time_interval": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Window the alert is judged over: seconds for observability/all alerts, number of recent completed runs for simulation alerts."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Change an existing alert in place via PUT /v1/update-alert/{alert_id}.
Partial update: only the parameters you pass change, and clear_fields resets nullable ones to
null. notification_channels and agent_ids replace the whole stored list. The previous
configuration is overwritten, not versioned. is_enabled false pauses the alert without deleting
it. See create_alert for how the condition and window are evaluated.
Prerequisites: you need write access to the alert's workspace. simulation_id is only valid
while source_scope is 'simulation', so moving a simulation alert to another source_scope also
needs simulation_id in clear_fields. applies_to_all_agents false needs agent_ids, given here
or already on the alert, and new agents and simulations must be in the alert's workspace.
Returns the alert's full stored configuration after the update, the same shape as create_alert.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
alert_id
The alert to change: its id, from list_alerts or create_alert.
Clear enough to supply this argument.
name
New name. Omit to keep the current one.
Clear enough to supply this argument.
description
New free-text note. Omit to keep it; list description in clear_fields to remove it.
Clear enough to supply this argument.
is_enabled
false pauses the alert, true resumes it. Omit to leave it as is.
Clear enough to supply this argument.
entity_type
What the alert watches: custom_metric (one of your custom metrics), standard_metric (a built-in metric), custom_goal, metadata_field (a conversation metadata key) or system_failure (simulation conversations ending in a given status). Decides what entity_field holds. Omit to keep the current one.
Clear enough to supply this argument.
entity_field
The exact thing watched, per entity_type: custom_metric takes the custom metric's UUID (from list_custom_metrics); standard_metric the built-in metric's UUID; metadata_field the metadata key as a dot path with no "metadata:" prefix; system_failure "status:<bucket>", the conversation status to count. Omit to keep the current one.
Clear enough to supply this argument.
operator
How each conversation's value is compared with comparison_value: equals, not_equals, greater_than, less_than, greater_than_or_equal, less_than_or_equal, contains or not_contains. Omit to keep the current one.
Clear enough to supply this argument.
comparison_value
The threshold to compare against, always as a string, e.g. "0.8", "true" or "billing". Omit to keep the current one.
Clear enough to supply this argument.
notification_channels
Where to send notifications when the alert fires, as a list of {"type", "target"}. type is email, slack, webhook, pagerduty, betterstack or incidentio; target is the email address, Slack channel, webhook URL or PagerDuty routing key, and is ignored for betterstack and incidentio, which use the organization's saved credentials. Replaces the whole stored list; [] stops all notifications. Omit to keep it.
Clear enough to supply this argument.
applies_to_all_agents
true watches every agent; false limits the alert to agent_ids (or its existing agents). Omit to keep it.
Clear enough to supply this argument.
agent_ids
Bluejay agent ids (from list_agents) the alert is limited to. Required when applies_to_all_agents is false. Replaces the alert's agent list. Omit to keep it.
Clear enough to supply this argument.
simulation_id
Limit a simulation alert to one simulation (id from list_simulations). Only valid when source_scope is simulation. Omit to keep it; list simulation_id in clear_fields to watch all simulations again.
Clear enough to supply this argument.
evaluation_scope
How a simulation alert is evaluated; per_simulation_run (judge each completed run) is the supported value. Omit to keep it.
Clear enough to supply this argument.
aggregation
How a simulation alert combines the conversation values in a run into one value: none, avg, max, min or count. Omit to keep it.
Clear enough to supply this argument.
threshold_time_interval
The window the alert is judged over. For observability or all alerts, seconds of recent conversations; for simulation alerts, the number K of recent completed runs, and it fires when all K met the condition. Omit to keep it.
Clear enough to supply this argument.
min_events
For observability or all alerts, how many conversations matching the condition within the window trip the alert: a count, or a percent of the window's conversations when min_events_type is percentage. Ignored (stored as null) for simulation alerts. Omit to keep it.
Clear enough to supply this argument.
min_events_type
Whether min_events is a count of events (events) or a percent of conversations, 0 to 100 (percentage). Omit to keep it.
Clear enough to supply this argument.
source_scope
Which conversations fire the alert: observability (live calls sent to Bluejay), simulation (simulation runs) or all (both). Omit to keep it.
Clear enough to supply this argument.
sample_size
Judge the alert over the most recent N conversations instead of a time window; at least 30, and the alert never fires with fewer than N. Omit to keep it; list sample_size in clear_fields to go back to the time window.
Clear enough to supply this argument.
clear_fields
Fields to reset to null, since omitting a parameter leaves it unchanged. Allowed: simulation_id, description, evaluation_scope, aggregation, threshold_time_interval, min_events, sample_size. Clearing simulation_id makes a simulation alert watch all simulations of its agents again.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Permanently delete an alert via DELETE /v1/alert/{alert_id}, along with its agent links.
The alert stops being evaluated and stops sending notifications. This cannot be undone and
the configuration is not recoverable; to stop an alert temporarily, call update_alert with
is_enabled false instead. Requires write access to the alert's workspace.
Returns a confirmation message and the deleted alert's id.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
alert_id
The alert to delete: its id, from list_alerts or create_alert.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List the organization's uptime monitors (GET /v1/uptime/monitors) in the workspaces you can see, newest first.
Returns `monitors`: each monitor's configuration (agent_id, frequency as an "<n>m" minutes
token like "5m", active_window, checks, notifications, enabled), its backing simulation
(experiment_id) and current state: last_status (e.g. UP or DOWN), last_checked_at and
last_latency_ms, the average response latency the latest finished check measured. For uptime %
and latency over time, use get_uptime_monitor_series.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Get one uptime monitor by id via GET /v1/uptime/monitors/{monitor_id}.
Returns the monitor's fields at the top level: its configuration (agent_id, frequency,
active_window, checks, notifications, enabled), experiment_id (the backing health-check
simulation) and current state: last_status (e.g. UP or DOWN), last_checked_at and
last_latency_ms. It holds no history; use get_uptime_monitor_series for uptime % and latency
over time.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
monitor_id
The monitor to read: its id, from list_uptime_monitors or create_uptime_monitor.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Outcome counts, uptime % and response-latency percentiles per bucket via GET /v1/uptime/monitors/{monitor_id}/series. Read-only.
Returns {"series": {"bucket", "from", "to", "series": [...], "latency": {...},
"window": {...}}}. Each point in `series` is {date, uptime_pct, up, down, unknown, pending,
avg_latency_ms, p50_latency_ms, p75_latency_ms, p90_latency_ms, p95_latency_ms,
p99_latency_ms}; uptime_pct and the latency fields are null for a bucket with nothing to
measure. `latency` holds the mean and the same five percentiles over the whole window, which
is not the mean of the buckets'.
`window` is {uptime_pct, incidents} for the monitor's own verdict over that window, where an
incident is the start of an unresolved DOWN streak. Every bucket in the window is returned, so a stretch with no
runs comes back with null rates rather than being missing. Requires a user access token: an
API key is rejected.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
monitor_id
The monitor to chart: its id, from list_uptime_monitors or create_uptime_monitor.
Clear enough to supply this argument.
days
How many days back from now to cover, up to 365.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
bucket
Width of each point: "15m", "hour", "day", "week" or "month". Omit to get a width that suits the window (hourly up to 2 days, then daily, weekly, monthly).
Clear enough to supply this argument.
check
Grade one health check instead of the monitor's own UP/DOWN verdict: its checkType (connection, agent_malfunction, latency) or the customMetricId of a custom-metric check, as listed in the monitor's checks. Omit for the monitor's verdict.
Clear enough to supply this argument.
label
The check's display name (its label in the monitor's checks). Runs recorded before custom metrics were keyed by id stored the name instead, so pass it alongside check to grade those too.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Create an uptime monitor via POST /v1/uptime/monitors: Bluejay probes one agent on a recurring
schedule with a short health-check conversation, grades it with the checks, and marks the agent
UP or DOWN.
Side effects: saves the monitor in the agent's workspace, provisions a backing simulation named
"Uptime Monitor · <agent>" with a probe digital human, attaches the custom metrics the checks name
to the agent, and schedules the first check (immediately unless start_at or enabled false). Every
check is a real conversation with the agent (a phone call for voice agents), and DOWN and recovery
alerts go to the notifications channels.
Prerequisites: at least one enabled check with a checkType or customMetricId, or the call fails
with a 400. An outbound agent needs a way to start the conversation: an outbound trigger webhook,
a Vapi, Retell or Bland agent Bluejay can auto-call, or an email_address for email agents.
Returns the new monitor's id and whether provisioning succeeded.
The description explains the capability, when to use it, and what to expect.
Inputs83/100
Resolve the mismatch between this description and its schema constraints.
agent_id
The agent to probe: its Bluejay agent id, from list_agents.
Clear enough to supply this argument.
frequency
How often a check runs, as minutes with an "m" suffix, e.g. "5m" or "15m". Omit for "5m".
Resolve the mismatch between this description and its schema constraints.
$defs › ActiveWindow › days
Weekdays the window is open on, e.g. ["monday", "friday"]. Leave empty for every day.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › ActiveWindow › start_time
Time of day the window opens, as a zero-padded 24-hour time such as "09:00". Leave start_time and end_time unset (or equal) for no time restriction.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › ActiveWindow › end_time
Time of day the window closes, as a zero-padded 24-hour time such as "17:00"; the window runs up to but not including it. An end before start_time wraps past midnight, e.g. 22:00 to 06:00.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › ActiveWindow › timezone
IANA timezone the days and times are read in, e.g. "America/Los_Angeles". Omit for UTC.
Clear enough to supply this argument.
checks
The health checks each run grades, as a list of objects: {"id", "label", "description", "enabled", "isTemplate", "checkType"?: connection|agent_malfunction|latency, "digitalHumanId"?, "customMetricId"?, "config"?: {"latency_threshold_ms", "alert_after_failures", "unresponsive_gap_ms"}, "condition"?: {"data_type": numeric|boolean|categorical, "operator", "comparison_value"}}. The three template checks (connection, agent_malfunction, latency) have isTemplate true and a checkType; your own checks have isTemplate false and a customMetricId (one of your custom metrics, from list_custom_metrics) or a digitalHumanId (from list_digital_humans). At least one enabled check must carry a checkType or customMetricId: a check with only a description grades nothing, and digitalHumanId only picks which digital human runs the probe. config.alert_after_failures (default 1) is how many runs in a row must fail the check before the monitor goes DOWN and alerts; raise it for latency and agent_malfunction so a one-off spike doesn't page, and keep connection at 1. config.unresponsive_gap_ms (voice only, default 15000) is how long the agent may stay silent after the caller speaks before the connection check fails.
Clear enough to supply this argument.
notifications
Where DOWN and recovery alerts go: an object with any of "slack": {"channel", "team_id"?, "notify_channel"?}, "pagerduty": bool, "betterstack": bool, "incidentio": bool, "email": {"scope": "all"|"specific", "addresses": [...]}, and "notify_on_recovery": bool. notify_on_recovery defaults to true; false mutes the Slack and email message sent when the monitor comes back up, while PagerDuty, Better Stack and incident.io still receive the resolve so their incidents close. Omit for no alerts.
Clear enough to supply this argument.
enabled
false creates the monitor paused. Omit to start it enabled.
Clear enough to supply this argument.
start_at
ISO 8601 time with a timezone for the next check, e.g. "2026-07-22T15:00:00Z". Omit to run the first check immediately.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The new monitor's id; pass it as monitor_id to get_uptime_monitor, update_uptime_monitor and delete_uptime_monitor."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"provisioned": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "False when the monitor was saved but its backing simulation could not be built; a update_uptime_monitor call retries provisioning."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_uptime_monitor",
"title": "Create uptime monitor",
"description": "Create an uptime monitor via POST /v1/uptime/monitors: Bluejay probes one agent on a recurring\nschedule with a short health-check conversation, grades it with the checks, and marks the agent\nUP or DOWN.\n\nSide effects: saves the monitor in the agent's workspace, provisions a backing simulation named\n\"Uptime Monitor · <agent>\" with a probe digital human, attaches the custom metrics the checks name\nto the agent, and schedules the first check (immediately unless start_at or enabled false). Every\ncheck is a real conversation with the agent (a phone call for voice agents), and DOWN and recovery\nalerts go to the notifications channels.\n\nPrerequisites: at least one enabled check with a checkType or customMetricId, or the call fails\nwith a 400. An outbound agent needs a way to start the conversation: an outbound trigger webhook,\na Vapi, Retell or Bland agent Bluejay can auto-call, or an email_address for email agents.\n\nReturns the new monitor's id and whether provisioning succeeded.\n",
"inputSchema": {
"type": "object",
"$defs": {
"ActiveWindow": {
"type": "object",
"title": "ActiveWindow",
"properties": {
"days": {
"type": "array",
"items": {
"enum": [
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday"
],
"type": "string"
},
"title": "Days",
"description": "Weekdays the window is open on, e.g. [\"monday\", \"friday\"]. Leave empty for every day."
},
"end_time": {
"anyOf": [
{
"type": "string",
"pattern": "^\\d{2}:\\d{2}$"
},
{
"type": "null"
}
],
"title": "End Time",
"default": null,
"description": "Time of day the window closes, as a zero-padded 24-hour time such as \"17:00\"; the window runs up to but not including it. An end before start_time wraps past midnight, e.g. 22:00 to 06:00."
},
"timezone": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Timezone",
"default": null,
"description": "IANA timezone the days and times are read in, e.g. \"America/Los_Angeles\". Omit for UTC."
},
"start_time": {
"anyOf": [
{
"type": "string",
"pattern": "^\\d{2}:\\d{2}$"
},
{
"type": "null"
}
],
"title": "Start Time",
"default": null,
"description": "Time of day the window opens, as a zero-padded 24-hour time such as \"09:00\". Leave start_time and end_time unset (or equal) for no time restriction."
}
},
"description": "Uptime monitor's active_window: same days/HH:MM shape as ScheduleWindow plus a timezone,\nbut interpreted directly rather than folded into cron — so a wrapping window with days is\nlegal here (unlike ScheduleWindow, which can't represent it in one cron expression)."
}
},
"title": "create_uptime_monitorArguments",
"required": [
"agent_id"
],
"properties": {
"checks": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
{
"type": "null"
}
],
"title": "Checks",
"default": null,
"description": "The health checks each run grades, as a list of objects: {\"id\", \"label\", \"description\", \"enabled\", \"isTemplate\", \"checkType\"?: connection|agent_malfunction|latency, \"digitalHumanId\"?, \"customMetricId\"?, \"config\"?: {\"latency_threshold_ms\", \"alert_after_failures\", \"unresponsive_gap_ms\"}, \"condition\"?: {\"data_type\": numeric|boolean|categorical, \"operator\", \"comparison_value\"}}. The three template checks (connection, agent_malfunction, latency) have isTemplate true and a checkType; your own checks have isTemplate false and a customMetricId (one of your custom metrics, from list_custom_metrics) or a digitalHumanId (from list_digital_humans). At least one enabled check must carry a checkType or customMetricId: a check with only a description grades nothing, and digitalHumanId only picks which digital human runs the probe. config.alert_after_failures (default 1) is how many runs in a row must fail the check before the monitor goes DOWN and alerts; raise it for latency and agent_malfunction so a one-off spike doesn't page, and keep connection at 1. config.unresponsive_gap_ms (voice only, default 15000) is how long the agent may stay silent after the caller speaks before the connection check fails."
},
"enabled": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Enabled",
"default": null,
"description": "false creates the monitor paused. Omit to start it enabled."
},
"agent_id": {
"type": "integer",
"title": "Agent Id",
"description": "The agent to probe: its Bluejay agent id, from list_agents."
},
"start_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Start At",
"default": null,
"description": "ISO 8601 time with a timezone for the next check, e.g. \"2026-07-22T15:00:00Z\". Omit to run the first check immediately."
},
"frequency": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Frequency",
"default": null,
"description": "How often a check runs, as minutes with an \"m\" suffix, e.g. \"5m\" or \"15m\". Omit for \"5m\"."
},
"active_window": {
"anyOf": [
{
"$ref": "#/$defs/ActiveWindow"
},
{
"type": "null"
}
],
"default": null,
"description": "Days/hours the monitor may run, e.g. {\"days\": [\"monday\"], \"start_time\": \"09:00\", \"end_time\": \"17:00\", \"timezone\": \"America/Los_Angeles\"}. Null runs it around the clock."
},
"notifications": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Notifications",
"default": null,
"description": "Where DOWN and recovery alerts go: an object with any of \"slack\": {\"channel\", \"team_id\"?, \"notify_channel\"?}, \"pagerduty\": bool, \"betterstack\": bool, \"incidentio\": bool, \"email\": {\"scope\": \"all\"|\"specific\", \"addresses\": [...]}, and \"notify_on_recovery\": bool. notify_on_recovery defaults to true; false mutes the Slack and email message sent when the monitor comes back up, while PagerDuty, Better Stack and incident.io still receive the resolve so their incidents close. Omit for no alerts."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The new monitor's id; pass it as monitor_id to get_uptime_monitor, update_uptime_monitor and delete_uptime_monitor."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"provisioned": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "False when the monitor was saved but its backing simulation could not be built; a update_uptime_monitor call retries provisioning."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Change an uptime monitor in place via PUT /v1/uptime/monitors/{monitor_id}, overwriting the
previous configuration.
Partial update: only the fields you pass change, but checks and notifications replace the whole
stored value. Changing checks or agent_id rebuilds the backing health-check simulation (its probe
digital human is regenerated) and attaches newly named custom metrics to the agent; other edits
only reschedule. Every update also makes an enabled monitor due again at start_at, or immediately
when start_at is omitted, so a real probe conversation runs right away. enabled false pauses it.
A failed re-provision is logged, not returned.
Prerequisites: write access to the monitor's workspace, and after the change at least one
enabled check must still carry a checkType or customMetricId, or the call fails with a 400.
Returns only the monitor's id; call get_uptime_monitor to see the stored result.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
monitor_id
The monitor to change: its id, from list_uptime_monitors or create_uptime_monitor.
Clear enough to supply this argument.
agent_id
Probe a different agent instead (Bluejay agent id from list_agents); it must be in the monitor's workspace. Rebuilds the backing simulation. Omit to keep the current agent.
Clear enough to supply this argument.
frequency
New check interval, as minutes with an "m" suffix, e.g. "10m". Omit to keep it.
Clear enough to supply this argument.
$defs › ActiveWindow › days
Weekdays the window is open on, e.g. ["monday", "friday"]. Leave empty for every day.
Clear enough to supply this argument.
$defs › ActiveWindow › start_time
Time of day the window opens, as a zero-padded 24-hour time such as "09:00". Leave start_time and end_time unset (or equal) for no time restriction.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › ActiveWindow › end_time
Time of day the window closes, as a zero-padded 24-hour time such as "17:00"; the window runs up to but not including it. An end before start_time wraps past midnight, e.g. 22:00 to 06:00.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › ActiveWindow › timezone
IANA timezone the days and times are read in, e.g. "America/Los_Angeles". Omit for UTC.
Clear enough to supply this argument.
clear_active_window
true removes the active window so the monitor runs around the clock. Omitting active_window leaves the existing window untouched, so clearing one needs this flag; don't pass both.
Clear enough to supply this argument.
checks
Replacement for the whole checks list; changing it rebuilds the backing simulation. The health checks each run grades, as a list of objects: {"id", "label", "description", "enabled", "isTemplate", "checkType"?: connection|agent_malfunction|latency, "digitalHumanId"?, "customMetricId"?, "config"?: {"latency_threshold_ms", "alert_after_failures", "unresponsive_gap_ms"}, "condition"?: {"data_type": numeric|boolean|categorical, "operator", "comparison_value"}}. The three template checks (connection, agent_malfunction, latency) have isTemplate true and a checkType; your own checks have isTemplate false and a customMetricId (one of your custom metrics, from list_custom_metrics) or a digitalHumanId (from list_digital_humans). At least one enabled check must carry a checkType or customMetricId: a check with only a description grades nothing, and digitalHumanId only picks which digital human runs the probe. config.alert_after_failures (default 1) is how many runs in a row must fail the check before the monitor goes DOWN and alerts; raise it for latency and agent_malfunction so a one-off spike doesn't page, and keep connection at 1. config.unresponsive_gap_ms (voice only, default 15000) is how long the agent may stay silent after the caller speaks before the connection check fails. Omit to keep the current checks.
Clear enough to supply this argument.
notifications
Replacement for the whole notifications object. Where DOWN and recovery alerts go: an object with any of "slack": {"channel", "team_id"?, "notify_channel"?}, "pagerduty": bool, "betterstack": bool, "incidentio": bool, "email": {"scope": "all"|"specific", "addresses": [...]}, and "notify_on_recovery": bool. notify_on_recovery defaults to true; false mutes the Slack and email message sent when the monitor comes back up, while PagerDuty, Better Stack and incident.io still receive the resolve so their incidents close. Omit to keep it.
Clear enough to supply this argument.
enabled
false pauses the monitor, true resumes it. Omit to leave it as is.
Clear enough to supply this argument.
start_at
ISO 8601 time with a timezone for the next check, e.g. "2026-07-22T15:00:00Z". Omit to make the next check due immediately.
{
"name": "update_uptime_monitor",
"title": "Update uptime monitor",
"description": "Change an uptime monitor in place via PUT /v1/uptime/monitors/{monitor_id}, overwriting the\nprevious configuration.\n\nPartial update: only the fields you pass change, but checks and notifications replace the whole\nstored value. Changing checks or agent_id rebuilds the backing health-check simulation (its probe\ndigital human is regenerated) and attaches newly named custom metrics to the agent; other edits\nonly reschedule. Every update also makes an enabled monitor due again at start_at, or immediately\nwhen start_at is omitted, so a real probe conversation runs right away. enabled false pauses it.\nA failed re-provision is logged, not returned.\n\nPrerequisites: write access to the monitor's workspace, and after the change at least one\nenabled check must still carry a checkType or customMetricId, or the call fails with a 400.\n\nReturns only the monitor's id; call get_uptime_monitor to see the stored result.\n",
"inputSchema": {
"type": "object",
"$defs": {
"ActiveWindow": {
"type": "object",
"title": "ActiveWindow",
"properties": {
"days": {
"type": "array",
"items": {
"enum": [
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday"
],
"type": "string"
},
"title": "Days",
"description": "Weekdays the window is open on, e.g. [\"monday\", \"friday\"]. Leave empty for every day."
},
"end_time": {
"anyOf": [
{
"type": "string",
"pattern": "^\\d{2}:\\d{2}$"
},
{
"type": "null"
}
],
"title": "End Time",
"default": null,
"description": "Time of day the window closes, as a zero-padded 24-hour time such as \"17:00\"; the window runs up to but not including it. An end before start_time wraps past midnight, e.g. 22:00 to 06:00."
},
"timezone": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Timezone",
"default": null,
"description": "IANA timezone the days and times are read in, e.g. \"America/Los_Angeles\". Omit for UTC."
},
"start_time": {
"anyOf": [
{
"type": "string",
"pattern": "^\\d{2}:\\d{2}$"
},
{
"type": "null"
}
],
"title": "Start Time",
"default": null,
"description": "Time of day the window opens, as a zero-padded 24-hour time such as \"09:00\". Leave start_time and end_time unset (or equal) for no time restriction."
}
},
"description": "Uptime monitor's active_window: same days/HH:MM shape as ScheduleWindow plus a timezone,\nbut interpreted directly rather than folded into cron — so a wrapping window with days is\nlegal here (unlike ScheduleWindow, which can't represent it in one cron expression)."
}
},
"title": "update_uptime_monitorArguments",
"required": [
"monitor_id"
],
"properties": {
"checks": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
{
"type": "null"
}
],
"title": "Checks",
"default": null,
"description": "Replacement for the whole checks list; changing it rebuilds the backing simulation. The health checks each run grades, as a list of objects: {\"id\", \"label\", \"description\", \"enabled\", \"isTemplate\", \"checkType\"?: connection|agent_malfunction|latency, \"digitalHumanId\"?, \"customMetricId\"?, \"config\"?: {\"latency_threshold_ms\", \"alert_after_failures\", \"unresponsive_gap_ms\"}, \"condition\"?: {\"data_type\": numeric|boolean|categorical, \"operator\", \"comparison_value\"}}. The three template checks (connection, agent_malfunction, latency) have isTemplate true and a checkType; your own checks have isTemplate false and a customMetricId (one of your custom metrics, from list_custom_metrics) or a digitalHumanId (from list_digital_humans). At least one enabled check must carry a checkType or customMetricId: a check with only a description grades nothing, and digitalHumanId only picks which digital human runs the probe. config.alert_after_failures (default 1) is how many runs in a row must fail the check before the monitor goes DOWN and alerts; raise it for latency and agent_malfunction so a one-off spike doesn't page, and keep connection at 1. config.unresponsive_gap_ms (voice only, default 15000) is how long the agent may stay silent after the caller speaks before the connection check fails. Omit to keep the current checks."
},
"enabled": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Enabled",
"default": null,
"description": "false pauses the monitor, true resumes it. Omit to leave it as is."
},
"agent_id": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Agent Id",
"default": null,
"description": "Probe a different agent instead (Bluejay agent id from list_agents); it must be in the monitor's workspace. Rebuilds the backing simulation. Omit to keep the current agent."
},
"start_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Start At",
"default": null,
"description": "ISO 8601 time with a timezone for the next check, e.g. \"2026-07-22T15:00:00Z\". Omit to make the next check due immediately."
},
"frequency": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Frequency",
"default": null,
"description": "New check interval, as minutes with an \"m\" suffix, e.g. \"10m\". Omit to keep it."
},
"monitor_id": {
"type": "string",
"title": "Monitor Id",
"description": "The monitor to change: its id, from list_uptime_monitors or create_uptime_monitor."
},
"active_window": {
"anyOf": [
{
"$ref": "#/$defs/ActiveWindow"
},
{
"type": "null"
}
],
"default": null,
"description": "Replacement days and hours the monitor may run in, same shape as on create_uptime_monitor. Omit to keep the current window; use clear_active_window to remove it."
},
"notifications": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Notifications",
"default": null,
"description": "Replacement for the whole notifications object. Where DOWN and recovery alerts go: an object with any of \"slack\": {\"channel\", \"team_id\"?, \"notify_channel\"?}, \"pagerduty\": bool, \"betterstack\": bool, \"incidentio\": bool, \"email\": {\"scope\": \"all\"|\"specific\", \"addresses\": [...]}, and \"notify_on_recovery\": bool. notify_on_recovery defaults to true; false mutes the Slack and email message sent when the monitor comes back up, while PagerDuty, Better Stack and incident.io still receive the resolve so their incidents close. Omit to keep it."
},
"clear_active_window": {
"type": "boolean",
"title": "Clear Active Window",
"default": false,
"description": "true removes the active window so the monitor runs around the clock. Omitting active_window leaves the existing window untouched, so clearing one needs this flag; don't pass both."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The updated monitor's id. Read get_uptime_monitor for its stored configuration."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Permanently delete an uptime monitor via DELETE /v1/uptime/monitors/{monitor_id}.
Unschedules its checks and deletes the monitor, so probes and DOWN/recovery alerts stop. Its
backing "Uptime Monitor" simulation is left in place. This cannot be undone; to stop a monitor
temporarily, call update_uptime_monitor with enabled false instead. Requires write access to the
monitor's workspace.
Returns success, deleted and the monitor_id that was removed.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
monitor_id
The monitor to delete: its id, from list_uptime_monitors or create_uptime_monitor.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
List the organization's metrics labs via GET /v1/metrics-lab/labs.
Read-only. Returns labs newest-first, each with id, name, description, tags,
created_at and its conversation_count, metric_count and revision_count, plus
total_count across all pages. Pass a lab's id to get_lab_detail for its
conversations, metrics and verdicts.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page
Which page to return, counting from 1; 1 when omitted.
Clear enough to supply this argument.
page_size
Labs per page, at most 100; 20 when omitted.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Get a lab's full state via GET /v1/metrics-lab/lab/{lab_id}.
Read-only. Returns lab, conversations, metrics, ai_evaluations (base metric verdicts),
human_evaluations (ground truth), metric_revisions, and lab_ai_evaluations
(per-revision verdicts), each verdict with response_value and reasoning. Poll this to
observe async evaluation progress via each evaluation's ``status``
(QUEUED/EVALUATING/COMPLETED/INCOMPLETED/…).
The description explains the capability, when to use it, and what to expect.
Inputs100/100
Input documentation gives an agent enough context to populate the arguments.
lab_id
The lab's id (a uuid), from list_labs or create_lab.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Create a Metrics Lab to iterate on a custom metric against real conversations.
POST /v1/metrics-lab/lab. A lab pins a metric to a set of conversations
(e.g. the suspect cases from get_alert_results) so you can inspect the
metric's verdicts and improve it. Existing evaluations for each (metric,
conversation) pair are copied in automatically; pairs with no prior result
are queued for fresh evaluation — so current (often wrong) verdicts appear
immediately and cheaply. The metrics and conversations themselves are not changed.
Returns the new lab: id (pass it as lab_id to the tools below), name,
description, created_at and updated_at.
Typical loop after creating the lab:
1. get_lab_detail(lab_id) — read ai_evaluations (response_value + reasoning)
to confirm which cases are false alarms. Poll until status COMPLETED.
2. create_metric_revision(lab_id, custom_metric_id, ...) — a candidate fix
(sharper description / scoring_guidance).
3. evaluate_conversation(... metric_type='custom_metric_revision') for the
cases, then get_lab_detail to compare the revision's lab_ai_evaluations
against the base ai_evaluations. Repeat 2-3 until the cases flip.
4. Promote the winning wording onto the metric with update_custom_metric.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Explain what happens when this optional value is omitted.
name
Display name for the lab, e.g. the metric and the problem being investigated.
Clear enough to supply this argument.
conversations
Conversations to score the metrics on, each an object with one key: {"call_id": "<uuid>"} for a production call (from list_conversations or get_alert_results) or {"test_result_id": <int>} for a simulated conversation (from get_simulation_results or list_simulated_conversations). May be [] to add conversations later.
Clear enough to supply this argument.
metric_ids
Ids (uuids) of the custom metrics to work on, from list_custom_metrics or a custom-metric alert's entity_field.
Clear enough to supply this argument.
description
Notes on what the lab is for.
Explain what happens when this optional value is omitted.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The lab's id; the lab_id of get_lab_detail and the other lab routes."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Name of the lab"
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the lab was created"
},
"updated_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When the lab was last updated"
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Description of the lab"
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_lab",
"title": "Create lab",
"description": "Create a Metrics Lab to iterate on a custom metric against real conversations.\n\nPOST /v1/metrics-lab/lab. A lab pins a metric to a set of conversations\n(e.g. the suspect cases from get_alert_results) so you can inspect the\nmetric's verdicts and improve it. Existing evaluations for each (metric,\nconversation) pair are copied in automatically; pairs with no prior result\nare queued for fresh evaluation — so current (often wrong) verdicts appear\nimmediately and cheaply. The metrics and conversations themselves are not changed.\n\nReturns the new lab: id (pass it as lab_id to the tools below), name,\ndescription, created_at and updated_at.\n\nTypical loop after creating the lab:\n 1. get_lab_detail(lab_id) — read ai_evaluations (response_value + reasoning)\n to confirm which cases are false alarms. Poll until status COMPLETED.\n 2. create_metric_revision(lab_id, custom_metric_id, ...) — a candidate fix\n (sharper description / scoring_guidance).\n 3. evaluate_conversation(... metric_type='custom_metric_revision') for the\n cases, then get_lab_detail to compare the revision's lab_ai_evaluations\n against the base ai_evaluations. Repeat 2-3 until the cases flip.\n 4. Promote the winning wording onto the metric with update_custom_metric.\n",
"inputSchema": {
"type": "object",
"title": "create_labArguments",
"required": [
"name",
"conversations",
"metric_ids"
],
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "Display name for the lab, e.g. the metric and the problem being investigated."
},
"tags": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Tags",
"default": null,
"description": "Free-form tags for organizing labs."
},
"metric_ids": {
"type": "array",
"items": {
"type": "string"
},
"title": "Metric Ids",
"description": "Ids (uuids) of the custom metrics to work on, from list_custom_metrics or a custom-metric alert's entity_field."
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description",
"default": null,
"description": "Notes on what the lab is for."
},
"conversations": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"title": "Conversations",
"description": "Conversations to score the metrics on, each an object with one key: {\"call_id\": \"<uuid>\"} for a production call (from list_conversations or get_alert_results) or {\"test_result_id\": <int>} for a simulated conversation (from get_simulation_results or list_simulated_conversations). May be [] to add conversations later."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The lab's id; the lab_id of get_lab_detail and the other lab routes."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Name of the lab"
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the lab was created"
},
"updated_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "When the lab was last updated"
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Description of the lab"
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Rename a metrics lab or change its description (PUT /v1/metrics-lab/lab/{lab_id}).
Pass at least one of name or description. Each one you pass overwrites the stored
value, which is not kept; the lab's conversations, metrics, revisions and verdicts
are not touched. Returns the lab: id, name, description, created_at and updated_at.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Input documentation gives an agent enough context to populate the arguments.
lab_id
The lab's id (a uuid), from list_labs or create_lab.
Clear enough to supply this argument.
name
New lab name; omit to keep the current one.
Clear enough to supply this argument.
description
New lab description; omit to keep the current one.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Delete a metrics lab via DELETE /v1/metrics-lab/lab/{lab_id}.
The lab moves to Recently Deleted: it leaves list_labs and the lab tools at once, can
be restored in the Bluejay app for 30 days, and is then purged for good, with its
revisions and lab verdicts. The custom metrics and the conversations it referenced
are not deleted. Confirm with the user before calling. Returns message,
deleted_lab_id, deleted=true and the lab_id you passed.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
lab_id
The lab's id (a uuid), from list_labs or create_lab.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"lab_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The lab_id you passed."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the lab was deleted."
},
"message": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Confirmation message."
},
"deleted_lab_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "ID of the deleted lab"
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "delete_lab",
"title": "Delete lab",
"description": "Delete a metrics lab via DELETE /v1/metrics-lab/lab/{lab_id}.\n\nThe lab moves to Recently Deleted: it leaves list_labs and the lab tools at once, can\nbe restored in the Bluejay app for 30 days, and is then purged for good, with its\nrevisions and lab verdicts. The custom metrics and the conversations it referenced\nare not deleted. Confirm with the user before calling. Returns message,\ndeleted_lab_id, deleted=true and the lab_id you passed.\n",
"inputSchema": {
"type": "object",
"title": "delete_labArguments",
"required": [
"lab_id"
],
"properties": {
"lab_id": {
"type": "string",
"title": "Lab Id",
"description": "The lab's id (a uuid), from list_labs or create_lab."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"lab_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The lab_id you passed."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the lab was deleted."
},
"message": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Confirmation message."
},
"deleted_lab_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "ID of the deleted lab"
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Attach more custom metrics to an existing metrics lab via POST /v1/metrics-lab/lab/{lab_id}/metrics.
Metrics already in the lab are skipped; the metrics themselves are not changed. With
evaluate_conversations, scoring is asynchronous: poll get_lab_detail until the new
ai_evaluations reach status COMPLETED. Returns added_count, skipped_count,
added_metric_ids, evaluation_triggered, evaluation_count and message.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
lab_id
The lab's id (a uuid), from list_labs or create_lab.
Clear enough to supply this argument.
metric_ids
Ids (uuids) of the custom metrics to attach, from list_custom_metrics; ones already in the lab are skipped.
Clear enough to supply this argument.
evaluate_conversations
When true, score the added metrics on every conversation already in the lab: existing results are copied in and only pairs with none are queued. Omit or false to only attach the metrics.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Add conversations to a lab via POST /v1/metrics-lab/lab/{lab_id}/conversations.
For each added conversation, existing evaluations for the lab's metrics are
copied in where present; only pairs with no result are queued, so poll
get_lab_detail until their status is COMPLETED. Conversations already in the lab
are skipped, and the conversations themselves are not changed. Returns
added_count, skipped_count, added_conversation_ids ({call_id, test_result_id} per
added conversation) and message.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
lab_id
The lab's id (a uuid), from list_labs or create_lab.
Clear enough to supply this argument.
conversations
Conversations to score the metrics on, each an object with one key: {"call_id": "<uuid>"} for a production call (from list_conversations or get_alert_results) or {"test_result_id": <int>} for a simulated conversation (from get_simulation_results or list_simulated_conversations). Ones already in the lab are skipped.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"message": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Human-readable message about the operation"
},
"added_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Number of conversations successfully added"
},
"skipped_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Number of conversations that were skipped (already existed)"
},
"added_conversation_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"description": "The conversations that were added, each {call_id, test_result_id}.",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "add_conversations_to_lab",
"title": "Add conversations to lab",
"description": "Add conversations to a lab via POST /v1/metrics-lab/lab/{lab_id}/conversations.\n\nFor each added conversation, existing evaluations for the lab's metrics are\ncopied in where present; only pairs with no result are queued, so poll\nget_lab_detail until their status is COMPLETED. Conversations already in the lab\nare skipped, and the conversations themselves are not changed. Returns\nadded_count, skipped_count, added_conversation_ids ({call_id, test_result_id} per\nadded conversation) and message.\n",
"inputSchema": {
"type": "object",
"title": "add_conversations_to_labArguments",
"required": [
"lab_id",
"conversations"
],
"properties": {
"lab_id": {
"type": "string",
"title": "Lab Id",
"description": "The lab's id (a uuid), from list_labs or create_lab."
},
"conversations": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"title": "Conversations",
"description": "Conversations to score the metrics on, each an object with one key: {\"call_id\": \"<uuid>\"} for a production call (from list_conversations or get_alert_results) or {\"test_result_id\": <int>} for a simulated conversation (from get_simulation_results or list_simulated_conversations). Ones already in the lab are skipped."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"message": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Human-readable message about the operation"
},
"added_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Number of conversations successfully added"
},
"skipped_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Number of conversations that were skipped (already existed)"
},
"added_conversation_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
"properties": {},
"description": "The conversations that were added, each {call_id, test_result_id}.",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Create a metric revision via POST /v1/metrics-lab/lab/{lab_id}/metric-revisions.
A revision is a candidate improvement to a metric — typically a sharper
``description`` and/or ``scoring_guidance``. It is saved in the lab only: the
custom metric itself is not changed (promote a winner with update_custom_metric).
The revision_number is auto-incremented. Nothing is scored yet: call
evaluate_conversation with metric_type='custom_metric_revision' and the returned
id to score it against conversations.
Returns the revision: id, lab_id, custom_metric_id, revision_number, description,
scoring_guidance, eval_route, model, audio_model, temperature,
allow_not_applicable and created_at.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
lab_id
The lab's id (a uuid), from list_labs or create_lab.
Clear enough to supply this argument.
custom_metric_id
The metric to rewrite: its id (a uuid), one of the lab's metrics as listed by get_lab_detail.
Clear enough to supply this argument.
description
The revised judge instruction to test, the counterpart of the metric's prompt; usually a sharper wording.
Clear enough to supply this argument.
scoring_guidance
Revised rubric text for the judge, e.g. how to treat borderline cases.
Clear enough to supply this argument.
eval_route
Which judge lane scores the revision: 'AUDIO' (recording), 'TEXT' (transcript) or 'AUTO'.
Clear enough to supply this argument.
model
Text judge model to score this revision with.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
audio_model
Audio judge model to score this revision with.
Clear enough to supply this argument.
temperature
Judge sampling temperature for this revision, from 0 to 2.
Clear enough to supply this argument.
allow_not_applicable
true lets the judge answer not_applicable instead of forcing a verdict; stored as false when omitted.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Queue evaluation of one conversation via POST /v1/metrics-lab/evaluate-conversation.
Each call runs the LLM judge again, even when a result already exists, and is refused
when the org has no usage entitlement; you need write access to the conversation.
Re-scoring a pair the lab already holds sets its status back to QUEUED, and the new
verdict replaces the old one when it completes. Evaluation is asynchronous — poll
get_lab_detail until the evaluation ``status`` reaches COMPLETED (base metric
results land in ai_evaluations, revision results in lab_ai_evaluations).
Returns status, message, conversation_id, conversation_type and metrics: one
{type, id, eval_id} per metric or revision queued.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
lab_id
The lab to record the results in: its id (a uuid), from list_labs or create_lab.
Clear enough to supply this argument.
conversation_type
Which kind of conversation conversation_id is: 'obs_conversation' for a production call or 'sim_conversation' for a simulated one.
Clear enough to supply this argument.
conversation_id
The conversation to score: a call's obs_conversation_id (a uuid; call_id in get_lab_detail) or a sim_conversation_id written as a string (test_result_id in get_lab_detail).
Clear enough to supply this argument.
metric_type
What to score: 'custom_metric' scores base metrics (pass custom_metric_ids); 'custom_metric_revision' scores one revision (pass custom_metric_revision_id).
Clear enough to supply this argument.
custom_metric_ids
Ids of the base metrics to score, from get_lab_detail's metrics; used when metric_type is custom_metric.
Clear enough to supply this argument.
custom_metric_revision_id
Id of the revision to score, from create_metric_revision or get_lab_detail's metric_revisions; used when metric_type is custom_metric_revision.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "success when the evaluation was queued."
},
"message": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Human-readable confirmation."
},
"metrics": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Metric ID (custom_metric_id or custom_metric_revision_id)"
},
"type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Type of metric: 'custom_metric' or 'custom_metric_revision'"
},
"eval_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Evaluation ID (lab_annotate_ai_evaluation_id or lab_ai_evaluation_id)"
}
},
"description": "Pydantic model for a single metric evaluation item in response",
"additionalProperties": true
},
"properties": {},
"description": "One entry per metric or revision queued: its type, id and eval_id, the id of the queued evaluation row as it appears in get_lab_detail.",
"additionalProperties": true
},
"conversation_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The conversation that was queued."
},
"conversation_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "obs_conversation or sim_conversation."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "evaluate_conversation",
"title": "Evaluate conversation",
"description": "Queue evaluation of one conversation via POST /v1/metrics-lab/evaluate-conversation.\n\nEach call runs the LLM judge again, even when a result already exists, and is refused\nwhen the org has no usage entitlement; you need write access to the conversation.\nRe-scoring a pair the lab already holds sets its status back to QUEUED, and the new\nverdict replaces the old one when it completes. Evaluation is asynchronous — poll\nget_lab_detail until the evaluation ``status`` reaches COMPLETED (base metric\nresults land in ai_evaluations, revision results in lab_ai_evaluations).\n\nReturns status, message, conversation_id, conversation_type and metrics: one\n{type, id, eval_id} per metric or revision queued.\n",
"inputSchema": {
"type": "object",
"title": "evaluate_conversationArguments",
"required": [
"lab_id",
"conversation_type",
"conversation_id",
"metric_type"
],
"properties": {
"lab_id": {
"type": "string",
"title": "Lab Id",
"description": "The lab to record the results in: its id (a uuid), from list_labs or create_lab."
},
"metric_type": {
"type": "string",
"title": "Metric Type",
"description": "What to score: 'custom_metric' scores base metrics (pass custom_metric_ids); 'custom_metric_revision' scores one revision (pass custom_metric_revision_id)."
},
"conversation_id": {
"type": "string",
"title": "Conversation Id",
"description": "The conversation to score: a call's obs_conversation_id (a uuid; call_id in get_lab_detail) or a sim_conversation_id written as a string (test_result_id in get_lab_detail)."
},
"conversation_type": {
"type": "string",
"title": "Conversation Type",
"description": "Which kind of conversation conversation_id is: 'obs_conversation' for a production call or 'sim_conversation' for a simulated one."
},
"custom_metric_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Custom Metric Ids",
"default": null,
"description": "Ids of the base metrics to score, from get_lab_detail's metrics; used when metric_type is custom_metric."
},
"custom_metric_revision_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Custom Metric Revision Id",
"default": null,
"description": "Id of the revision to score, from create_metric_revision or get_lab_detail's metric_revisions; used when metric_type is custom_metric_revision."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "success when the evaluation was queued."
},
"message": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Human-readable confirmation."
},
"metrics": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Metric ID (custom_metric_id or custom_metric_revision_id)"
},
"type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Type of metric: 'custom_metric' or 'custom_metric_revision'"
},
"eval_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Evaluation ID (lab_annotate_ai_evaluation_id or lab_ai_evaluation_id)"
}
},
"description": "Pydantic model for a single metric evaluation item in response",
"additionalProperties": true
},
"properties": {},
"description": "One entry per metric or revision queued: its type, id and eval_id, the id of the queued evaluation row as it appears in get_lab_detail.",
"additionalProperties": true
},
"conversation_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The conversation that was queued."
},
"conversation_type": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "obs_conversation or sim_conversation."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Create a community via POST /v1/create-community: a named group of digital humans in your
current workspace, used to organize a set of test callers and reuse them together.
Optionally adds members right away; membership only links existing digital humans, it does not
copy or change them. Requires write access to the workspace, and every digital human must be in it.
Returns the new community: id (for get_community, update_community and delete_community), title,
description, created_at and digital_human_ids, its members.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Explain what happens when this optional value is omitted.
title
Name of the community, e.g. "Spanish-speaking callers".
Clear enough to supply this argument.
description
What the digital humans in this community have in common.
Explain what happens when this optional value is omitted.
digital_human_ids
Digital humans to add as members, by id from list_digital_humans. They must be in your current workspace, where the community is created. Omit to start it empty.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's id; pass it as community_id to get_community, update_community or delete_community."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"title": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's name."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the community was created."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "What its digital humans have in common."
},
"digital_human_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Ids of its member digital humans (read each with get_digital_human).",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_community",
"title": "Create community",
"description": "Create a community via POST /v1/create-community: a named group of digital humans in your\ncurrent workspace, used to organize a set of test callers and reuse them together.\n\nOptionally adds members right away; membership only links existing digital humans, it does not\ncopy or change them. Requires write access to the workspace, and every digital human must be in it.\n\nReturns the new community: id (for get_community, update_community and delete_community), title,\ndescription, created_at and digital_human_ids, its members.\n",
"inputSchema": {
"type": "object",
"title": "create_communityArguments",
"required": [
"title"
],
"properties": {
"title": {
"type": "string",
"title": "Title",
"description": "Name of the community, e.g. \"Spanish-speaking callers\"."
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description",
"default": null,
"description": "What the digital humans in this community have in common."
},
"digital_human_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Digital Human Ids",
"default": null,
"description": "Digital humans to add as members, by id from list_digital_humans. They must be in your current workspace, where the community is created. Omit to start it empty."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's id; pass it as community_id to get_community, update_community or delete_community."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"title": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's name."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the community was created."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "What its digital humans have in common."
},
"digital_human_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Ids of its member digital humans (read each with get_digital_human).",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Get one community (a named group of digital humans) via GET /v1/community/{community_id}.
Returns its id, title, description, created_at and digital_human_ids, the ids of its member
digital humans (read each with get_digital_human), with the same object repeated under `data`.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
community_id
The community to read: its id, from list_communities or create_community.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's id; pass it as community_id to get_community, update_community or delete_community."
},
"data": {
"type": [
"object",
"array",
"null"
],
"description": "The same community object as returned by the API."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"title": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's name."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the community was created."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "What its digital humans have in common."
},
"digital_human_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Ids of its member digital humans (read each with get_digital_human).",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "get_community",
"title": "Get community",
"description": "Get one community (a named group of digital humans) via GET /v1/community/{community_id}.\n\nReturns its id, title, description, created_at and digital_human_ids, the ids of its member\ndigital humans (read each with get_digital_human), with the same object repeated under `data`.\n",
"inputSchema": {
"type": "object",
"title": "get_communityArguments",
"required": [
"community_id"
],
"properties": {
"community_id": {
"type": "string",
"title": "Community Id",
"format": "uuid",
"description": "The community to read: its id, from list_communities or create_community."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's id; pass it as community_id to get_community, update_community or delete_community."
},
"data": {
"type": [
"object",
"array",
"null"
],
"description": "The same community object as returned by the API."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"title": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's name."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the community was created."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "What its digital humans have in common."
},
"digital_human_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Ids of its member digital humans (read each with get_digital_human).",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
List the organization's communities (named groups of digital humans) in the workspaces you
can see, via GET /v1/communities, or only those one digital human belongs to.
Returns `communities`: each with id, title, description and created_at. Member ids are dropped to
keep the list small; call get_community for a community's digital_human_ids.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
digital_human_id
Only return the communities this digital human belongs to (id from list_digital_humans). Omit to return every community you can see.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"communities": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's id; pass it as community_id to GET /v1/community/{community_id}, PUT /v1/update-community/{community_id} or DELETE /v1/community/{community_id}."
},
"title": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's name."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the community was created."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "What its digital humans have in common."
},
"digital_human_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Ids of its member digital humans (read each with GET /v1/digital-human/{digital_human_id}).",
"additionalProperties": true
}
},
"description": "A community: a named group of digital humans, with its member ids.",
"additionalProperties": true
},
"properties": {},
"description": "The communities you can see; only digital_human_id's when that filter is passed.",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "list_communities",
"title": "List communities",
"description": "List the organization's communities (named groups of digital humans) in the workspaces you\ncan see, via GET /v1/communities, or only those one digital human belongs to.\n\nReturns `communities`: each with id, title, description and created_at. Member ids are dropped to\nkeep the list small; call get_community for a community's digital_human_ids.\n",
"inputSchema": {
"type": "object",
"title": "list_communitiesArguments",
"properties": {
"digital_human_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Digital Human Id",
"default": null,
"description": "Only return the communities this digital human belongs to (id from list_digital_humans). Omit to return every community you can see."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"communities": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's id; pass it as community_id to GET /v1/community/{community_id}, PUT /v1/update-community/{community_id} or DELETE /v1/community/{community_id}."
},
"title": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's name."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the community was created."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "What its digital humans have in common."
},
"digital_human_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Ids of its member digital humans (read each with GET /v1/digital-human/{digital_human_id}).",
"additionalProperties": true
}
},
"description": "A community: a named group of digital humans, with its member ids.",
"additionalProperties": true
},
"properties": {},
"description": "The communities you can see; only digital_human_id's when that filter is passed.",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Change a community in place via PUT /v1/update-community/{community_id}.
title and description are overwritten when passed. digital_human_ids replaces the whole
membership: digital humans left out of the list are removed from the community (they are not
deleted themselves), and the previous member list is not kept. Requires write access to the
community's workspace.
Returns the community after the update: id, title, description, created_at and digital_human_ids.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
community_id
The community to change: its id, from list_communities or create_community.
Clear enough to supply this argument.
title
New name. Omit to keep the current one.
Clear enough to supply this argument.
description
New description. Omit to keep the current one.
Clear enough to supply this argument.
digital_human_ids
The complete new member list, by id from list_digital_humans: it replaces the current members, and [] empties the community. Members must be in the community's workspace. Omit to keep the members.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's id; pass it as community_id to get_community, update_community or delete_community."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"title": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's name."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the community was created."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "What its digital humans have in common."
},
"digital_human_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Ids of its member digital humans (read each with get_digital_human).",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "update_community",
"title": "Update community",
"description": "Change a community in place via PUT /v1/update-community/{community_id}.\n\ntitle and description are overwritten when passed. digital_human_ids replaces the whole\nmembership: digital humans left out of the list are removed from the community (they are not\ndeleted themselves), and the previous member list is not kept. Requires write access to the\ncommunity's workspace.\n\nReturns the community after the update: id, title, description, created_at and digital_human_ids.\n",
"inputSchema": {
"type": "object",
"title": "update_communityArguments",
"required": [
"community_id"
],
"properties": {
"title": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Title",
"default": null,
"description": "New name. Omit to keep the current one."
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description",
"default": null,
"description": "New description. Omit to keep the current one."
},
"community_id": {
"type": "string",
"title": "Community Id",
"format": "uuid",
"description": "The community to change: its id, from list_communities or create_community."
},
"digital_human_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Digital Human Ids",
"default": null,
"description": "The complete new member list, by id from list_digital_humans: it replaces the current members, and [] empties the community. Members must be in the community's workspace. Omit to keep the members."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's id; pass it as community_id to get_community, update_community or delete_community."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"title": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The community's name."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the community was created."
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "What its digital humans have in common."
},
"digital_human_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Ids of its member digital humans (read each with get_digital_human).",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Permanently delete a community and its membership links via DELETE /v1/community/{community_id}.
The member digital humans themselves are not deleted. This cannot be undone. Requires write
access to the community's workspace.
Returns the deleted community's id, title, description and created_at (digital_human_ids is
normally empty, since the links are removed first), plus deleted and community_id.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
community_id
The community to delete: its id, from list_communities or create_community.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Create a scenario-builder workflow: a conversation graph that scripts how a test
conversation can go. Each path through the graph can back a digital human. Writes a
new workflow to your organization (POST /v1/scenario); nothing else is changed.
``definition`` is required (omit or null fails): a React Flow graph object with
``nodes`` and ``edges`` arrays. Use ``{"nodes": [], "edges": []}`` for an empty draft.
Each node: string ``id``, ``type``, ``position`` (x/y), ``data``; each edge: string
``id``, ``source``, ``target`` (node ids). Use ``validate_workflow_definition`` to check
a graph before persisting. Linked agents must be voice agents.
Returns the stored workflow: its ``id`` (for get_workflow, update_workflow,
duplicate_workflow, delete_workflow), name, description, agent_ids, definition,
created_at and any non-blocking lint ``warnings``.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Display name for the new workflow, shown in the scenario builder.
Clear enough to supply this argument.
definition
The conversation graph as a JSON object with `nodes` and `edges` arrays (React Flow shape). Each node has a non-empty string `id` on the node object (not only inside `data`), plus `type`, `position` (x/y) and `data`; each edge has a non-empty string `id`, unique across all edges, plus `source` and `target` node ids. Omitted `nodes` / `edges` default to []; send {"nodes": [], "edges": []} for an empty draft. With no `single` or `options` nodes, the graph is stored as a draft (only multiple-start is rejected). Once there is content, export rules apply (paths, branch_options, etc.).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
description
Free-text note on what the workflow covers. Omit to leave it empty.
Clear enough to supply this argument.
agent_ids
Bluejay ids of voice agents in your organization to link the workflow to (from list_agents). Omit or null for a workflow that is not tied to an agent.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow's id; pass it as workflow_id to get_workflow, update_workflow, duplicate_workflow or delete_workflow."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow's display name."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"warnings": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "Non-blocking lint warnings emitted at save time (e.g. node text referencing an unknown ``{{trait_name}}``). Empty when the definition is clean or no agents are linked.",
"additionalProperties": true
},
"agent_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Bluejay ids of the voice agents the workflow is linked to; empty when it is not tied to an agent.",
"additionalProperties": true
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the workflow was created, as an ISO 8601 timestamp."
},
"definition": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"description": "The stored conversation graph: `start`, `single` and `options` nodes plus edges. Nodes and edges use top-level string `id` fields; edge `id` values are unique within the graph.",
"additionalProperties": true
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The workflow's free-text description."
},
"dh_sync_summary": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Only on update_workflow when the definition changed: counts of digital humans updated, created, marked_stale and skipped, plus errors, from re-syncing this workflow's digital humans."
},
"organization_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Organization that owns the workflow."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_workflow",
"title": "Create workflow",
"description": "Create a scenario-builder workflow: a conversation graph that scripts how a test\nconversation can go. Each path through the graph can back a digital human. Writes a\nnew workflow to your organization (POST /v1/scenario); nothing else is changed.\n\n``definition`` is required (omit or null fails): a React Flow graph object with\n``nodes`` and ``edges`` arrays. Use ``{\"nodes\": [], \"edges\": []}`` for an empty draft.\nEach node: string ``id``, ``type``, ``position`` (x/y), ``data``; each edge: string\n``id``, ``source``, ``target`` (node ids). Use ``validate_workflow_definition`` to check\na graph before persisting. Linked agents must be voice agents.\n\nReturns the stored workflow: its ``id`` (for get_workflow, update_workflow,\nduplicate_workflow, delete_workflow), name, description, agent_ids, definition,\ncreated_at and any non-blocking lint ``warnings``.\n",
"inputSchema": {
"type": "object",
"title": "create_workflowArguments",
"required": [
"name",
"definition"
],
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "Display name for the new workflow, shown in the scenario builder."
},
"agent_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "integer"
}
},
{
"type": "null"
}
],
"title": "Agent Ids",
"default": null,
"description": "Bluejay ids of voice agents in your organization to link the workflow to (from list_agents). Omit or null for a workflow that is not tied to an agent."
},
"definition": {
"type": "object",
"title": "Definition",
"description": "The conversation graph as a JSON object with `nodes` and `edges` arrays (React Flow shape). Each node has a non-empty string `id` on the node object (not only inside `data`), plus `type`, `position` (x/y) and `data`; each edge has a non-empty string `id`, unique across all edges, plus `source` and `target` node ids. Omitted `nodes` / `edges` default to []; send {\"nodes\": [], \"edges\": []} for an empty draft. With no `single` or `options` nodes, the graph is stored as a draft (only multiple-start is rejected). Once there is content, export rules apply (paths, branch_options, etc.).",
"additionalProperties": true
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description",
"default": null,
"description": "Free-text note on what the workflow covers. Omit to leave it empty."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow's id; pass it as workflow_id to get_workflow, update_workflow, duplicate_workflow or delete_workflow."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow's display name."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"warnings": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "Non-blocking lint warnings emitted at save time (e.g. node text referencing an unknown ``{{trait_name}}``). Empty when the definition is clean or no agents are linked.",
"additionalProperties": true
},
"agent_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Bluejay ids of the voice agents the workflow is linked to; empty when it is not tied to an agent.",
"additionalProperties": true
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the workflow was created, as an ISO 8601 timestamp."
},
"definition": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"description": "The stored conversation graph: `start`, `single` and `options` nodes plus edges. Nodes and edges use top-level string `id` fields; edge `id` values are unique within the graph.",
"additionalProperties": true
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The workflow's free-text description."
},
"dh_sync_summary": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Only on update_workflow when the definition changed: counts of digital humans updated, created, marked_stale and skipped, plus errors, from re-syncing this workflow's digital humans."
},
"organization_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Organization that owns the workflow."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Read one scenario-builder workflow by id (GET /v1/scenario/{workflow_id}). Read-only.
Returns the workflow's id, name, description, linked agent_ids, the full ``definition``
graph (every node and edge), created_at and lint warnings. Use list_workflows to find
an id, and read the graph here before editing it with update_workflow.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
workflow_id
The workflow's id, a UUID from list_workflows or create_workflow.
Shorten the title to an action and subject; move usage details into the description.
Description99/100
List your organization's scenario-builder workflows (GET /v1/scenario), optionally
only those linked to one agent. Read-only; deleted workflows are left out.
Returns ``workflows`` (each with id, name, description, agent_ids, definition graph and
created_at) and ``total_count``. Open one with get_workflow.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Only workflows linked to this agent: its Bluejay id from list_agents (it must be in your organization). Omit to list every workflow.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Change a scenario-builder workflow in place (PUT /v1/scenario/{workflow_id}). Only the
fields you pass change, and at least one is required.
Overwrites without keeping the old value: ``definition`` replaces the whole graph (send
every node and edge, not a diff) and ``agent_ids`` replaces the linked agents. Read the
workflow with get_workflow first so nothing is dropped. When the definition changes,
Bluejay re-syncs the digital humans generated from this workflow: existing ones get the
new turns, new paths get new digital humans, and ones whose path is gone are tagged
stale (none are deleted).
Returns the updated workflow (id, name, description, agent_ids, definition, created_at,
warnings) plus ``dh_sync_summary`` when the definition changed.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
workflow_id
The workflow's id, a UUID from list_workflows or create_workflow.
Clear enough to supply this argument.
name
New display name. Omit to keep the current one.
Clear enough to supply this argument.
description
New free-text description; an empty string clears it. Omit to keep the current one.
Clear enough to supply this argument.
definition
A complete replacement graph with `nodes` and `edges`, same shape as on create_workflow: each node needs a top-level `id`; each edge needs a top-level `id` unique among edges. It overwrites the whole stored graph, so start from the definition get_workflow returns. Omit to keep the current graph.
Clear enough to supply this argument.
agent_ids
The full new set of linked agent ids (voice agents in your organization, from list_agents), replacing the current links; [] or null unlinks all. Omit to keep the current links.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow's id; pass it as workflow_id to get_workflow, update_workflow, duplicate_workflow or delete_workflow."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow's display name."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"warnings": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "Non-blocking lint warnings emitted at save time (e.g. node text referencing an unknown ``{{trait_name}}``). Empty when the definition is clean or no agents are linked.",
"additionalProperties": true
},
"agent_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Bluejay ids of the voice agents the workflow is linked to; empty when it is not tied to an agent.",
"additionalProperties": true
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the workflow was created, as an ISO 8601 timestamp."
},
"definition": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"description": "The stored conversation graph: `start`, `single` and `options` nodes plus edges. Nodes and edges use top-level string `id` fields; edge `id` values are unique within the graph.",
"additionalProperties": true
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The workflow's free-text description."
},
"dh_sync_summary": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Only on update_workflow when the definition changed: counts of digital humans updated, created, marked_stale and skipped, plus errors, from re-syncing this workflow's digital humans."
},
"organization_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Organization that owns the workflow."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "update_workflow",
"title": "Update workflow",
"description": "Change a scenario-builder workflow in place (PUT /v1/scenario/{workflow_id}). Only the\nfields you pass change, and at least one is required.\n\nOverwrites without keeping the old value: ``definition`` replaces the whole graph (send\nevery node and edge, not a diff) and ``agent_ids`` replaces the linked agents. Read the\nworkflow with get_workflow first so nothing is dropped. When the definition changes,\nBluejay re-syncs the digital humans generated from this workflow: existing ones get the\nnew turns, new paths get new digital humans, and ones whose path is gone are tagged\nstale (none are deleted).\n\nReturns the updated workflow (id, name, description, agent_ids, definition, created_at,\nwarnings) plus ``dh_sync_summary`` when the definition changed.\n",
"inputSchema": {
"type": "object",
"title": "update_workflowArguments",
"required": [
"workflow_id"
],
"properties": {
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Name",
"default": null,
"description": "New display name. Omit to keep the current one."
},
"agent_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "integer"
}
},
{
"type": "null"
}
],
"title": "Agent Ids",
"default": null,
"description": "The full new set of linked agent ids (voice agents in your organization, from list_agents), replacing the current links; [] or null unlinks all. Omit to keep the current links."
},
"definition": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Definition",
"default": null,
"description": "A complete replacement graph with `nodes` and `edges`, same shape as on create_workflow: each node needs a top-level `id`; each edge needs a top-level `id` unique among edges. It overwrites the whole stored graph, so start from the definition get_workflow returns. Omit to keep the current graph."
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description",
"default": null,
"description": "New free-text description; an empty string clears it. Omit to keep the current one."
},
"workflow_id": {
"type": "string",
"title": "Workflow Id",
"description": "The workflow's id, a UUID from list_workflows or create_workflow."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow's id; pass it as workflow_id to get_workflow, update_workflow, duplicate_workflow or delete_workflow."
},
"name": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow's display name."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"warnings": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"string",
"integer",
"number",
"null"
]
},
"properties": {},
"description": "Non-blocking lint warnings emitted at save time (e.g. node text referencing an unknown ``{{trait_name}}``). Empty when the definition is clean or no agents are linked.",
"additionalProperties": true
},
"agent_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Bluejay ids of the voice agents the workflow is linked to; empty when it is not tied to an agent.",
"additionalProperties": true
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the workflow was created, as an ISO 8601 timestamp."
},
"definition": {
"type": [
"object",
"array",
"null"
],
"properties": {},
"description": "The stored conversation graph: `start`, `single` and `options` nodes plus edges. Nodes and edges use top-level string `id` fields; edge `id` values are unique within the graph.",
"additionalProperties": true
},
"description": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The workflow's free-text description."
},
"dh_sync_summary": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Only on update_workflow when the definition changed: counts of digital humans updated, created, marked_stale and skipped, plus errors, from re-syncing this workflow's digital humans."
},
"organization_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Organization that owns the workflow."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Delete a scenario-builder workflow (DELETE /v1/scenario/{workflow_id}).
The workflow disappears from list_workflows and get_workflow at once and moves to Recently
Deleted, where it can be restored in the app for 30 days before it is permanently
purged. Confirm with the user before calling. Returns ``deleted`` and the ``workflow_id``.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
workflow_id
The workflow's id, a UUID from list_workflows or create_workflow.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the workflow was moved to Recently Deleted."
},
"message": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Confirmation message."
},
"workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The id of the workflow that was deleted."
},
"deleted_workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The deleted workflow's id."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "delete_workflow",
"title": "Delete workflow",
"description": "Delete a scenario-builder workflow (DELETE /v1/scenario/{workflow_id}).\n\nThe workflow disappears from list_workflows and get_workflow at once and moves to Recently\nDeleted, where it can be restored in the app for 30 days before it is permanently\npurged. Confirm with the user before calling. Returns ``deleted`` and the ``workflow_id``.\n",
"inputSchema": {
"type": "object",
"title": "delete_workflowArguments",
"required": [
"workflow_id"
],
"properties": {
"workflow_id": {
"type": "string",
"title": "Workflow Id",
"description": "The workflow's id, a UUID from list_workflows or create_workflow."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the workflow was moved to Recently Deleted."
},
"message": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Confirmation message."
},
"workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The id of the workflow that was deleted."
},
"deleted_workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The deleted workflow's id."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Copy a scenario-builder workflow into a new workflow with the same definition graph and
agent links (POST /v1/scenario/{workflow_id}/duplicate). The original is not changed.
``name`` is optional; when omitted the copy is named ``"Copy of {original}"``.
Returns the new copy: its own ``id`` (use it to edit the copy with update_workflow), name,
description, agent_ids, definition, created_at and lint warnings.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
workflow_id
The workflow to copy: its id, a UUID from list_workflows.
Clear enough to supply this argument.
name
Name for the copy. Omit or null for "Copy of {original name}".
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Check a scenario-builder graph against the save rules without storing anything
(POST /v1/scenario/validate-definition). Read-only.
Provide exactly one of ``definition`` (object) or ``json_text`` (stringified JSON).
Returns ``success: true`` when the graph is valid; otherwise ``error`` says what is wrong
(bad JSON, missing node or edge ids, duplicate edge ids, multiple starts, and so on). Run
it before create_workflow or update_workflow.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Input documentation gives an agent enough context to populate the arguments.
definition
The graph to check as a JSON object with nodes and edges, same shape as the `definition` of create_workflow. Give this or json_text, not both.
Clear enough to supply this argument.
json_text
The same graph as a JSON string, e.g. pasted by a user. Give this or definition, not both.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"success": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the graph passes the same checks create_workflow and update_workflow apply. An invalid graph is rejected with an error whose detail names the problem."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "validate_workflow_definition",
"title": "Validate workflow definition",
"description": "Check a scenario-builder graph against the save rules without storing anything\n(POST /v1/scenario/validate-definition). Read-only.\n\nProvide exactly one of ``definition`` (object) or ``json_text`` (stringified JSON).\n\nReturns ``success: true`` when the graph is valid; otherwise ``error`` says what is wrong\n(bad JSON, missing node or edge ids, duplicate edge ids, multiple starts, and so on). Run\nit before create_workflow or update_workflow.\n",
"inputSchema": {
"type": "object",
"title": "validate_workflow_definitionArguments",
"properties": {
"json_text": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Json Text",
"default": null,
"description": "The same graph as a JSON string, e.g. pasted by a user. Give this or definition, not both."
},
"definition": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Definition",
"default": null,
"description": "The graph to check as a JSON object with nodes and edges, same shape as the `definition` of create_workflow. Give this or json_text, not both."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"success": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the graph passes the same checks create_workflow and update_workflow apply. An invalid graph is rejected with an error whose detail names the problem."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Add a node to a scenario-builder workflow and save it (writes /v1/scenario/{workflow_id}).
The workflow is read, the node appended, the definition validated and written back
whole; if validation fails nothing is saved. The new node has no edges: wire it with
add_scenario_edge. `node_type` decides which leg of the phone tree you are adding and
which fields apply. Fields belonging to another type are rejected, not ignored.
node_type="ivr_menu" — the automated menu. `options` is required. The prompt the IVR
plays is every option's `phrase` joined with ". ", and each option becomes a source
handle `opt-<id>` you wire up with add_scenario_edge, one edge per option.
node_type="hold" — hold music. `duration_ms` is required and 0 means skip the wait,
with optional "please hold" / "thanks for waiting" lines around it.
node_type="human_agent" — the Bluejay-emulated live representative. `intent` (what
the rep should accomplish) and `success_criteria` (how the eval grades the leg) are
both required; the timing fields bound the leg. At most one outbound edge.
Shared: `position`, `label`, `node_id`. `voice_accent` and `voice_speed` override
the TTS voice on the ivr_menu prompt or the human_agent rep.
Returns workflow_id, node_id (for add_scenario_edge and update_scenario_node) and
node (the saved id, type, position and data).
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
workflow_id
The workflow's id, a UUID from list_workflows or create_workflow.
Clear enough to supply this argument.
node_type
Which kind of node: ivr_menu (automated menu), hold (hold audio) or human_agent (emulated live representative). It decides which other fields apply.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
options
ivr_menu only: the menu choices, e.g. [{"id": "billing", "phrase": "For billing, press 1", "label": "Billing"}]. id is unique in the menu and becomes the edge handle opt-<id>; phrase is what the menu says (all phrases joined form the prompt); label is optional display text. Required for ivr_menu.
Clear enough to supply this argument.
duration_ms
hold only, required there: how long hold audio plays, in milliseconds; 0 skips the wait.
Clear enough to supply this argument.
intent
human_agent only, required there: what the emulated representative should accomplish on this leg.
Clear enough to supply this argument.
success_criteria
human_agent only, required there: how the eval decides this leg passed.
Clear enough to supply this argument.
position
Where the node sits on the canvas, e.g. {"x": 240, "y": 120}. Omitted, {"x": 0, "y": 0}.
Clear enough to supply this argument.
label
Display name shown on the node in the scenario builder.
Clear enough to supply this argument.
node_id
Id to give the node instead of a generated one like ivr_menu-1a2b3c4d; it must not already exist in the workflow.
Clear enough to supply this argument.
barge_in_allowed
ivr_menu only: whether the caller may talk or press keys over the menu prompt. Omitted, true.
Clear enough to supply this argument.
interdigit_timeout_ms
ivr_menu only: milliseconds the menu waits between keypresses.
Explain what happens when this optional value is omitted.
message_before_hold
hold only: line spoken before the hold audio, e.g. "Please hold."
Clear enough to supply this argument.
message_after_hold
hold only: line spoken after the hold audio, e.g. "Thanks for waiting."
Clear enough to supply this argument.
pickup_delay_ms
human_agent only: milliseconds before the representative picks up. Omitted, 1500.
Clear enough to supply this argument.
max_talk_duration_ms
human_agent only: hard cap in milliseconds on the representative's talk time before the leg ends. Omitted, 180000.
Clear enough to supply this argument.
min_talk_duration_ms
human_agent only: milliseconds the leg lasts before meeting success_criteria can end it. Omitted, 30000.
Clear enough to supply this argument.
speaks_first
human_agent only: true for the representative to speak first after pickup, false for the caller. Omitted, true.
Clear enough to supply this argument.
voice_accent
ivr_menu or human_agent: accent of this node's TTS voice, as <language>_<accent>_<masculine|feminine> from get_voice_options (e.g. en_british_feminine). Omitted, the test case's voice.
Clear enough to supply this argument.
voice_speed
ivr_menu or human_agent: speaking speed of this node's TTS voice: slowest, slow, normal, fast or fastest. Omitted, the test case's speed.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"node": {
"type": [
"object",
"array",
"null"
],
"description": "The node as saved: id, type, position and data (its type-specific fields)."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"node_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The node's id, for add_scenario_edge, update_scenario_node and delete_scenario_node."
},
"workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow that was edited."
},
"validation_errors": {
"type": [
"array",
"object",
"null"
],
"description": "The validator's errors when the edit would leave the workflow invalid; nothing was saved."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_scenario_node",
"title": "Create scenario node",
"description": "Add a node to a scenario-builder workflow and save it (writes /v1/scenario/{workflow_id}).\n\nThe workflow is read, the node appended, the definition validated and written back\nwhole; if validation fails nothing is saved. The new node has no edges: wire it with\nadd_scenario_edge. `node_type` decides which leg of the phone tree you are adding and\nwhich fields apply. Fields belonging to another type are rejected, not ignored.\n\nnode_type=\"ivr_menu\" — the automated menu. `options` is required. The prompt the IVR\nplays is every option's `phrase` joined with \". \", and each option becomes a source\nhandle `opt-<id>` you wire up with add_scenario_edge, one edge per option.\n\nnode_type=\"hold\" — hold music. `duration_ms` is required and 0 means skip the wait,\nwith optional \"please hold\" / \"thanks for waiting\" lines around it.\n\nnode_type=\"human_agent\" — the Bluejay-emulated live representative. `intent` (what\nthe rep should accomplish) and `success_criteria` (how the eval grades the leg) are\nboth required; the timing fields bound the leg. At most one outbound edge.\n\nShared: `position`, `label`, `node_id`. `voice_accent` and `voice_speed` override\nthe TTS voice on the ivr_menu prompt or the human_agent rep.\n\nReturns workflow_id, node_id (for add_scenario_edge and update_scenario_node) and\nnode (the saved id, type, position and data).\n",
"inputSchema": {
"type": "object",
"title": "create_scenario_nodeArguments",
"required": [
"workflow_id",
"node_type"
],
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Label",
"default": null,
"description": "Display name shown on the node in the scenario builder."
},
"intent": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Intent",
"default": null,
"description": "human_agent only, required there: what the emulated representative should accomplish on this leg."
},
"node_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Node Id",
"default": null,
"description": "Id to give the node instead of a generated one like ivr_menu-1a2b3c4d; it must not already exist in the workflow."
},
"options": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
{
"type": "null"
}
],
"title": "Options",
"default": null,
"description": "ivr_menu only: the menu choices, e.g. [{\"id\": \"billing\", \"phrase\": \"For billing, press 1\", \"label\": \"Billing\"}]. id is unique in the menu and becomes the edge handle opt-<id>; phrase is what the menu says (all phrases joined form the prompt); label is optional display text. Required for ivr_menu."
},
"position": {
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "number"
}
},
{
"type": "null"
}
],
"title": "Position",
"default": null,
"description": "Where the node sits on the canvas, e.g. {\"x\": 240, \"y\": 120}. Omitted, {\"x\": 0, \"y\": 0}."
},
"node_type": {
"enum": [
"ivr_menu",
"hold",
"human_agent"
],
"type": "string",
"title": "Node Type",
"description": "Which kind of node: ivr_menu (automated menu), hold (hold audio) or human_agent (emulated live representative). It decides which other fields apply."
},
"duration_ms": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Duration Ms",
"default": null,
"description": "hold only, required there: how long hold audio plays, in milliseconds; 0 skips the wait."
},
"voice_speed": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Voice Speed",
"default": null,
"description": "ivr_menu or human_agent: speaking speed of this node's TTS voice: slowest, slow, normal, fast or fastest. Omitted, the test case's speed."
},
"workflow_id": {
"type": "string",
"title": "Workflow Id",
"description": "The workflow's id, a UUID from list_workflows or create_workflow."
},
"speaks_first": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Speaks First",
"default": null,
"description": "human_agent only: true for the representative to speak first after pickup, false for the caller. Omitted, true."
},
"voice_accent": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Voice Accent",
"default": null,
"description": "ivr_menu or human_agent: accent of this node's TTS voice, as <language>_<accent>_<masculine|feminine> from get_voice_options (e.g. en_british_feminine). Omitted, the test case's voice."
},
"pickup_delay_ms": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Pickup Delay Ms",
"default": null,
"description": "human_agent only: milliseconds before the representative picks up. Omitted, 1500."
},
"barge_in_allowed": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Barge In Allowed",
"default": null,
"description": "ivr_menu only: whether the caller may talk or press keys over the menu prompt. Omitted, true."
},
"success_criteria": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Success Criteria",
"default": null,
"description": "human_agent only, required there: how the eval decides this leg passed."
},
"message_after_hold": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Message After Hold",
"default": null,
"description": "hold only: line spoken after the hold audio, e.g. \"Thanks for waiting.\""
},
"message_before_hold": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Message Before Hold",
"default": null,
"description": "hold only: line spoken before the hold audio, e.g. \"Please hold.\""
},
"max_talk_duration_ms": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Max Talk Duration Ms",
"default": null,
"description": "human_agent only: hard cap in milliseconds on the representative's talk time before the leg ends. Omitted, 180000."
},
"min_talk_duration_ms": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Min Talk Duration Ms",
"default": null,
"description": "human_agent only: milliseconds the leg lasts before meeting success_criteria can end it. Omitted, 30000."
},
"interdigit_timeout_ms": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Interdigit Timeout Ms",
"default": null,
"description": "ivr_menu only: milliseconds the menu waits between keypresses."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"node": {
"type": [
"object",
"array",
"null"
],
"description": "The node as saved: id, type, position and data (its type-specific fields)."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"node_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The node's id, for add_scenario_edge, update_scenario_node and delete_scenario_node."
},
"workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow that was edited."
},
"validation_errors": {
"type": [
"array",
"object",
"null"
],
"description": "The validator's errors when the edit would leave the workflow invalid; nothing was saved."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Partial update of one scenario-builder node's data fields, saved immediately.
`node_id` picks the node and `node_type` must match that node's actual type —
it selects which fields are writable, and fields belonging to another type are
rejected. Only the fields you pass change; at least one must be provided. The
workflow is read, the node edited, validated and written back whole, overwriting
the old values with no history; if validation fails nothing is saved.
The fields carry the same meaning as in create_scenario_node: `options` for
ivr_menu (editing it drops the `opt-<id>` handle of any removed option, so
re-wire those edges), `duration_ms` and the hold messages for hold, `intent` /
`success_criteria` and the timing bounds for human_agent. Pass voice_accent=""
or voice_speed="" to clear an override and go back to inheriting the test
case's voice.
Returns workflow_id, node_id and node (the saved id, type, position and data).
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
workflow_id
The workflow's id, a UUID from list_workflows or create_workflow.
Clear enough to supply this argument.
node_id
The node to change: an id from list_scenario_nodes.
Clear enough to supply this argument.
node_type
The node's current type, as list_scenario_nodes shows it; it selects which fields are writable.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
options
ivr_menu only: the menu choices, e.g. [{"id": "billing", "phrase": "For billing, press 1", "label": "Billing"}]. id is unique in the menu and becomes the edge handle opt-<id>; phrase is what the menu says (all phrases joined form the prompt); label is optional display text. Replaces the whole list.
Clear enough to supply this argument.
duration_ms
hold only: new hold length in milliseconds; 0 skips the wait.
Clear enough to supply this argument.
intent
human_agent only: new goal for the emulated representative on this leg.
Clear enough to supply this argument.
success_criteria
human_agent only: new rule for how the eval decides this leg passed.
Clear enough to supply this argument.
label
New display name shown on the node.
Clear enough to supply this argument.
barge_in_allowed
ivr_menu only: whether the caller may talk or press keys over the menu prompt.
Clear enough to supply this argument.
interdigit_timeout_ms
ivr_menu only: milliseconds the menu waits between keypresses.
Clear enough to supply this argument.
message_before_hold
hold only: line spoken before the hold audio; "" stores an empty line.
Clear enough to supply this argument.
message_after_hold
hold only: line spoken after the hold audio; "" stores an empty line.
Clear enough to supply this argument.
pickup_delay_ms
human_agent only: milliseconds before the representative picks up.
Clear enough to supply this argument.
max_talk_duration_ms
human_agent only: hard cap in milliseconds on the representative's talk time.
Clear enough to supply this argument.
min_talk_duration_ms
human_agent only: milliseconds the leg lasts before meeting success_criteria can end it.
Clear enough to supply this argument.
speaks_first
human_agent only: true for the representative to speak first after pickup, false for the caller.
Clear enough to supply this argument.
voice_accent
ivr_menu or human_agent: accent of this node's TTS voice, as <language>_<accent>_<masculine|feminine> from get_voice_options (e.g. en_british_feminine). Omitted, the test case's voice. "" clears the override.
Clear enough to supply this argument.
voice_speed
ivr_menu or human_agent: speaking speed of this node's TTS voice: slowest, slow, normal, fast or fastest. Omitted, the test case's speed. "" clears the override.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"node": {
"type": [
"object",
"array",
"null"
],
"description": "The node as saved: id, type, position and data (its type-specific fields)."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"node_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The node's id, for add_scenario_edge, update_scenario_node and delete_scenario_node."
},
"workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow that was edited."
},
"validation_errors": {
"type": [
"array",
"object",
"null"
],
"description": "The validator's errors when the edit would leave the workflow invalid; nothing was saved."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "update_scenario_node",
"title": "Update scenario node",
"description": "Partial update of one scenario-builder node's data fields, saved immediately.\n\n`node_id` picks the node and `node_type` must match that node's actual type —\nit selects which fields are writable, and fields belonging to another type are\nrejected. Only the fields you pass change; at least one must be provided. The\nworkflow is read, the node edited, validated and written back whole, overwriting\nthe old values with no history; if validation fails nothing is saved.\n\nThe fields carry the same meaning as in create_scenario_node: `options` for\nivr_menu (editing it drops the `opt-<id>` handle of any removed option, so\nre-wire those edges), `duration_ms` and the hold messages for hold, `intent` /\n`success_criteria` and the timing bounds for human_agent. Pass voice_accent=\"\"\nor voice_speed=\"\" to clear an override and go back to inheriting the test\ncase's voice.\n\nReturns workflow_id, node_id and node (the saved id, type, position and data).\n",
"inputSchema": {
"type": "object",
"title": "update_scenario_nodeArguments",
"required": [
"workflow_id",
"node_id",
"node_type"
],
"properties": {
"label": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Label",
"default": null,
"description": "New display name shown on the node."
},
"intent": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Intent",
"default": null,
"description": "human_agent only: new goal for the emulated representative on this leg."
},
"node_id": {
"type": "string",
"title": "Node Id",
"description": "The node to change: an id from list_scenario_nodes."
},
"options": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
{
"type": "null"
}
],
"title": "Options",
"default": null,
"description": "ivr_menu only: the menu choices, e.g. [{\"id\": \"billing\", \"phrase\": \"For billing, press 1\", \"label\": \"Billing\"}]. id is unique in the menu and becomes the edge handle opt-<id>; phrase is what the menu says (all phrases joined form the prompt); label is optional display text. Replaces the whole list."
},
"node_type": {
"enum": [
"ivr_menu",
"hold",
"human_agent"
],
"type": "string",
"title": "Node Type",
"description": "The node's current type, as list_scenario_nodes shows it; it selects which fields are writable."
},
"duration_ms": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Duration Ms",
"default": null,
"description": "hold only: new hold length in milliseconds; 0 skips the wait."
},
"voice_speed": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Voice Speed",
"default": null,
"description": "ivr_menu or human_agent: speaking speed of this node's TTS voice: slowest, slow, normal, fast or fastest. Omitted, the test case's speed. \"\" clears the override."
},
"workflow_id": {
"type": "string",
"title": "Workflow Id",
"description": "The workflow's id, a UUID from list_workflows or create_workflow."
},
"speaks_first": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Speaks First",
"default": null,
"description": "human_agent only: true for the representative to speak first after pickup, false for the caller."
},
"voice_accent": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Voice Accent",
"default": null,
"description": "ivr_menu or human_agent: accent of this node's TTS voice, as <language>_<accent>_<masculine|feminine> from get_voice_options (e.g. en_british_feminine). Omitted, the test case's voice. \"\" clears the override."
},
"pickup_delay_ms": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Pickup Delay Ms",
"default": null,
"description": "human_agent only: milliseconds before the representative picks up."
},
"barge_in_allowed": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Barge In Allowed",
"default": null,
"description": "ivr_menu only: whether the caller may talk or press keys over the menu prompt."
},
"success_criteria": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Success Criteria",
"default": null,
"description": "human_agent only: new rule for how the eval decides this leg passed."
},
"message_after_hold": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Message After Hold",
"default": null,
"description": "hold only: line spoken after the hold audio; \"\" stores an empty line."
},
"message_before_hold": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Message Before Hold",
"default": null,
"description": "hold only: line spoken before the hold audio; \"\" stores an empty line."
},
"max_talk_duration_ms": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Max Talk Duration Ms",
"default": null,
"description": "human_agent only: hard cap in milliseconds on the representative's talk time."
},
"min_talk_duration_ms": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Min Talk Duration Ms",
"default": null,
"description": "human_agent only: milliseconds the leg lasts before meeting success_criteria can end it."
},
"interdigit_timeout_ms": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Interdigit Timeout Ms",
"default": null,
"description": "ivr_menu only: milliseconds the menu waits between keypresses."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"node": {
"type": [
"object",
"array",
"null"
],
"description": "The node as saved: id, type, position and data (its type-specific fields)."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"node_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The node's id, for add_scenario_edge, update_scenario_node and delete_scenario_node."
},
"workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow that was edited."
},
"validation_errors": {
"type": [
"array",
"object",
"null"
],
"description": "The validator's errors when the edit would leave the workflow invalid; nothing was saved."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Remove a node from a scenario-builder workflow. Cascades every edge
that touches the node (incoming OR outgoing). The workflow is saved in place
with no undo; re-create the node and edges to restore them.
**Requires explicit user confirmation.** Calling pattern:
1. First call with ``confirmed=False`` (the default) — returns
``{needs_confirmation: True, preview: "...", ...}`` describing what
would happen.
2. Relay the preview to the user and ask "Do you want me to proceed?".
3. ONLY after the user explicitly approves, call again with
``confirmed=True`` and the same arguments.
Works on any node type (ivr_menu, hold, human_agent, single, options, start).
The ``start`` node is structurally required by the validator — deleting it
will fail validation and the change will be rejected before persistence.
The confirmed call returns workflow_id, node_id, cascaded_edge_ids (the edges
removed with it) and deleted=True.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
workflow_id
The workflow's id, a UUID from list_workflows or create_workflow.
Clear enough to supply this argument.
node_id
The node to delete: an id from list_scenario_nodes.
Clear enough to supply this argument.
confirmed
false returns a preview and changes nothing; true performs the delete. Pass true only after the user approved that preview.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Preview only: the tool to call again with confirmed=true."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True once the delete is saved."
},
"node_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The node deleted (or, on the preview, to be deleted)."
},
"preview": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Preview only: what the delete would do, to relay to the user."
},
"to_proceed": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Preview only: how to proceed once the user approves."
},
"workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow the node is in."
},
"cascaded_edge_ids": {
"type": [
"array",
"object",
"null"
],
"description": "Ids of the edges removed with the node."
},
"validation_errors": {
"type": [
"array",
"object",
"null"
],
"description": "The validator's errors when the edit would leave the workflow invalid; nothing was saved."
},
"needs_confirmation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True on the preview call: nothing changed yet."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "delete_scenario_node",
"title": "Delete scenario node",
"description": "Remove a node from a scenario-builder workflow. Cascades every edge\nthat touches the node (incoming OR outgoing). The workflow is saved in place\nwith no undo; re-create the node and edges to restore them.\n\n**Requires explicit user confirmation.** Calling pattern:\n 1. First call with ``confirmed=False`` (the default) — returns\n ``{needs_confirmation: True, preview: \"...\", ...}`` describing what\n would happen.\n 2. Relay the preview to the user and ask \"Do you want me to proceed?\".\n 3. ONLY after the user explicitly approves, call again with\n ``confirmed=True`` and the same arguments.\n\nWorks on any node type (ivr_menu, hold, human_agent, single, options, start).\nThe ``start`` node is structurally required by the validator — deleting it\nwill fail validation and the change will be rejected before persistence.\n\nThe confirmed call returns workflow_id, node_id, cascaded_edge_ids (the edges\nremoved with it) and deleted=True.\n",
"inputSchema": {
"type": "object",
"title": "delete_scenario_nodeArguments",
"required": [
"workflow_id",
"node_id"
],
"properties": {
"node_id": {
"type": "string",
"title": "Node Id",
"description": "The node to delete: an id from list_scenario_nodes."
},
"confirmed": {
"type": "boolean",
"title": "Confirmed",
"default": false,
"description": "false returns a preview and changes nothing; true performs the delete. Pass true only after the user approved that preview."
},
"workflow_id": {
"type": "string",
"title": "Workflow Id",
"description": "The workflow's id, a UUID from list_workflows or create_workflow."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Preview only: the tool to call again with confirmed=true."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True once the delete is saved."
},
"node_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The node deleted (or, on the preview, to be deleted)."
},
"preview": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Preview only: what the delete would do, to relay to the user."
},
"to_proceed": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Preview only: how to proceed once the user approves."
},
"workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow the node is in."
},
"cascaded_edge_ids": {
"type": [
"array",
"object",
"null"
],
"description": "Ids of the edges removed with the node."
},
"validation_errors": {
"type": [
"array",
"object",
"null"
],
"description": "The validator's errors when the edit would leave the workflow invalid; nothing was saved."
},
"needs_confirmation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True on the preview call: nothing changed yet."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description87/100
Add an edge between two nodes in a scenario-builder workflow. Saved immediately.
For edges originating at an ``ivr_menu`` node, ``source_handle`` is REQUIRED
and must be ``"opt-<option_id>"`` matching a real option on the source node
— that's the routing key the runtime keys DTMF branches on. For ``hold`` and
``human_agent`` sources, leave ``source_handle`` out (single source handle
on the canvas).
``hold`` and ``human_agent`` nodes accept at most ONE outbound edge — the
backend validator will reject the workflow if you add a second.
Writes to the scenario-builder workflow via ``/v1/scenario/{workflow_id}``.
Returns ``{workflow_id, edge_id, edge, error}``.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
workflow_id
The workflow's id, a UUID from list_workflows or create_workflow.
Clear enough to supply this argument.
source_node_id
Node the connection leaves from: an id from list_scenario_nodes or create_scenario_node.
Clear enough to supply this argument.
target_node_id
Node the connection leads to: an id from list_scenario_nodes or create_scenario_node.
Clear enough to supply this argument.
source_handle
Needed when the source is an ivr_menu: opt-<option id> of the menu option this branch follows, e.g. opt-billing. Leave it out for hold and human_agent sources.
Clear enough to supply this argument.
edge_id
Id to give the edge instead of a generated one like edge-1a2b3c4d; it must not already exist in the workflow.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"edge": {
"type": [
"object",
"array",
"null"
],
"description": "The edge as saved: id, source, target and sourceHandle when set."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"edge_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The new edge's id, for delete_scenario_edge."
},
"workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow that was edited."
},
"validation_errors": {
"type": [
"array",
"object",
"null"
],
"description": "The validator's errors when the edit would leave the workflow invalid; nothing was saved."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "add_scenario_edge",
"title": "Add scenario edge",
"description": "Add an edge between two nodes in a scenario-builder workflow. Saved immediately.\n\nFor edges originating at an ``ivr_menu`` node, ``source_handle`` is REQUIRED\nand must be ``\"opt-<option_id>\"`` matching a real option on the source node\n— that's the routing key the runtime keys DTMF branches on. For ``hold`` and\n``human_agent`` sources, leave ``source_handle`` out (single source handle\non the canvas).\n\n``hold`` and ``human_agent`` nodes accept at most ONE outbound edge — the\nbackend validator will reject the workflow if you add a second.\n\nWrites to the scenario-builder workflow via ``/v1/scenario/{workflow_id}``.\nReturns ``{workflow_id, edge_id, edge, error}``.\n",
"inputSchema": {
"type": "object",
"title": "add_scenario_edgeArguments",
"required": [
"workflow_id",
"source_node_id",
"target_node_id"
],
"properties": {
"edge_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Edge Id",
"default": null,
"description": "Id to give the edge instead of a generated one like edge-1a2b3c4d; it must not already exist in the workflow."
},
"workflow_id": {
"type": "string",
"title": "Workflow Id",
"description": "The workflow's id, a UUID from list_workflows or create_workflow."
},
"source_handle": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Source Handle",
"default": null,
"description": "Needed when the source is an ivr_menu: opt-<option id> of the menu option this branch follows, e.g. opt-billing. Leave it out for hold and human_agent sources."
},
"source_node_id": {
"type": "string",
"title": "Source Node Id",
"description": "Node the connection leaves from: an id from list_scenario_nodes or create_scenario_node."
},
"target_node_id": {
"type": "string",
"title": "Target Node Id",
"description": "Node the connection leads to: an id from list_scenario_nodes or create_scenario_node."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"edge": {
"type": [
"object",
"array",
"null"
],
"description": "The edge as saved: id, source, target and sourceHandle when set."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"edge_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The new edge's id, for delete_scenario_edge."
},
"workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow that was edited."
},
"validation_errors": {
"type": [
"array",
"object",
"null"
],
"description": "The validator's errors when the edit would leave the workflow invalid; nothing was saved."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Remove an edge by id from a scenario-builder workflow.
**Requires explicit user confirmation.** Same two-call pattern as
``delete_scenario_node``: first call with ``confirmed=False`` returns a
``needs_confirmation`` payload with a ``preview``; only call with
``confirmed=True`` after the user approves. Both endpoints survive — only the
connection is dropped, saved in place with no undo (add_scenario_edge restores it).
An ivr_menu option left without an edge is no longer routable.
The confirmed call returns workflow_id, edge_id and deleted=True.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
workflow_id
The workflow's id, a UUID from list_workflows or create_workflow.
Clear enough to supply this argument.
edge_id
The edge to remove: an id from the edges of list_scenario_nodes, or from add_scenario_edge.
Clear enough to supply this argument.
confirmed
false returns a preview and changes nothing; true performs the delete. Pass true only after the user approved that preview.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Preview only: the tool to call again with confirmed=true."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True once the delete is saved."
},
"edge_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The edge deleted (or, on the preview, to be deleted)."
},
"preview": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Preview only: what the delete would do, to relay to the user."
},
"to_proceed": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Preview only: how to proceed once the user approves."
},
"workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow the edge is in."
},
"validation_errors": {
"type": [
"array",
"object",
"null"
],
"description": "The validator's errors when the edit would leave the workflow invalid; nothing was saved."
},
"needs_confirmation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True on the preview call: nothing changed yet."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "delete_scenario_edge",
"title": "Delete scenario edge",
"description": "Remove an edge by id from a scenario-builder workflow.\n\n**Requires explicit user confirmation.** Same two-call pattern as\n``delete_scenario_node``: first call with ``confirmed=False`` returns a\n``needs_confirmation`` payload with a ``preview``; only call with\n``confirmed=True`` after the user approves. Both endpoints survive — only the\nconnection is dropped, saved in place with no undo (add_scenario_edge restores it).\nAn ivr_menu option left without an edge is no longer routable.\n\nThe confirmed call returns workflow_id, edge_id and deleted=True.\n",
"inputSchema": {
"type": "object",
"title": "delete_scenario_edgeArguments",
"required": [
"workflow_id",
"edge_id"
],
"properties": {
"edge_id": {
"type": "string",
"title": "Edge Id",
"description": "The edge to remove: an id from the edges of list_scenario_nodes, or from add_scenario_edge."
},
"confirmed": {
"type": "boolean",
"title": "Confirmed",
"default": false,
"description": "false returns a preview and changes nothing; true performs the delete. Pass true only after the user approved that preview."
},
"workflow_id": {
"type": "string",
"title": "Workflow Id",
"description": "The workflow's id, a UUID from list_workflows or create_workflow."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Preview only: the tool to call again with confirmed=true."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True once the delete is saved."
},
"edge_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The edge deleted (or, on the preview, to be deleted)."
},
"preview": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Preview only: what the delete would do, to relay to the user."
},
"to_proceed": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Preview only: how to proceed once the user approves."
},
"workflow_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The workflow the edge is in."
},
"validation_errors": {
"type": [
"array",
"object",
"null"
],
"description": "The validator's errors when the edit would leave the workflow invalid; nothing was saved."
},
"needs_confirmation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True on the preview call: nothing changed yet."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Return a compact view of the workflow's nodes and edges — enough to orient
follow-up edits without paying for the full ``definition`` blob. Read-only.
Shape: ``{"workflow_id", "nodes": [{id, type, label, ...type-specific fields}],
"edges": [{id, source, target, sourceHandle?}], "error"}``. Use this before
``update_*_node`` / ``add_scenario_edge`` so you know which ids exist.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
workflow_id
The workflow's id, a UUID from list_workflows or create_workflow.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Schedule a simulation to run automatically via POST /v1/create-schedule.
Stores a recurring trigger that starts a full run of simulation_id every time it fires, until it
is paused or deleted. Each fire is a real simulation run against the agent (real calls or
conversations, the same as queuing a run by hand), so a tight interval multiplies runs and usage.
The timing is converted to a cron expression and read in UTC. A simulation can have more than one
schedule. Requires write access to the simulation's workspace.
Returns the new schedule: its id (for get_schedule, update_schedule, delete_schedule),
simulation_id, the stored cron_expression, enabled and timezone.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
simulation_id
The simulation to run on this schedule: its id, from list_simulations.
Clear enough to supply this argument.
$defs › ScheduleWindow › days
Weekdays the window is open on, e.g. ["monday", "friday"]. Leave empty for every day.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › ScheduleWindow › start_time
Time of day the window opens, as a zero-padded 24-hour time such as "09:00". Leave start_time and end_time unset (or equal) for no time restriction.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › ScheduleWindow › end_time
Time of day the window closes, as a zero-padded 24-hour time such as "17:00"; the window runs up to but not including it. An end before start_time wraps past midnight, e.g. 22:00 to 06:00.
Clear enough to supply this argument.
$defs › EveryNMinutesSchedule › frequency
Selects this form: fire every `interval` minutes, optionally only inside `window`.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › EveryNMinutesSchedule › interval
Minutes between fires, counted from the top of each hour: 15 fires at :00, :15, :30 and :45.
Clear enough to supply this argument.
$defs › EveryNHoursSchedule › frequency
Selects this form: fire on the hour every `interval` hours, optionally only inside `window`.
Clear enough to supply this argument.
$defs › EveryNHoursSchedule › interval
Hours between fires, at minute 0, counted from midnight or from the window's start hour: 6 fires at 00:00, 06:00, 12:00 and 18:00.
Clear enough to supply this argument.
$defs › DailySchedule › time
Time of day the schedule fires, as a zero-padded 24-hour time such as "09:30", read in the schedule's timezone.
Clear enough to supply this argument.
$defs › DailySchedule › frequency
Selects this form: fire once a day at `time`.
Clear enough to supply this argument.
$defs › WeeklySchedule › time
Time of day the schedule fires, as a zero-padded 24-hour time such as "09:30", read in the schedule's timezone.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › WeeklySchedule › frequency
Selects this form: fire once a week on `day_of_week` at `time`.
Clear enough to supply this argument.
$defs › WeeklySchedule › day_of_week
The weekday the schedule fires on, at `time`.
Clear enough to supply this argument.
$defs › MonthlySchedule › time
Time of day the schedule fires, as a zero-padded 24-hour time such as "09:30", read in the schedule's timezone.
Clear enough to supply this argument.
$defs › MonthlySchedule › frequency
Selects this form: fire once a month on `day_of_month` at `time`.
Clear enough to supply this argument.
$defs › MonthlySchedule › day_of_month
The day of the month the schedule fires on, at `time`, e.g. 1 for the first of each month.
Clear enough to supply this argument.
$defs › CronSchedule › frequency
Selects this form: fire on a raw cron `expression`, for timing the other forms can't express.
Clear enough to supply this argument.
$defs › CronSchedule › expression
A five-field cron expression (minute hour day-of-month month day-of-week) read in the schedule's timezone, e.g. "0 9 * * *" fires at 09:00 every day. A numeric day-of-week counts monday as 0 (the scheduler's numbering, not standard cron's sunday=0), so prefer day names such as mon-fri.
Clear enough to supply this argument.
enabled
false creates the schedule paused. Omit to create it enabled.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The schedule's id; pass it as schedule_id to get_schedule, update_schedule or delete_schedule."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"enabled": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "False when the schedule is paused."
},
"timezone": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "IANA timezone the cron expression is read in. Null means UTC."
},
"simulation_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The simulation this schedule runs (see get_simulation)."
},
"cron_expression": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The stored timing as a cron expression, also for schedules given in a frequency form."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_schedule",
"title": "Create schedule",
"description": "Schedule a simulation to run automatically via POST /v1/create-schedule.\n\nStores a recurring trigger that starts a full run of simulation_id every time it fires, until it\nis paused or deleted. Each fire is a real simulation run against the agent (real calls or\nconversations, the same as queuing a run by hand), so a tight interval multiplies runs and usage.\nThe timing is converted to a cron expression and read in UTC. A simulation can have more than one\nschedule. Requires write access to the simulation's workspace.\n\nReturns the new schedule: its id (for get_schedule, update_schedule, delete_schedule),\nsimulation_id, the stored cron_expression, enabled and timezone.\n",
"inputSchema": {
"type": "object",
"$defs": {
"CronSchedule": {
"type": "object",
"title": "CronSchedule",
"required": [
"frequency",
"expression"
],
"properties": {
"frequency": {
"type": "string",
"const": "cron",
"title": "Frequency",
"description": "Selects this form: fire on a raw cron `expression`, for timing the other forms can't express."
},
"expression": {
"type": "string",
"title": "Expression",
"description": "A five-field cron expression (minute hour day-of-month month day-of-week) read in the schedule's timezone, e.g. \"0 9 * * *\" fires at 09:00 every day. A numeric day-of-week counts monday as 0 (the scheduler's numbering, not standard cron's sunday=0), so prefer day names such as mon-fri."
}
}
},
"DailySchedule": {
"type": "object",
"title": "DailySchedule",
"required": [
"time",
"frequency"
],
"properties": {
"time": {
"type": "string",
"title": "Time",
"pattern": "^\\d{2}:\\d{2}$",
"description": "Time of day the schedule fires, as a zero-padded 24-hour time such as \"09:30\", read in the schedule's timezone."
},
"window": {
"anyOf": [
{
"$ref": "#/$defs/ScheduleWindow"
},
{
"type": "null"
}
],
"default": null,
"description": "Only fire on window.days; its time range is ignored, since `time` names the time. Omit to fire every day."
},
"frequency": {
"type": "string",
"const": "daily",
"title": "Frequency",
"description": "Selects this form: fire once a day at `time`."
}
}
},
"ScheduleWindow": {
"type": "object",
"title": "ScheduleWindow",
"properties": {
"days": {
"type": "array",
"items": {
"enum": [
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday"
],
"type": "string"
},
"title": "Days",
"description": "Weekdays the window is open on, e.g. [\"monday\", \"friday\"]. Leave empty for every day."
},
"end_time": {
"anyOf": [
{
"type": "string",
"pattern": "^\\d{2}:\\d{2}$"
},
{
"type": "null"
}
],
"title": "End Time",
"default": null,
"description": "Time of day the window closes, as a zero-padded 24-hour time such as \"17:00\"; the window runs up to but not including it. An end before start_time wraps past midnight, e.g. 22:00 to 06:00."
},
"start_time": {
"anyOf": [
{
"type": "string",
"pattern": "^\\d{2}:\\d{2}$"
},
{
"type": "null"
}
],
"title": "Start Time",
"default": null,
"description": "Time of day the window opens, as a zero-padded 24-hour time such as \"09:00\". Leave start_time and end_time unset (or equal) for no time restriction."
}
},
"description": "Restricts a recurring schedule to certain days and/or a daily time range —\n\"Mondays and Fridays\", \"weekdays 9am-5pm\". Times are read in the schedule's timezone and\napplied in whole hours: start_time's hour is the first that runs (09:30 starts at 09:00), an\nend_time on the hour is excluded (17:00 stops after 16:59) and one with minutes keeps its hour\n(17:30 runs through 17:59). A range that wraps past midnight can't be combined with days."
},
"WeeklySchedule": {
"type": "object",
"title": "WeeklySchedule",
"required": [
"time",
"frequency",
"day_of_week"
],
"properties": {
"time": {
"type": "string",
"title": "Time",
"pattern": "^\\d{2}:\\d{2}$",
"description": "Time of day the schedule fires, as a zero-padded 24-hour time such as \"09:30\", read in the schedule's timezone."
},
"frequency": {
"type": "string",
"const": "weekly",
"title": "Frequency",
"description": "Selects this form: fire once a week on `day_of_week` at `time`."
},
"day_of_week": {
"enum": [
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday"
],
"type": "string",
"title": "Day Of Week",
"description": "The weekday the schedule fires on, at `time`."
}
}
},
"MonthlySchedule": {
"type": "object",
"title": "MonthlySchedule",
"required": [
"time",
"frequency",
"day_of_month"
],
"properties": {
"time": {
"type": "string",
"title": "Time",
"pattern": "^\\d{2}:\\d{2}$",
"description": "Time of day the schedule fires, as a zero-padded 24-hour time such as \"09:30\", read in the schedule's timezone."
},
"frequency": {
"type": "string",
"const": "monthly",
"title": "Frequency",
"description": "Selects this form: fire once a month on `day_of_month` at `time`."
},
"day_of_month": {
"type": "integer",
"title": "Day Of Month",
"maximum": 31,
"minimum": 1,
"description": "The day of the month the schedule fires on, at `time`, e.g. 1 for the first of each month."
}
}
},
"EveryNHoursSchedule": {
"type": "object",
"title": "EveryNHoursSchedule",
"required": [
"frequency",
"interval"
],
"properties": {
"window": {
"anyOf": [
{
"$ref": "#/$defs/ScheduleWindow"
},
{
"type": "null"
}
],
"default": null,
"description": "Only fire on these days and/or within this daily time range. Omit to fire all day, every day."
},
"interval": {
"type": "integer",
"title": "Interval",
"maximum": 23,
"description": "Hours between fires, at minute 0, counted from midnight or from the window's start hour: 6 fires at 00:00, 06:00, 12:00 and 18:00.",
"exclusiveMinimum": 0
},
"frequency": {
"type": "string",
"const": "every_n_hours",
"title": "Frequency",
"description": "Selects this form: fire on the hour every `interval` hours, optionally only inside `window`."
}
}
},
"EveryNMinutesSchedule": {
"type": "object",
"title": "EveryNMinutesSchedule",
"required": [
"frequency",
"interval"
],
"properties": {
"window": {
"anyOf": [
{
"$ref": "#/$defs/ScheduleWindow"
},
{
"type": "null"
}
],
"default": null,
"description": "Only fire on these days and/or within this daily time range. Omit to fire all day, every day."
},
"interval": {
"type": "integer",
"title": "Interval",
"maximum": 59,
"description": "Minutes between fires, counted from the top of each hour: 15 fires at :00, :15, :30 and :45.",
"exclusiveMinimum": 0
},
"frequency": {
"type": "string",
"const": "every_n_minutes",
"title": "Frequency",
"description": "Selects this form: fire every `interval` minutes, optionally only inside `window`."
}
}
}
},
"title": "create_scheduleArguments",
"required": [
"simulation_id",
"schedule"
],
"properties": {
"enabled": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Enabled",
"default": null,
"description": "false creates the schedule paused. Omit to create it enabled."
},
"schedule": {
"anyOf": [
{
"$ref": "#/$defs/EveryNMinutesSchedule"
},
{
"$ref": "#/$defs/EveryNHoursSchedule"
},
{
"$ref": "#/$defs/DailySchedule"
},
{
"$ref": "#/$defs/WeeklySchedule"
},
{
"$ref": "#/$defs/MonthlySchedule"
},
{
"$ref": "#/$defs/CronSchedule"
}
],
"title": "Schedule",
"description": "When the simulation runs. Pick one form by frequency: every_n_minutes or every_n_hours (interval, plus an optional days/hours window), daily (time, plus optional window days), weekly (day_of_week and time), monthly (day_of_month and time), or cron (a raw expression). Times are read in the schedule's timezone."
},
"simulation_id": {
"type": "string",
"title": "Simulation Id",
"description": "The simulation to run on this schedule: its id, from list_simulations."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The schedule's id; pass it as schedule_id to get_schedule, update_schedule or delete_schedule."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"enabled": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "False when the schedule is paused."
},
"timezone": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "IANA timezone the cron expression is read in. Null means UTC."
},
"simulation_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The simulation this schedule runs (see get_simulation)."
},
"cron_expression": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The stored timing as a cron expression, also for schedules given in a frequency form."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
Shorten the title to an action and subject; move usage details into the description.
Description98/100
Get one simulation schedule via GET /v1/schedule/{schedule_id}.
Returns its id, the simulation_id it runs, cron_expression (the stored timing, also for
schedules created from a frequency form), enabled, timezone (null means UTC) and created_at,
with the same object repeated under `data`. It does not list past or upcoming runs.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
schedule_id
The schedule's id, from list_schedules or create_schedule.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The schedule's id; pass it as schedule_id to get_schedule, update_schedule or delete_schedule."
},
"data": {
"type": [
"object",
"array",
"null"
],
"description": "The same schedule object as returned by the API."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"enabled": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "False when the schedule is paused."
},
"timezone": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "IANA timezone the cron expression is read in. Null means UTC."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the schedule was created."
},
"simulation_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The simulation this schedule runs (see get_simulation)."
},
"cron_expression": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The stored timing as a cron expression, also for schedules given in a frequency form."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "get_schedule",
"title": "Get schedule",
"description": "Get one simulation schedule via GET /v1/schedule/{schedule_id}.\n\nReturns its id, the simulation_id it runs, cron_expression (the stored timing, also for\nschedules created from a frequency form), enabled, timezone (null means UTC) and created_at,\nwith the same object repeated under `data`. It does not list past or upcoming runs.\n",
"inputSchema": {
"type": "object",
"title": "get_scheduleArguments",
"required": [
"schedule_id"
],
"properties": {
"schedule_id": {
"type": "string",
"title": "Schedule Id",
"format": "uuid",
"description": "The schedule's id, from list_schedules or create_schedule."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The schedule's id; pass it as schedule_id to get_schedule, update_schedule or delete_schedule."
},
"data": {
"type": [
"object",
"array",
"null"
],
"description": "The same schedule object as returned by the API."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"enabled": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "False when the schedule is paused."
},
"timezone": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "IANA timezone the cron expression is read in. Null means UTC."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the schedule was created."
},
"simulation_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The simulation this schedule runs (see get_simulation)."
},
"cron_expression": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The stored timing as a cron expression, also for schedules given in a frequency form."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List every simulation schedule in the organization whose agent you can see, via GET /v1/schedules.
Returns `schedules`: for each, its id, the simulation_id it runs, cron_expression (the stored
timing), enabled, timezone (null means UTC) and created_at. There is no server-side filter: to
find one simulation's schedules, match simulation_id yourself.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"schedules": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The schedule's id; pass it as schedule_id to GET /v1/schedule/{schedule_id}, PUT /v1/update-schedule/{schedule_id} or DELETE /v1/delete-schedule/{schedule_id}."
},
"enabled": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "False when the schedule is paused."
},
"timezone": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "IANA timezone the cron expression is read in. Null means UTC."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the schedule was created."
},
"simulation_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The simulation this schedule runs (see GET /v1/simulation/{simulation_id})."
},
"cron_expression": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The stored timing as a cron expression, also for schedules given in a frequency form."
}
},
"description": "A simulation schedule: the simulation it runs and its stored cron timing.",
"additionalProperties": true
},
"properties": {},
"description": "Every schedule you can see, each with id, simulation_id, cron_expression, enabled, timezone and created_at.",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "list_schedules",
"title": "List schedules",
"description": "List every simulation schedule in the organization whose agent you can see, via GET /v1/schedules.\n\nReturns `schedules`: for each, its id, the simulation_id it runs, cron_expression (the stored\ntiming), enabled, timezone (null means UTC) and created_at. There is no server-side filter: to\nfind one simulation's schedules, match simulation_id yourself.\n",
"inputSchema": {
"type": "object",
"title": "list_schedulesArguments",
"properties": {}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"schedules": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The schedule's id; pass it as schedule_id to GET /v1/schedule/{schedule_id}, PUT /v1/update-schedule/{schedule_id} or DELETE /v1/delete-schedule/{schedule_id}."
},
"enabled": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "False when the schedule is paused."
},
"timezone": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "IANA timezone the cron expression is read in. Null means UTC."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the schedule was created."
},
"simulation_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The simulation this schedule runs (see GET /v1/simulation/{simulation_id})."
},
"cron_expression": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The stored timing as a cron expression, also for schedules given in a frequency form."
}
},
"description": "A simulation schedule: the simulation it runs and its stored cron timing.",
"additionalProperties": true
},
"properties": {},
"description": "Every schedule you can see, each with id, simulation_id, cron_expression, enabled, timezone and created_at.",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Change a simulation schedule in place via PUT /v1/update-schedule/{schedule_id}.
Pass `schedule` to replace its timing (the previous cron expression is overwritten, not kept)
and/or `enabled` to pause (false) or resume (true) it; at least one is required. The timezone is
left as it is. A resumed or retimed schedule goes back to starting real simulation runs of its
simulation each time it fires. Requires write access to the schedule's workspace.
Returns the stored schedule after the update: id, simulation_id, cron_expression, enabled,
timezone and created_at.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
schedule_id
The schedule's id, from list_schedules or create_schedule.
Clear enough to supply this argument.
$defs › ScheduleWindow › days
Weekdays the window is open on, e.g. ["monday", "friday"]. Leave empty for every day.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › ScheduleWindow › start_time
Time of day the window opens, as a zero-padded 24-hour time such as "09:00". Leave start_time and end_time unset (or equal) for no time restriction.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › ScheduleWindow › end_time
Time of day the window closes, as a zero-padded 24-hour time such as "17:00"; the window runs up to but not including it. An end before start_time wraps past midnight, e.g. 22:00 to 06:00.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › EveryNMinutesSchedule › frequency
Selects this form: fire every `interval` minutes, optionally only inside `window`.
Clear enough to supply this argument.
$defs › EveryNMinutesSchedule › interval
Minutes between fires, counted from the top of each hour: 15 fires at :00, :15, :30 and :45.
Clear enough to supply this argument.
$defs › EveryNHoursSchedule › frequency
Selects this form: fire on the hour every `interval` hours, optionally only inside `window`.
Clear enough to supply this argument.
$defs › EveryNHoursSchedule › interval
Hours between fires, at minute 0, counted from midnight or from the window's start hour: 6 fires at 00:00, 06:00, 12:00 and 18:00.
Clear enough to supply this argument.
$defs › DailySchedule › time
Time of day the schedule fires, as a zero-padded 24-hour time such as "09:30", read in the schedule's timezone.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
$defs › DailySchedule › frequency
Selects this form: fire once a day at `time`.
Clear enough to supply this argument.
$defs › WeeklySchedule › time
Time of day the schedule fires, as a zero-padded 24-hour time such as "09:30", read in the schedule's timezone.
Clear enough to supply this argument.
$defs › WeeklySchedule › frequency
Selects this form: fire once a week on `day_of_week` at `time`.
Clear enough to supply this argument.
$defs › WeeklySchedule › day_of_week
The weekday the schedule fires on, at `time`.
Clear enough to supply this argument.
$defs › MonthlySchedule › time
Time of day the schedule fires, as a zero-padded 24-hour time such as "09:30", read in the schedule's timezone.
Clear enough to supply this argument.
$defs › MonthlySchedule › frequency
Selects this form: fire once a month on `day_of_month` at `time`.
Clear enough to supply this argument.
$defs › MonthlySchedule › day_of_month
The day of the month the schedule fires on, at `time`, e.g. 1 for the first of each month.
Clear enough to supply this argument.
$defs › CronSchedule › frequency
Selects this form: fire on a raw cron `expression`, for timing the other forms can't express.
Clear enough to supply this argument.
$defs › CronSchedule › expression
A five-field cron expression (minute hour day-of-month month day-of-week) read in the schedule's timezone, e.g. "0 9 * * *" fires at 09:00 every day. A numeric day-of-week counts monday as 0 (the scheduler's numbering, not standard cron's sunday=0), so prefer day names such as mon-fri.
Clear enough to supply this argument.
enabled
false pauses the schedule, true resumes it. Omit to leave it as is.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The schedule's id; pass it as schedule_id to get_schedule, update_schedule or delete_schedule."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"enabled": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "False when the schedule is paused."
},
"timezone": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "IANA timezone the cron expression is read in. Null means UTC."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the schedule was created."
},
"simulation_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The simulation this schedule runs (see get_simulation)."
},
"cron_expression": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The stored timing as a cron expression, also for schedules given in a frequency form."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "update_schedule",
"title": "Update schedule",
"description": "Change a simulation schedule in place via PUT /v1/update-schedule/{schedule_id}.\n\nPass `schedule` to replace its timing (the previous cron expression is overwritten, not kept)\nand/or `enabled` to pause (false) or resume (true) it; at least one is required. The timezone is\nleft as it is. A resumed or retimed schedule goes back to starting real simulation runs of its\nsimulation each time it fires. Requires write access to the schedule's workspace.\n\nReturns the stored schedule after the update: id, simulation_id, cron_expression, enabled,\ntimezone and created_at.\n",
"inputSchema": {
"type": "object",
"$defs": {
"CronSchedule": {
"type": "object",
"title": "CronSchedule",
"required": [
"frequency",
"expression"
],
"properties": {
"frequency": {
"type": "string",
"const": "cron",
"title": "Frequency",
"description": "Selects this form: fire on a raw cron `expression`, for timing the other forms can't express."
},
"expression": {
"type": "string",
"title": "Expression",
"description": "A five-field cron expression (minute hour day-of-month month day-of-week) read in the schedule's timezone, e.g. \"0 9 * * *\" fires at 09:00 every day. A numeric day-of-week counts monday as 0 (the scheduler's numbering, not standard cron's sunday=0), so prefer day names such as mon-fri."
}
}
},
"DailySchedule": {
"type": "object",
"title": "DailySchedule",
"required": [
"time",
"frequency"
],
"properties": {
"time": {
"type": "string",
"title": "Time",
"pattern": "^\\d{2}:\\d{2}$",
"description": "Time of day the schedule fires, as a zero-padded 24-hour time such as \"09:30\", read in the schedule's timezone."
},
"window": {
"anyOf": [
{
"$ref": "#/$defs/ScheduleWindow"
},
{
"type": "null"
}
],
"default": null,
"description": "Only fire on window.days; its time range is ignored, since `time` names the time. Omit to fire every day."
},
"frequency": {
"type": "string",
"const": "daily",
"title": "Frequency",
"description": "Selects this form: fire once a day at `time`."
}
}
},
"ScheduleWindow": {
"type": "object",
"title": "ScheduleWindow",
"properties": {
"days": {
"type": "array",
"items": {
"enum": [
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday"
],
"type": "string"
},
"title": "Days",
"description": "Weekdays the window is open on, e.g. [\"monday\", \"friday\"]. Leave empty for every day."
},
"end_time": {
"anyOf": [
{
"type": "string",
"pattern": "^\\d{2}:\\d{2}$"
},
{
"type": "null"
}
],
"title": "End Time",
"default": null,
"description": "Time of day the window closes, as a zero-padded 24-hour time such as \"17:00\"; the window runs up to but not including it. An end before start_time wraps past midnight, e.g. 22:00 to 06:00."
},
"start_time": {
"anyOf": [
{
"type": "string",
"pattern": "^\\d{2}:\\d{2}$"
},
{
"type": "null"
}
],
"title": "Start Time",
"default": null,
"description": "Time of day the window opens, as a zero-padded 24-hour time such as \"09:00\". Leave start_time and end_time unset (or equal) for no time restriction."
}
},
"description": "Restricts a recurring schedule to certain days and/or a daily time range —\n\"Mondays and Fridays\", \"weekdays 9am-5pm\". Times are read in the schedule's timezone and\napplied in whole hours: start_time's hour is the first that runs (09:30 starts at 09:00), an\nend_time on the hour is excluded (17:00 stops after 16:59) and one with minutes keeps its hour\n(17:30 runs through 17:59). A range that wraps past midnight can't be combined with days."
},
"WeeklySchedule": {
"type": "object",
"title": "WeeklySchedule",
"required": [
"time",
"frequency",
"day_of_week"
],
"properties": {
"time": {
"type": "string",
"title": "Time",
"pattern": "^\\d{2}:\\d{2}$",
"description": "Time of day the schedule fires, as a zero-padded 24-hour time such as \"09:30\", read in the schedule's timezone."
},
"frequency": {
"type": "string",
"const": "weekly",
"title": "Frequency",
"description": "Selects this form: fire once a week on `day_of_week` at `time`."
},
"day_of_week": {
"enum": [
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday"
],
"type": "string",
"title": "Day Of Week",
"description": "The weekday the schedule fires on, at `time`."
}
}
},
"MonthlySchedule": {
"type": "object",
"title": "MonthlySchedule",
"required": [
"time",
"frequency",
"day_of_month"
],
"properties": {
"time": {
"type": "string",
"title": "Time",
"pattern": "^\\d{2}:\\d{2}$",
"description": "Time of day the schedule fires, as a zero-padded 24-hour time such as \"09:30\", read in the schedule's timezone."
},
"frequency": {
"type": "string",
"const": "monthly",
"title": "Frequency",
"description": "Selects this form: fire once a month on `day_of_month` at `time`."
},
"day_of_month": {
"type": "integer",
"title": "Day Of Month",
"maximum": 31,
"minimum": 1,
"description": "The day of the month the schedule fires on, at `time`, e.g. 1 for the first of each month."
}
}
},
"EveryNHoursSchedule": {
"type": "object",
"title": "EveryNHoursSchedule",
"required": [
"frequency",
"interval"
],
"properties": {
"window": {
"anyOf": [
{
"$ref": "#/$defs/ScheduleWindow"
},
{
"type": "null"
}
],
"default": null,
"description": "Only fire on these days and/or within this daily time range. Omit to fire all day, every day."
},
"interval": {
"type": "integer",
"title": "Interval",
"maximum": 23,
"description": "Hours between fires, at minute 0, counted from midnight or from the window's start hour: 6 fires at 00:00, 06:00, 12:00 and 18:00.",
"exclusiveMinimum": 0
},
"frequency": {
"type": "string",
"const": "every_n_hours",
"title": "Frequency",
"description": "Selects this form: fire on the hour every `interval` hours, optionally only inside `window`."
}
}
},
"EveryNMinutesSchedule": {
"type": "object",
"title": "EveryNMinutesSchedule",
"required": [
"frequency",
"interval"
],
"properties": {
"window": {
"anyOf": [
{
"$ref": "#/$defs/ScheduleWindow"
},
{
"type": "null"
}
],
"default": null,
"description": "Only fire on these days and/or within this daily time range. Omit to fire all day, every day."
},
"interval": {
"type": "integer",
"title": "Interval",
"maximum": 59,
"description": "Minutes between fires, counted from the top of each hour: 15 fires at :00, :15, :30 and :45.",
"exclusiveMinimum": 0
},
"frequency": {
"type": "string",
"const": "every_n_minutes",
"title": "Frequency",
"description": "Selects this form: fire every `interval` minutes, optionally only inside `window`."
}
}
}
},
"title": "update_scheduleArguments",
"required": [
"schedule_id"
],
"properties": {
"enabled": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Enabled",
"default": null,
"description": "false pauses the schedule, true resumes it. Omit to leave it as is."
},
"schedule": {
"anyOf": [
{
"$ref": "#/$defs/EveryNMinutesSchedule"
},
{
"$ref": "#/$defs/EveryNHoursSchedule"
},
{
"$ref": "#/$defs/DailySchedule"
},
{
"$ref": "#/$defs/WeeklySchedule"
},
{
"$ref": "#/$defs/MonthlySchedule"
},
{
"$ref": "#/$defs/CronSchedule"
},
{
"type": "null"
}
],
"title": "Schedule",
"default": null,
"description": "Replacement timing; overwrites the stored cron expression. When the simulation runs. Pick one form by frequency: every_n_minutes or every_n_hours (interval, plus an optional days/hours window), daily (time, plus optional window days), weekly (day_of_week and time), monthly (day_of_month and time), or cron (a raw expression). Times are read in the schedule's timezone. Omit to keep the current timing."
},
"schedule_id": {
"type": "string",
"title": "Schedule Id",
"format": "uuid",
"description": "The schedule's id, from list_schedules or create_schedule."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The schedule's id; pass it as schedule_id to get_schedule, update_schedule or delete_schedule."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"enabled": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "False when the schedule is paused."
},
"timezone": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "IANA timezone the cron expression is read in. Null means UTC."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the schedule was created."
},
"simulation_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The simulation this schedule runs (see get_simulation)."
},
"cron_expression": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The stored timing as a cron expression, also for schedules given in a frequency form."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Permanently delete a simulation schedule via DELETE /v1/delete-schedule/{schedule_id}.
Its simulation stops running automatically on that timing; the simulation itself, its other
schedules and its past runs are untouched. This cannot be undone; to stop it temporarily, call
update_schedule with enabled false instead. Requires write access to the schedule's workspace.
Returns status and message from the API, plus deleted and the schedule_id removed.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
Input documentation gives an agent enough context to populate the arguments.
schedule_id
The schedule's id, from list_schedules or create_schedule.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Start an autonomous self-improve loop for a single VAPI, ElevenLabs, Retell, or Google CES agent.
The loop iterates ``agent_id``'s prompt in place - pushing each candidate to the agent's
provider and re-running ``simulation_id`` to measure it - and, when finished, writes
the single winning prompt as ONE new 'latest' version on the agent. The prior version is
left intact so the user can revert; the 'production' label is never moved. For Google CES
the prompt covers every agent in the app, and each candidate is published as a CES version
that the agent's deployment is repointed to; the draft must match the deployment to start.
Side effects once confirmed: candidates go live on the provider agent while the run is
going, so real traffic to it can reach them; every round places simulated calls and spends
credits; new metrics may be created and the simulation's metric selection is replaced.
**Confirm-gated.** Call first with ``confirmed=False`` (default) - the response will be
``{needs_confirmation: true, preview: "..."}``. Relay the preview verbatim and ask the
user to approve. ONLY after they approve, call again with ``confirmed=True`` and the same
arguments. That call returns ``run_id`` and ``status``; follow progress with
get_self_improve_run and halt with stop_self_improve_run.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
The agent whose prompt to improve in place: its Bluejay id from list_agents. It must be a VAPI, ElevenLabs, Retell or Google CES agent connected to its provider, with no other self-improve run active.
Clear enough to supply this argument.
simulation_id
The simulation re-run every round to score each candidate prompt (its digital humans are the test set): its id from list_simulations. Its selected metrics are replaced with the run's success metrics.
Clear enough to supply this argument.
target_pass_rate
Pass rate, as a fraction (0.9 means 90%), at which the loop stops early as good enough.
Clear enough to supply this argument.
max_iterations
Most improvement rounds to run. Each round pushes a candidate prompt and runs the whole simulation again, so each round costs a full simulation run.
Clear enough to supply this argument.
min_improvement
Smallest pass-rate gain, as a fraction (0.02 means 2 points), for a candidate to replace the best prompt so far; non-negative so worse prompts are never kept. Two rounds in a row without this gain end the loop.
Clear enough to supply this argument.
metric_count
How many pass/fail success metrics to generate from the agent's prompt when success_metric_ids is not given. Ignored when it is.
Clear enough to supply this argument.
success_metric_ids
Existing custom metric ids (UUIDs from list_custom_metrics) to score pass rate with, instead of generating new metrics. Omit to have the run generate metric_count of them.
Clear enough to supply this argument.
confirmed
Leave false for the first call, which only returns a preview. Set true, with the same arguments, only after the user approves that preview; that call starts the run.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the preview call, the action to repeat with confirmed=true."
},
"run_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the confirmed call, the new run's id; poll it with get_self_improve_run."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the confirmed call, the run's starting status, normally PENDING."
},
"preview": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the preview call, what the run will do. Relay it to the user verbatim."
},
"to_proceed": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the preview call, how to start the run once the user approves."
},
"needs_confirmation": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "True on the preview call (confirmed=false): nothing has started yet."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "start_self_improve_run",
"title": "Start self improve run",
"description": "Start an autonomous self-improve loop for a single VAPI, ElevenLabs, Retell, or Google CES agent.\n\nThe loop iterates ``agent_id``'s prompt in place - pushing each candidate to the agent's\nprovider and re-running ``simulation_id`` to measure it - and, when finished, writes\nthe single winning prompt as ONE new 'latest' version on the agent. The prior version is\nleft intact so the user can revert; the 'production' label is never moved. For Google CES\nthe prompt covers every agent in the app, and each candidate is published as a CES version\nthat the agent's deployment is repointed to; the draft must match the deployment to start.\n\nSide effects once confirmed: candidates go live on the provider agent while the run is\ngoing, so real traffic to it can reach them; every round places simulated calls and spends\ncredits; new metrics may be created and the simulation's metric selection is replaced.\n\n**Confirm-gated.** Call first with ``confirmed=False`` (default) - the response will be\n``{needs_confirmation: true, preview: \"...\"}``. Relay the preview verbatim and ask the\nuser to approve. ONLY after they approve, call again with ``confirmed=True`` and the same\narguments. That call returns ``run_id`` and ``status``; follow progress with\nget_self_improve_run and halt with stop_self_improve_run.\n",
"inputSchema": {
"type": "object",
"title": "start_self_improve_runArguments",
"required": [
"agent_id",
"simulation_id"
],
"properties": {
"agent_id": {
"type": "integer",
"title": "Agent Id",
"description": "The agent whose prompt to improve in place: its Bluejay id from list_agents. It must be a VAPI, ElevenLabs, Retell or Google CES agent connected to its provider, with no other self-improve run active."
},
"confirmed": {
"type": "boolean",
"title": "Confirmed",
"default": false,
"description": "Leave false for the first call, which only returns a preview. Set true, with the same arguments, only after the user approves that preview; that call starts the run."
},
"metric_count": {
"type": "integer",
"title": "Metric Count",
"default": 5,
"description": "How many pass/fail success metrics to generate from the agent's prompt when success_metric_ids is not given. Ignored when it is."
},
"simulation_id": {
"type": "integer",
"title": "Simulation Id",
"description": "The simulation re-run every round to score each candidate prompt (its digital humans are the test set): its id from list_simulations. Its selected metrics are replaced with the run's success metrics."
},
"max_iterations": {
"type": "integer",
"title": "Max Iterations",
"default": 5,
"description": "Most improvement rounds to run. Each round pushes a candidate prompt and runs the whole simulation again, so each round costs a full simulation run."
},
"min_improvement": {
"type": "number",
"title": "Min Improvement",
"default": 0.02,
"description": "Smallest pass-rate gain, as a fraction (0.02 means 2 points), for a candidate to replace the best prompt so far; non-negative so worse prompts are never kept. Two rounds in a row without this gain end the loop."
},
"target_pass_rate": {
"type": "number",
"title": "Target Pass Rate",
"default": 0.9,
"description": "Pass rate, as a fraction (0.9 means 90%), at which the loop stops early as good enough."
},
"success_metric_ids": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Success Metric Ids",
"default": null,
"description": "Existing custom metric ids (UUIDs from list_custom_metrics) to score pass rate with, instead of generating new metrics. Omit to have the run generate metric_count of them."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the preview call, the action to repeat with confirmed=true."
},
"run_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the confirmed call, the new run's id; poll it with get_self_improve_run."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the confirmed call, the run's starting status, normally PENDING."
},
"preview": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the preview call, what the run will do. Relay it to the user verbatim."
},
"to_proceed": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the preview call, how to start the run once the user approves."
},
"needs_confirmation": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "True on the preview call (confirmed=false): nothing has started yet."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Get one self-improve run's progress and outcome. Read-only.
Returns ``run`` with its status, baseline/current/final pass rates, the round it is on,
per-iteration history (each candidate's pass rate and whether it was kept), the baseline
and current prompt text, and ``proposed_agent_version_id`` once a winning prompt has been
saved as the agent's new 'latest' version. Poll this after start_self_improve_run.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
run_id
The self-improve run's id: run_id from start_self_improve_run, or id from list_self_improve_runs.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
List self-improve runs for the org, optionally filtered by agent_id or status. Read-only.
Returns ``runs``, newest first (up to 100), each with its id, agent_id, simulation_id,
status, pass rates and iteration history. Use it to find an active run to stop or a past
run's id for get_self_improve_run.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
agent_id
Only runs that improve this agent: its Bluejay id from list_agents. Omit for every agent you can see.
Clear enough to supply this argument.
status
Only runs in this state: PENDING, RUNNING, SUCCEEDED, STOPPED or FAILED. Omit for all states.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Request a cooperative stop of an active self-improve run.
The loop notices the flag while it waits on a round, so it is not instantaneous. It then
puts the best prompt kept so far back on the provider agent and ends with status STOPPED;
if that prompt beat the baseline it is still saved as a new 'latest' version. The stop
cannot be undone (start a new run instead). A run that is not PENDING or RUNNING is left as is.
Returns ``status`` (STOP_REQUESTED, or the run's status if it was already done) and
``note``. Confirm the final state with get_self_improve_run.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
run_id
The self-improve run's id: run_id from start_self_improve_run, or id from list_self_improve_runs.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"note": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Set to 'run is not active' when there was nothing to stop."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "STOP_REQUESTED when the stop was recorded, or the run's current status when it was already finished."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "stop_self_improve_run",
"title": "Stop self improve run",
"description": "Request a cooperative stop of an active self-improve run.\n\nThe loop notices the flag while it waits on a round, so it is not instantaneous. It then\nputs the best prompt kept so far back on the provider agent and ends with status STOPPED;\nif that prompt beat the baseline it is still saved as a new 'latest' version. The stop\ncannot be undone (start a new run instead). A run that is not PENDING or RUNNING is left as is.\nReturns ``status`` (STOP_REQUESTED, or the run's status if it was already done) and\n``note``. Confirm the final state with get_self_improve_run.\n",
"inputSchema": {
"type": "object",
"title": "stop_self_improve_runArguments",
"required": [
"run_id"
],
"properties": {
"run_id": {
"type": "integer",
"title": "Run Id",
"description": "The self-improve run's id: run_id from start_self_improve_run, or id from list_self_improve_runs."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"note": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Set to 'run is not active' when there was nothing to stop."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "STOP_REQUESTED when the stop was recorded, or the run's current status when it was already finished."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Start a generational-tree red-team simulation against a single target agent.
The simulation runs benign recon call(s) that seed an agent-level knowledge base (the
citadel), then attacker calls that branch per the oracle's triage — up to max_levels deep,
bounded by max_branches_per_node and a max_total_dhs budget. Every call is one voice call
hard-capped at max_call_duration_minutes. ``config`` overrides those caps (clamped to the
mandatory ceilings). ``attack_quotas`` (optional) is ``{social_engineering, prompt_injection,
audio_native, content_harm}`` → attempt counts; 0 (default) keeps the adaptive mix, N runs that
family N times (clamped to 20 per family); each attack level is sized from those counts
(largest family, at least one slot per active family). Custom per-family counts require a
Growth, Scale, Enterprise, or custom Growth+ contract. Content-safety probes (harm_categories)
run by default alongside the OWASP attacks; pass ``harm_categories: []`` for an OWASP-only test.
Once confirmed it places real voice calls to the agent, spends credits, and needs a card
on file unless the org has a red-teaming override.
**Confirm-gated.** Call first with ``confirmed=False`` (default) — the response will be
``{needs_confirmation: true, preview: "..."}``. Relay the preview verbatim and ask the user
to approve. ONLY after they approve, call again with ``confirmed=True`` and the same arguments.
That call returns ``simulation_id``; follow it with get_red_team_simulation.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
agent_id
The agent to attack: its Bluejay id from list_agents. It must be in a workspace you can write to; SMS agents are not supported.
Clear enough to supply this argument.
config
Optional overrides as a JSON object: max_levels, max_branches_per_node, max_total_dhs (total calls), max_call_duration_minutes, recon_count, objective, extension, harm_categories, harm_first and attack_quotas. Values over the mandatory ceilings are lowered to them. Omit for the defaults: 5 levels, 3 attacks per level, 16 calls of up to 10 minutes, 3 recon probes. attack_quotas is {social_engineering, prompt_injection, audio_native, content_harm} → attempt counts (0 = adaptive); quota mode raises the call budget and sizes each attack level from those counts (largest family, at least one slot per active family). Content-safety probes run by default; pass harm_categories=[] for an OWASP-only test.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
confirmed
Leave false for the first call, which only returns a preview. Set true, with the same arguments, only after the user approves that preview; that call places real calls.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the preview call, the action to repeat with confirmed=true."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the confirmed call, RUNNING."
},
"preview": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the preview call, the test's scope and call budget. Relay it to the user verbatim."
},
"test_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the confirmed call, the test's own id."
},
"to_proceed": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the preview call, how to start the test once the user approves."
},
"simulation_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the confirmed call, the test's simulation id (the id in the app's /red-teaming/{id} URL)."
},
"simulation_run_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the confirmed call, the first (recon) run's id."
},
"needs_confirmation": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "True on the preview call (confirmed=false): no call has been placed yet."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "start_red_team_simulation",
"title": "Start red team simulation",
"description": "Start a generational-tree red-team simulation against a single target agent.\n\nThe simulation runs benign recon call(s) that seed an agent-level knowledge base (the\ncitadel), then attacker calls that branch per the oracle's triage — up to max_levels deep,\nbounded by max_branches_per_node and a max_total_dhs budget. Every call is one voice call\nhard-capped at max_call_duration_minutes. ``config`` overrides those caps (clamped to the\nmandatory ceilings). ``attack_quotas`` (optional) is ``{social_engineering, prompt_injection,\naudio_native, content_harm}`` → attempt counts; 0 (default) keeps the adaptive mix, N runs that\nfamily N times (clamped to 20 per family); each attack level is sized from those counts\n(largest family, at least one slot per active family). Custom per-family counts require a\nGrowth, Scale, Enterprise, or custom Growth+ contract. Content-safety probes (harm_categories)\nrun by default alongside the OWASP attacks; pass ``harm_categories: []`` for an OWASP-only test.\n\nOnce confirmed it places real voice calls to the agent, spends credits, and needs a card\non file unless the org has a red-teaming override.\n\n**Confirm-gated.** Call first with ``confirmed=False`` (default) — the response will be\n``{needs_confirmation: true, preview: \"...\"}``. Relay the preview verbatim and ask the user\nto approve. ONLY after they approve, call again with ``confirmed=True`` and the same arguments.\nThat call returns ``simulation_id``; follow it with get_red_team_simulation.\n",
"inputSchema": {
"type": "object",
"title": "start_red_team_simulationArguments",
"required": [
"agent_id"
],
"properties": {
"config": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Config",
"default": null,
"description": "Optional overrides as a JSON object: max_levels, max_branches_per_node, max_total_dhs (total calls), max_call_duration_minutes, recon_count, objective, extension, harm_categories, harm_first and attack_quotas. Values over the mandatory ceilings are lowered to them. Omit for the defaults: 5 levels, 3 attacks per level, 16 calls of up to 10 minutes, 3 recon probes. attack_quotas is {social_engineering, prompt_injection, audio_native, content_harm} → attempt counts (0 = adaptive); quota mode raises the call budget and sizes each attack level from those counts (largest family, at least one slot per active family). Content-safety probes run by default; pass harm_categories=[] for an OWASP-only test."
},
"agent_id": {
"type": "integer",
"title": "Agent Id",
"description": "The agent to attack: its Bluejay id from list_agents. It must be in a workspace you can write to; SMS agents are not supported."
},
"confirmed": {
"type": "boolean",
"title": "Confirmed",
"default": false,
"description": "Leave false for the first call, which only returns a preview. Set true, with the same arguments, only after the user approves that preview; that call places real calls."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the preview call, the action to repeat with confirmed=true."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the confirmed call, RUNNING."
},
"preview": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the preview call, the test's scope and call budget. Relay it to the user verbatim."
},
"test_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the confirmed call, the test's own id."
},
"to_proceed": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the preview call, how to start the test once the user approves."
},
"simulation_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the confirmed call, the test's simulation id (the id in the app's /red-teaming/{id} URL)."
},
"simulation_run_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "On the confirmed call, the first (recon) run's id."
},
"needs_confirmation": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "True on the preview call (confirmed=false): no call has been placed yet."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Read-only. Get a red-team simulation's status, overall verdict, OWASP + MITRE ATLAS scorecard,
confirmed vulnerabilities, and Bluejay analysis. ``simulation_id`` is the id in the app's
/red-teaming/{id} URL and the ``simulation_id`` field of list_red_team_simulations.
For per-attack rows (scenario, intended action, Pass/Fail, transcript link) use
get_red_team_attacks with this simulation_id where it is available (Bluejay AI). Otherwise each
attack is one conversation in the simulation's runs (level 1 = recon): call
get_simulation_runs with this simulation_id, then get_simulation_results /
get_simulation_transcript.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
simulation_id
The red-team test's simulation id: simulation_id from start_red_team_simulation or list_red_team_simulations, or the id in the app's /red-teaming/{id} URL.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
List red-team simulations for the org, optionally filtered by agent_id or status. Read-only.
Returns ``tests``, newest first (up to 100), each with its simulation_id, agent_id, status,
overall verdict, scorecards and created_at. Pass a simulation_id to
get_red_team_simulation for the full report or to stop_red_team_simulation.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
agent_id
Only tests against this agent: its Bluejay id from list_agents. Omit for every agent you can see.
Clear enough to supply this argument.
status
Only tests in this state: PENDING, RUNNING, COMPLETED, STOPPED or FAILED. Omit for all states.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Stop a red-team simulation now: hang up its live calls and mark it STOPPED.
Every call of this test still in progress is ended (gracefully, with a 30-second
fallback), and a test not yet COMPLETED, STOPPED or FAILED is set to STOPPED, so no
further attack levels run. Calls already made and findings so far are kept. It cannot be
resumed; start a new test instead. Returns ``status`` and ``ended_conversations``.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
simulation_id
The red-team test's simulation id: simulation_id from start_red_team_simulation or list_red_team_simulations, or the id in the app's /red-teaming/{id} URL.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The test's status after the call: STOPPED, or its terminal status if it had already finished."
},
"ended_conversations": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Ids of the live calls this stop hung up."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "stop_red_team_simulation",
"title": "Stop red team simulation",
"description": "Stop a red-team simulation now: hang up its live calls and mark it STOPPED.\n\nEvery call of this test still in progress is ended (gracefully, with a 30-second\nfallback), and a test not yet COMPLETED, STOPPED or FAILED is set to STOPPED, so no\nfurther attack levels run. Calls already made and findings so far are kept. It cannot be\nresumed; start a new test instead. Returns ``status`` and ``ended_conversations``.\n",
"inputSchema": {
"type": "object",
"title": "stop_red_team_simulationArguments",
"required": [
"simulation_id"
],
"properties": {
"simulation_id": {
"type": "integer",
"title": "Simulation Id",
"description": "The red-team test's simulation id: simulation_id from start_red_team_simulation or list_red_team_simulations, or the id in the app's /red-teaming/{id} URL."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The test's status after the call: STOPPED, or its terminal status if it had already finished."
},
"ended_conversations": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Ids of the live calls this stop hung up."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Submit one finished production conversation (a call, chat or email thread) for Bluejay
to store and score (POST /v1/evaluate).
Creates a conversation under the agent in your observability data and queues the agent's
metrics, plus any custom_metrics, to run on it asynchronously. Each submission counts
toward billed usage. Identify the agent with agent_id or external_agent_id, give
start_time_utc and two participants (one AGENT, one USER), and supply the content: for a
voice agent a recording_url (preferred), recording_base64, transcript or transcript_url;
for a text agent a transcript, transcript_url or emails (no audio). Resending with the
same metadata.external_conversation_id replaces the earlier conversation.
Returns status, message and ``call_id``: the new conversation's id. Scores arrive later;
read them with get_conversation(call_id) or list_conversations. Some submissions are
stored without scoring under the organization's sampling rate; message says so.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
start_time_utc
When the conversation started, as an ISO 8601 UTC timestamp such as 2026-11-04T15:30:00Z. Transcript, tool-call and event offsets count from this moment.
Clear enough to supply this argument.
$defs › Participant › role
Which side of the conversation this is: AGENT for the agent being evaluated, USER for the customer it spoke with. DIGITAL_HUMAN marks Bluejay's simulated caller; lowercase values are legacy.
Clear enough to supply this argument.
$defs › Participant › name
Display name for this participant, e.g. the agent's or caller's name.
Clear enough to supply this argument.
$defs › Participant › spoke_first
True for the participant who spoke first in the conversation, false for the other.
Clear enough to supply this argument.
$defs › Participant › phone_number
This participant's phone number in E.164 form (e.g. +14155550123) for phone calls; omit for web or chat.
Clear enough to supply this argument.
agent_id
The Bluejay agent this conversation belongs to: its numeric id from list_agents, as a string. Give this or external_agent_id.
Clear enough to supply this argument.
external_agent_id
Your own system's id for the agent, as saved in the agent's external_agent_id. Give this or agent_id.
Clear enough to supply this argument.
recording_url
http(s) link to the call recording (.mp3, .mp4, .wav or .m4a), public or presigned, or private with recording_auth_headers. Bluejay copies the file at ingest. Voice agents only.
Clear enough to supply this argument.
recording_base64
Deprecated: use recording_url (with recording_auth_headers for private files). The recording itself as a base64 data URL, e.g. data:audio/wav;base64,<data> (.mp3, .mp4, .wav or .m4a). Bluejay uploads it and uses it like recording_url. Voice agents only; large files make the request very large.
Clear enough to supply this argument.
call_direction
Who placed the call, from the agent's side: INBOUND when the customer reached the agent, OUTBOUND when the agent called out. Omitted means INBOUND.
Clear enough to supply this argument.
interface
Channel the conversation ran over: PHONE for a phone call, WEB for a browser or app session. Omitted means PHONE.
Clear enough to supply this argument.
transcript_url
http(s) link to a .json transcript file, as an alternative to sending transcript inline.
Clear enough to supply this argument.
$defs › TranscriptEntryRequest › start_offset_ms
Start offset of the utterance in milliseconds
Clear enough to supply this argument.
$defs › TranscriptEntryRequest › end_offset_ms
End offset of the utterance in milliseconds
Clear enough to supply this argument.
$defs › TranscriptEntryRequest › speaker
Identifier for the speaker (e.g., 'AGENT', 'USER')
Clear enough to supply this argument.
$defs › TranscriptEntryRequest › utterance
Transcribed text of the utterance
Clear enough to supply this argument.
$defs › TranscriptEntryRequest › filler_utterance
True when this utterance is filler that covers a pause, such as 'one moment' or 'let me check', rather than a real reply. Lets latency be measured to the first real reply.
Clear enough to supply this argument.
$defs › EmailMessageRequest › speaker
Who sent this email: 'AGENT' or 'USER'
Clear enough to supply this argument.
$defs › EmailMessageRequest › raw
Full RFC 822 source of the email, headers included. The agent's emails are checked for SPF, DKIM, DMARC and spam.
Clear enough to supply this argument.
$defs › ToolCallData › name
Name of the tool the agent called, e.g. lookup_order.
Clear enough to supply this argument.
$defs › ToolCallData › start_offset_ms
When the agent called the tool, in milliseconds from the start of the conversation.
Clear enough to supply this argument.
$defs › ToolCallData › description
What the tool does, as described to the agent.
Clear enough to supply this argument.
$defs › ToolCallData › parameters
Arguments the agent passed to the tool, as a JSON object.
Clear enough to supply this argument.
$defs › ToolCallData › output
What the tool returned to the agent: text or any JSON value.
Clear enough to supply this argument.
events
Notable moments to attach, such as a transfer or hold. Each is an object with title and start_offset_ms, and optionally description, end_offset_ms, tags and metadata.
Clear enough to supply this argument.
tags
Free-text tags to store on the conversation; list_conversations can filter by them.
Clear enough to supply this argument.
metadata
Extra JSON stored on the conversation (list_conversations can filter by its keys). Set `external_conversation_id` to your own id for the conversation to update it later (scoped to the agent): sending again with the same id replaces it and evaluates it again (each send is billed), and identical content is ignored. Provider call ids (`vapi_call_id`, `retell_call_id`, `bland_call_id`, `eleven_labs_conversation_id`) take precedence over it.
Clear enough to supply this argument.
webhook_tag
Tag of one of your organization's existing webhooks that should receive this evaluation's result.
Clear enough to supply this argument.
custom_metrics
Extra custom metric ids (UUIDs from list_custom_metrics) to score this conversation with, on top of the agent's own metrics.
Clear enough to supply this argument.
label
Name of the agent label to evaluate against; it picks which prompt version and knowledge base apply. Omitted means production. An unknown label is created and attached to the production version.
Clear enough to supply this argument.
enable_phrase_latencies
Deprecated; ignored.
Clear enough to supply this argument.
conversation_ended_by
Which side ended the conversation, when known: USER or AGENT.
Clear enough to supply this argument.
multichannel
True when the recording puts each participant on a separate audio channel. Omitted means false.
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "success when the conversation was accepted."
},
"call_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The new production conversation's id. Pass it to get_conversation (or conversation_ids on list_conversations) to read its scores once evaluation finishes."
},
"message": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What happened: 'Call submitted for evaluation' (scoring queued), 'Call ingested' (stored without scoring, e.g. sampled out), or 'Call already processed' (identical resend)."
},
"warning": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Non-fatal notes from ingest, such as the agent having no production version."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "evaluate",
"title": "Submit conversation for evaluation",
"description": "Submit one finished production conversation (a call, chat or email thread) for Bluejay\nto store and score (POST /v1/evaluate).\n\nCreates a conversation under the agent in your observability data and queues the agent's\nmetrics, plus any custom_metrics, to run on it asynchronously. Each submission counts\ntoward billed usage. Identify the agent with agent_id or external_agent_id, give\nstart_time_utc and two participants (one AGENT, one USER), and supply the content: for a\nvoice agent a recording_url (preferred), recording_base64, transcript or transcript_url;\nfor a text agent a transcript, transcript_url or emails (no audio). Resending with the\nsame metadata.external_conversation_id replaces the earlier conversation.\n\nReturns status, message and ``call_id``: the new conversation's id. Scores arrive later;\nread them with get_conversation(call_id) or list_conversations. Some submissions are\nstored without scoring under the organization's sampling rate; message says so.\n",
"inputSchema": {
"type": "object",
"$defs": {
"Participant": {
"type": "object",
"title": "Participant",
"properties": {
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Name",
"default": null,
"description": "Display name for this participant, e.g. the agent's or caller's name."
},
"role": {
"$ref": "#/$defs/ParticipantRole",
"default": "AGENT",
"description": "Which side of the conversation this is: AGENT for the agent being evaluated, USER for the customer it spoke with. DIGITAL_HUMAN marks Bluejay's simulated caller; lowercase values are legacy."
},
"spoke_first": {
"type": "boolean",
"title": "Spoke First",
"default": false,
"description": "True for the participant who spoke first in the conversation, false for the other."
},
"phone_number": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Phone Number",
"default": null,
"description": "This participant's phone number in E.164 form (e.g. +14155550123) for phone calls; omit for web or chat."
}
},
"description": "Participant on a call or conversation."
},
"ToolCallData": {
"type": "object",
"title": "ToolCallData",
"required": [
"name",
"start_offset_ms"
],
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "Name of the tool the agent called, e.g. lookup_order."
},
"output": {
"anyOf": [
{},
{
"type": "null"
}
],
"title": "Output",
"default": null,
"description": "What the tool returned to the agent: text or any JSON value."
},
"parameters": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Parameters",
"default": null,
"description": "Arguments the agent passed to the tool, as a JSON object."
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description",
"default": null,
"description": "What the tool does, as described to the agent."
},
"start_offset_ms": {
"type": "integer",
"title": "Start Offset Ms",
"description": "When the agent called the tool, in milliseconds from the start of the conversation."
}
},
"description": "Tool call as stored on calls, jobs, and test results (API and database)."
},
"ParticipantRole": {
"enum": [
"AGENT",
"USER",
"DIGITAL_HUMAN",
"agent",
"digital_human"
],
"type": "string",
"title": "ParticipantRole",
"description": "Role of a participant in a call or simulated conversation."
},
"EmailMessageRequest": {
"type": "object",
"title": "EmailMessageRequest",
"required": [
"speaker",
"raw"
],
"properties": {
"raw": {
"type": "string",
"title": "Raw",
"maxLength": 1000000,
"description": "Full RFC 822 source of the email, headers included. The agent's emails are checked for SPF, DKIM, DMARC and spam."
},
"speaker": {
"enum": [
"AGENT",
"USER"
],
"type": "string",
"title": "Speaker",
"description": "Who sent this email: 'AGENT' or 'USER'"
}
}
},
"TranscriptEntryRequest": {
"type": "object",
"title": "TranscriptEntryRequest",
"required": [
"start_offset_ms",
"end_offset_ms",
"speaker",
"utterance"
],
"properties": {
"speaker": {
"$ref": "#/$defs/ParticipantRole",
"description": "Identifier for the speaker (e.g., 'AGENT', 'USER')"
},
"utterance": {
"type": "string",
"title": "Utterance",
"description": "Transcribed text of the utterance"
},
"end_offset_ms": {
"type": "integer",
"title": "End Offset Ms",
"description": "End offset of the utterance in milliseconds"
},
"start_offset_ms": {
"type": "integer",
"title": "Start Offset Ms",
"description": "Start offset of the utterance in milliseconds"
},
"filler_utterance": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Filler Utterance",
"default": null,
"description": "True when this utterance is filler that covers a pause, such as 'one moment' or 'let me check', rather than a real reply. Lets latency be measured to the first real reply."
}
}
}
},
"title": "evaluateArguments",
"required": [
"start_time_utc",
"participants"
],
"properties": {
"tags": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Tags",
"default": null,
"description": "Free-text tags to store on the conversation; list_conversations can filter by them."
},
"label": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Label",
"default": null,
"description": "Name of the agent label to evaluate against; it picks which prompt version and knowledge base apply. Omitted means production. An unknown label is created and attached to the production version."
},
"emails": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/EmailMessageRequest"
}
},
{
"type": "null"
}
],
"title": "Emails",
"default": null,
"description": "For email conversations: the thread in send order, each with its sender and raw RFC 822 source. Builds the transcript when none is given."
},
"events": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
{
"type": "null"
}
],
"title": "Events",
"default": null,
"description": "Notable moments to attach, such as a transfer or hold. Each is an object with title and start_offset_ms, and optionally description, end_offset_ms, tags and metadata."
},
"agent_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Agent Id",
"default": null,
"description": "The Bluejay agent this conversation belongs to: its numeric id from list_agents, as a string. Give this or external_agent_id."
},
"metadata": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Metadata",
"default": null,
"description": "Extra JSON stored on the conversation (list_conversations can filter by its keys). Set `external_conversation_id` to your own id for the conversation to update it later (scoped to the agent): sending again with the same id replaces it and evaluates it again (each send is billed), and identical content is ignored. Provider call ids (`vapi_call_id`, `retell_call_id`, `bland_call_id`, `eleven_labs_conversation_id`) take precedence over it."
},
"interface": {
"anyOf": [
{
"enum": [
"PHONE",
"WEB"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Interface",
"default": null,
"description": "Channel the conversation ran over: PHONE for a phone call, WEB for a browser or app session. Omitted means PHONE."
},
"tool_calls": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/ToolCallData"
}
},
{
"type": "null"
}
],
"title": "Tool Calls",
"default": null,
"description": "Tools the agent called during the conversation, with their arguments and results, so tool-use metrics can judge them."
},
"transcript": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/TranscriptEntryRequest"
}
},
{
"type": "null"
}
],
"title": "Transcript",
"default": null,
"description": "The conversation as ordered utterances, each with speaker, utterance text and start/end offsets in milliseconds from start_time_utc. Needed unless a recording, transcript_url or emails is given."
},
"webhook_tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Webhook Tag",
"default": null,
"description": "Tag of one of your organization's existing webhooks that should receive this evaluation's result."
},
"multichannel": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Multichannel",
"default": null,
"description": "True when the recording puts each participant on a separate audio channel. Omitted means false."
},
"participants": {
"type": "array",
"items": {
"$ref": "#/$defs/Participant"
},
"title": "Participants",
"description": "The two sides of the conversation: one entry with role AGENT (your agent) and one with role USER (the customer)."
},
"recording_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Recording Url",
"default": null,
"description": "http(s) link to the call recording (.mp3, .mp4, .wav or .m4a), public or presigned, or private with recording_auth_headers. Bluejay copies the file at ingest. Voice agents only."
},
"call_direction": {
"anyOf": [
{
"enum": [
"INBOUND",
"OUTBOUND"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Call Direction",
"default": null,
"description": "Who placed the call, from the agent's side: INBOUND when the customer reached the agent, OUTBOUND when the agent called out. Omitted means INBOUND."
},
"custom_metrics": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Custom Metrics",
"default": null,
"description": "Extra custom metric ids (UUIDs from list_custom_metrics) to score this conversation with, on top of the agent's own metrics."
},
"start_time_utc": {
"type": "string",
"title": "Start Time Utc",
"description": "When the conversation started, as an ISO 8601 UTC timestamp such as 2026-11-04T15:30:00Z. Transcript, tool-call and event offsets count from this moment."
},
"transcript_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Transcript Url",
"default": null,
"description": "http(s) link to a .json transcript file, as an alternative to sending transcript inline."
},
"recording_base64": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Recording Base64",
"default": null,
"description": "Deprecated: use recording_url (with recording_auth_headers for private files). The recording itself as a base64 data URL, e.g. data:audio/wav;base64,<data> (.mp3, .mp4, .wav or .m4a). Bluejay uploads it and uses it like recording_url. Voice agents only; large files make the request very large."
},
"external_agent_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "External Agent Id",
"default": null,
"description": "Your own system's id for the agent, as saved in the agent's external_agent_id. Give this or agent_id."
},
"conversation_ended_by": {
"anyOf": [
{
"enum": [
"AGENT",
"USER"
],
"type": "string"
},
{
"type": "null"
}
],
"title": "Conversation Ended By",
"default": null,
"description": "Which side ended the conversation, when known: USER or AGENT."
},
"enable_phrase_latencies": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "Enable Phrase Latencies",
"default": null,
"description": "Deprecated; ignored."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "success when the conversation was accepted."
},
"call_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The new production conversation's id. Pass it to get_conversation (or conversation_ids on list_conversations) to read its scores once evaluation finishes."
},
"message": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What happened: 'Call submitted for evaluation' (scoring queued), 'Call ingested' (stored without scoring, e.g. sampled out), or 'Call already processed' (identical resend)."
},
"warning": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Non-fatal notes from ingest, such as the agent having no production version."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
Align the title with the capability actually described by this tool.
Description99/100
Post the agent's next chat message into a running HTTP text simulation
(POST /v1/send-http-text-message).
Used for simulations of HTTP-webhook text agents, where your agent answers through this
call instead of a phone line. The message is added to the live transcript as the agent's
turn and Bluejay's digital human replies by calling the agent's webhook. This changes the
live conversation and cannot be taken back; each turn counts toward the simulation's max
turns, and end_conversation=true ends the conversation and starts its evaluation.
Returns simulation_result_id, status and ``end_conversation``: true once the conversation
has ended, after which further messages are ignored.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
simulation_result_id
The running text conversation to post into: one of the simulation_result_ids POST /v1/queue-http-text-simulation-run returned, or a result id from get_simulation_results.
Clear enough to supply this argument.
message
The agent's reply, exactly as the agent would send it to the customer.
Clear enough to supply this argument.
end_conversation
True to make this the agent's last message: the conversation ends and is evaluated, with no digital-human reply. Omitted means false.
Clear enough to supply this argument.
end_turn
False to hold this message and send it with the next one as a single turn, for agents that reply in several pieces. Omitted means true: the turn goes out now.
Clear enough to supply this argument.
message_id
Your unique id for this message. A repeat with the same id in the same conversation is ignored, so retries are safe.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "success when the message was accepted, ignored as a duplicate, or held."
},
"end_conversation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the conversation has ended (this message ended it, or it had already ended and the message was ignored)."
},
"simulation_result_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The conversation the message was posted to."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "send_http_text_message",
"title": "Send agent chat message",
"description": "Post the agent's next chat message into a running HTTP text simulation\n(POST /v1/send-http-text-message).\n\nUsed for simulations of HTTP-webhook text agents, where your agent answers through this\ncall instead of a phone line. The message is added to the live transcript as the agent's\nturn and Bluejay's digital human replies by calling the agent's webhook. This changes the\nlive conversation and cannot be taken back; each turn counts toward the simulation's max\nturns, and end_conversation=true ends the conversation and starts its evaluation.\n\nReturns simulation_result_id, status and ``end_conversation``: true once the conversation\nhas ended, after which further messages are ignored.\n",
"inputSchema": {
"type": "object",
"title": "send_http_text_messageArguments",
"required": [
"simulation_result_id",
"message"
],
"properties": {
"message": {
"type": "string",
"title": "Message",
"description": "The agent's reply, exactly as the agent would send it to the customer."
},
"end_turn": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "End Turn",
"default": null,
"description": "False to hold this message and send it with the next one as a single turn, for agents that reply in several pieces. Omitted means true: the turn goes out now."
},
"message_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Message Id",
"default": null,
"description": "Your unique id for this message. A repeat with the same id in the same conversation is ignored, so retries are safe."
},
"end_conversation": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"title": "End Conversation",
"default": null,
"description": "True to make this the agent's last message: the conversation ends and is evaluated, with no digital-human reply. Omitted means false."
},
"simulation_result_id": {
"type": "string",
"title": "Simulation Result Id",
"description": "The running text conversation to post into: one of the simulation_result_ids POST /v1/queue-http-text-simulation-run returned, or a result id from get_simulation_results."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "success when the message was accepted, ignored as a duplicate, or held."
},
"end_conversation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the conversation has ended (this message ended it, or it had already ended and the message was ignored)."
},
"simulation_result_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The conversation the message was posted to."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Translate every utterance of one conversation's transcript into another language with
Google Translate (POST /v1/translate-transcript).
Works on a simulated conversation (simulation_result_id) or a production conversation
(conversation_id); give one. The translation is saved on the conversation for reuse and
the original transcript is not changed. If the conversation already has a saved
translation, that one is returned as is, whatever target_language you pass.
Returns ``translated_transcript_url`` (a signed link to the translated transcript),
target_language and success.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
simulation_result_id
A simulated conversation to translate: its result id from get_simulation_results. Give this or conversation_id.
Clear enough to supply this argument.
conversation_id
A production conversation to translate: its id (UUID) from list_conversations, or the call_id evaluate returns. Give this or simulation_result_id.
Clear enough to supply this argument.
target_language
Language code to translate into, such as es, fr or de. Omitted means en (English).
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"success": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when a translation was produced or an existing one was found."
},
"target_language": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The language code the transcript was translated into."
},
"translated_transcript_url": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Signed link to the translated transcript (JSON utterances)."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "translate_transcript",
"title": "Translate transcript",
"description": "Translate every utterance of one conversation's transcript into another language with\nGoogle Translate (POST /v1/translate-transcript).\n\nWorks on a simulated conversation (simulation_result_id) or a production conversation\n(conversation_id); give one. The translation is saved on the conversation for reuse and\nthe original transcript is not changed. If the conversation already has a saved\ntranslation, that one is returned as is, whatever target_language you pass.\n\nReturns ``translated_transcript_url`` (a signed link to the translated transcript),\ntarget_language and success.\n",
"inputSchema": {
"type": "object",
"title": "translate_transcriptArguments",
"properties": {
"conversation_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Conversation Id",
"default": null,
"description": "A production conversation to translate: its id (UUID) from list_conversations, or the call_id evaluate returns. Give this or simulation_result_id."
},
"target_language": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Target Language",
"default": null,
"description": "Language code to translate into, such as es, fr or de. Omitted means en (English)."
},
"simulation_result_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Simulation Result Id",
"default": null,
"description": "A simulated conversation to translate: its result id from get_simulation_results. Give this or conversation_id."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"success": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when a translation was produced or an existing one was found."
},
"target_language": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The language code the transcript was translated into."
},
"translated_transcript_url": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Signed link to the translated transcript (JSON utterances)."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Hang up running simulated conversations now (POST /v1/end-conversations).
For each id that is RUNNING, Bluejay signals the live call worker to end the call
gracefully, with a 30-second fallback that marks it ended if the worker does not respond.
Ids that are not running are reported in failed_ids and left alone. Irreversible: an
ended conversation cannot be resumed, so confirm with the user before ending calls they
did not ask to stop.
Returns success, ended_count, test_result_ids (the ids marked for ending), failed_ids and
message.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
test_result_ids
Ids of the running simulated conversations to end: result ids from get_simulation_results (called test_result_id elsewhere).
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"message": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Summary of what was ended."
},
"success": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when at least one conversation was marked for ending."
},
"failed_ids": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Ids that were not ended: not running, already finished, or not found."
},
"ended_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "How many conversations were marked for ending."
},
"test_result_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Ids of the conversations marked for ending.",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "end_conversations",
"title": "End conversations",
"description": "Hang up running simulated conversations now (POST /v1/end-conversations).\n\nFor each id that is RUNNING, Bluejay signals the live call worker to end the call\ngracefully, with a 30-second fallback that marks it ended if the worker does not respond.\nIds that are not running are reported in failed_ids and left alone. Irreversible: an\nended conversation cannot be resumed, so confirm with the user before ending calls they\ndid not ask to stop.\n\nReturns success, ended_count, test_result_ids (the ids marked for ending), failed_ids and\nmessage.\n",
"inputSchema": {
"type": "object",
"title": "end_conversationsArguments",
"required": [
"test_result_ids"
],
"properties": {
"test_result_ids": {
"type": "array",
"items": {
"type": "integer"
},
"title": "Test Result Ids",
"description": "Ids of the running simulated conversations to end: result ids from get_simulation_results (called test_result_id elsewhere)."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"message": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Summary of what was ended."
},
"success": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when at least one conversation was marked for ending."
},
"failed_ids": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Ids that were not ended: not running, already finished, or not found."
},
"ended_count": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "How many conversations were marked for ending."
},
"test_result_ids": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"integer",
"number",
"string",
"null"
]
},
"properties": {},
"description": "Ids of the conversations marked for ending.",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List all phone numbers for the org via GET /v1/phone-numbers. Read-only.
These are the numbers Bluejay owns on your behalf for simulated calls. Returns
``phone_numbers``, each with id, phone_number (E.164), purchase_date, price in cents and
created_at; only numbers in workspaces you can see are included.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"phone_numbers": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Bluejay's record id for the number."
},
"price": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Monthly price in cents; 0 for numbers in the free allowance."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the record was created."
},
"phone_number": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The number in E.164 form; pass it to DELETE /v1/phone-numbers/{phone_number}/release."
},
"purchase_date": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Date the number was bought."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Owning organization."
}
},
"description": "A phone number Bluejay owns on your organization's behalf for simulated calls.",
"additionalProperties": true
},
"properties": {},
"description": "A list. Each item: A phone number Bluejay owns on your organization's behalf for simulated calls.",
"additionalProperties": true
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "list_phone_numbers",
"title": "List phone numbers",
"description": "List all phone numbers for the org via GET /v1/phone-numbers. Read-only.\n\nThese are the numbers Bluejay owns on your behalf for simulated calls. Returns\n``phone_numbers``, each with id, phone_number (E.164), purchase_date, price in cents and\ncreated_at; only numbers in workspaces you can see are included.\n",
"inputSchema": {
"type": "object",
"title": "list_phone_numbersArguments",
"properties": {}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"phone_numbers": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"id": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Bluejay's record id for the number."
},
"price": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Monthly price in cents; 0 for numbers in the free allowance."
},
"created_at": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "When the record was created."
},
"phone_number": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The number in E.164 form; pass it to DELETE /v1/phone-numbers/{phone_number}/release."
},
"purchase_date": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Date the number was bought."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Owning organization."
}
},
"description": "A phone number Bluejay owns on your organization's behalf for simulated calls.",
"additionalProperties": true
},
"properties": {},
"description": "A list. Each item: A phone number Bluejay owns on your organization's behalf for simulated calls.",
"additionalProperties": true
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Purchase a new phone number via POST /v1/phone-numbers/add.
Buys one real US phone number from Twilio and adds it to your organization, in your
default workspace. Numbers past the organization's free allowance are billed monthly
(a card on file is required for those), and the organization's number limit applies.
Confirm with the user before calling. Returns ``numbers`` (the purchased number, its
Twilio SID, purchase date and price in cents) and ``total_price_cents``.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
area_code
Three-digit US area code to buy the number in, such as 415. If none is free there the request fails. Omit to take any available US number.
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"numbers": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"price": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Monthly price in cents; 0 when it falls in the free allowance."
},
"twilio_sid": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Twilio's id for the number (IncomingPhoneNumber SID)."
},
"phone_number": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The purchased number in E.164 form."
},
"purchase_date": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Date of purchase."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Owning organization."
}
},
"description": "Response schema after auto-purchasing and storing a phone number.",
"additionalProperties": true
},
"properties": {},
"description": "The numbers that were bought, one entry each.",
"additionalProperties": true
},
"total_price_cents": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Combined monthly price of what was bought, in cents."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "add_phone_number",
"title": "Add phone number",
"description": "Purchase a new phone number via POST /v1/phone-numbers/add.\n\nBuys one real US phone number from Twilio and adds it to your organization, in your\ndefault workspace. Numbers past the organization's free allowance are billed monthly\n(a card on file is required for those), and the organization's number limit applies.\nConfirm with the user before calling. Returns ``numbers`` (the purchased number, its\nTwilio SID, purchase date and price in cents) and ``total_price_cents``.\n",
"inputSchema": {
"type": "object",
"title": "add_phone_numberArguments",
"properties": {
"area_code": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Area Code",
"default": null,
"description": "Three-digit US area code to buy the number in, such as 415. If none is free there the request fails. Omit to take any available US number."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"numbers": {
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"price": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Monthly price in cents; 0 when it falls in the free allowance."
},
"twilio_sid": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Twilio's id for the number (IncomingPhoneNumber SID)."
},
"phone_number": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The purchased number in E.164 form."
},
"purchase_date": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Date of purchase."
},
"organization_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Owning organization."
}
},
"description": "Response schema after auto-purchasing and storing a phone number.",
"additionalProperties": true
},
"properties": {},
"description": "The numbers that were bought, one entry each.",
"additionalProperties": true
},
"total_price_cents": {
"type": [
"integer",
"number",
"string",
"null"
],
"description": "Combined monthly price of what was bought, in cents."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Release a phone number via DELETE /v1/phone-numbers/{phone_number}/release.
Permanently gives the number up: it is returned to Twilio and removed from your
organization, and you cannot get the same number back. Anything that dials from or to it
stops working. If it was a billed number, its monthly charge stops at the end of the
billing period. Confirm with the user before calling. Returns ``phone_number`` and
``released``.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
phone_number
The number to give up, exactly as list_phone_numbers shows it (E.164, e.g. +14155550123).
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"released": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the number was given back to Twilio; false when another organization still uses it, so only your organization's record was removed."
},
"phone_number": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The number that was removed, in E.164 form."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "release_phone_number",
"title": "Release phone number",
"description": "Release a phone number via DELETE /v1/phone-numbers/{phone_number}/release.\n\nPermanently gives the number up: it is returned to Twilio and removed from your\norganization, and you cannot get the same number back. Anything that dials from or to it\nstops working. If it was a billed number, its monthly charge stops at the end of the\nbilling period. Confirm with the user before calling. Returns ``phone_number`` and\n``released``.\n",
"inputSchema": {
"type": "object",
"title": "release_phone_numberArguments",
"required": [
"phone_number"
],
"properties": {
"phone_number": {
"type": "string",
"title": "Phone Number",
"description": "The number to give up, exactly as list_phone_numbers shows it (E.164, e.g. +14155550123)."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"released": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the number was given back to Twilio; false when another organization still uses it, so only your organization's record was removed."
},
"phone_number": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The number that was removed, in E.164 form."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Return a compact, read-only view of the agent's multi-agent workflow as stored in Bluejay.
Shape: ``{"nodes": [{node_id, name, prompt_excerpt, type}], "edges": [{edge_id, source_node_id,
target_node_id, condition}]}``. Use this before ``update_workflow_node`` so you know which
``node_id`` to target without paying for the full workflow blob.
Works for any workflow-adapter provider — **ElevenLabs, Google Dialogflow CX**
(``GOOGLE_DFCX_VOICE`` / ``GOOGLE_DFCX_CHAT``), **VAPI**, **Retell**, **Amelia**, and
**Bland**. For DFCX, nodes are flows/pages/playbooks and edges are transition routes/event
handlers; for Amelia they come from the synced flow revision; for Bland they are the pathway's
nodes and routes; for Google CES nodes are the app's agents and edges are their handoffs.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Bluejay id of the agent (from list_agents) whose stored workflow to use. It needs a workflow already pulled with sync_agent_workflow.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Update a single node inside the agent's stored multi-agent workflow. Returns status.
Pass only the fields you want to change. ``None`` leaves a field unchanged. At least one
of ``prompt``, ``name``, or ``description`` must be supplied.
This writes to the Bluejay-stored workflow only. To push the change back to the source
provider, call ``push_agent_workflow`` afterwards.
Works for any workflow-adapter provider — ElevenLabs, Google Dialogflow CX
(``GOOGLE_DFCX_VOICE`` / ``GOOGLE_DFCX_CHAT``), VAPI, Retell, and Bland. For DFCX this edits
the prompt/fulfillment of a page or playbook node; for Bland the prompt of a pathway node.
Amelia rejects node edits: edit the flow in Amelia and sync again. Provider-specific fields
(ElevenLabs voice/llm/eagerness, etc.) are not supported here; use the provider-named tool
when one exists.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Bluejay id of the agent (from list_agents) whose stored workflow to use. It needs a workflow already pulled with sync_agent_workflow.
Clear enough to supply this argument.
node_id
Id of the node to change: a nodes[].node_id from get_workflow_summary.
Clear enough to supply this argument.
prompt
New prompt for the node (for DFCX, the page's fulfillment text or the playbook's instructions).
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Add a new node to the agent's multi-agent workflow (Bluejay-side only).
The new node has no incoming/outgoing edges — it's unreachable until you connect it with
``add_workflow_edge``. Returns ``{node_id}`` so you can wire it up in a follow-up call.
Works for ElevenLabs, Google Dialogflow CX, VAPI, Retell, and Bland (not Amelia). For DFCX the
node is added as a new page on the agent's first flow (it gets a real Dialogflow resource name
on push).
This writes to the Bluejay-stored workflow only. Call ``push_agent_workflow`` afterwards to
make the change live upstream.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Explain what happens when this optional value is omitted.
agent_id
Bluejay id of the agent (from list_agents) whose stored workflow to use. It needs a workflow already pulled with sync_agent_workflow.
Clear enough to supply this argument.
name
Display name of the new node, e.g. "Billing".
Clear enough to supply this argument.
prompt
Prompt or instructions the new node runs with.
Explain what happens when this optional value is omitted.
description
What the new node handles.
Explain what happens when this optional value is omitted.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Remove a node from the workflow. Every edge touching the node is cascade-deleted.
The Start node is protected — every workflow needs an entry point. Writes to Bluejay only;
push afterwards to ship the change upstream. To undo before pushing, sync_agent_workflow again,
which discards every unpushed edit. Returns status with the agent_id and node_id; call
get_workflow_summary to see the remaining graph.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Bluejay id of the agent (from list_agents) whose stored workflow to use. It needs a workflow already pulled with sync_agent_workflow.
Clear enough to supply this argument.
node_id
Id of the node to remove: a nodes[].node_id from get_workflow_summary. The Start node cannot be removed.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Add a directed edge between two existing nodes in the agent's workflow. Returns the new edge_id.
``condition`` is the user-facing transition trigger (e.g. "caller asks about returns"). It's
optional but strongly recommended — without one the agent can't tell when to follow the edge.
Works for ElevenLabs, Google Dialogflow CX, VAPI, Retell, and Bland (not Amelia). For DFCX this
adds a transition route on the source page targeting the destination page/flow — e.g. to
re-route a billing intent into the Billing Disputes Flow, or reattach a response to the correct
intent. ``condition`` becomes the route's condition/intent label. On a Bland pathway with branch
conditions, push_agent_workflow refuses routing changes, since Bland's update API would drop them.
Writes to Bluejay only; push afterwards to ship the change upstream.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Bluejay id of the agent (from list_agents) whose stored workflow to use. It needs a workflow already pulled with sync_agent_workflow.
Clear enough to supply this argument.
source_node_id
Node the transition leaves from: a nodes[].node_id from get_workflow_summary.
Clear enough to supply this argument.
target_node_id
Node the transition goes to: a nodes[].node_id from get_workflow_summary.
Clear enough to supply this argument.
condition
When to follow this edge, in plain words, e.g. "caller asks about returns". For DFCX it becomes the route's condition or intent label.
{
"name": "add_workflow_edge",
"title": "Add workflow edge",
"description": "Add a directed edge between two existing nodes in the agent's workflow. Returns the new edge_id.\n\n``condition`` is the user-facing transition trigger (e.g. \"caller asks about returns\"). It's\noptional but strongly recommended — without one the agent can't tell when to follow the edge.\n\nWorks for ElevenLabs, Google Dialogflow CX, VAPI, Retell, and Bland (not Amelia). For DFCX this\nadds a transition route on the source page targeting the destination page/flow — e.g. to\nre-route a billing intent into the Billing Disputes Flow, or reattach a response to the correct\nintent. ``condition`` becomes the route's condition/intent label. On a Bland pathway with branch\nconditions, push_agent_workflow refuses routing changes, since Bland's update API would drop them.\n\nWrites to Bluejay only; push afterwards to ship the change upstream.\n",
"inputSchema": {
"type": "object",
"title": "add_workflow_edgeArguments",
"required": [
"agent_id",
"source_node_id",
"target_node_id"
],
"properties": {
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "Bluejay id of the agent (from list_agents) whose stored workflow to use. It needs a workflow already pulled with sync_agent_workflow."
},
"condition": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Condition",
"default": null,
"description": "When to follow this edge, in plain words, e.g. \"caller asks about returns\". For DFCX it becomes the route's condition or intent label."
},
"source_node_id": {
"type": "string",
"title": "Source Node Id",
"description": "Node the transition leaves from: a nodes[].node_id from get_workflow_summary."
},
"target_node_id": {
"type": "string",
"title": "Target Node Id",
"description": "Node the transition goes to: a nodes[].node_id from get_workflow_summary."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "\"ok\" when Bluejay saved the change."
},
"edge_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Id of the new edge; pass it to delete_workflow_edge to remove it."
},
"agent_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The agent_id you passed."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Remove an edge by id from the agent's workflow stored in Bluejay. The nodes stay; only the
connection is dropped, along with its condition.
Writes to Bluejay only; the live agent changes when you push_agent_workflow. To undo before
pushing, re-add it with add_workflow_edge, or sync_agent_workflow again, which discards every
unpushed edit. Returns status with the agent_id and edge_id.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Bluejay id of the agent (from list_agents) whose stored workflow to use. It needs a workflow already pulled with sync_agent_workflow.
Clear enough to supply this argument.
edge_id
Id of the edge to remove: an edges[].edge_id from get_workflow_summary.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Pull the latest workflow from the agent's source provider into Bluejay.
Returns a confirmation preview first; once confirmed, status "ok" with the agent_id and the
branch_id pulled. Read the result with get_workflow_summary.
Supported for **ElevenLabs**, **Google Dialogflow CX** (``GOOGLE_DFCX_VOICE`` /
``GOOGLE_DFCX_CHAT``), **VAPI**, **Retell**, **Amelia**, and **Bland**. For DFCX this pulls the
agent's flows, pages, intents, playbooks, and transition routes so you can inspect and edit
them before pushing. For Amelia it pulls the latest revision of the agent's
``amelia_flow_name`` flow (inspect only, edits happen in Amelia). For Bland it pulls the
pathway named by ``bland_pathway_id`` (draft, or the version pinned by ``branch_id``).
For Google CES (``GOOGLE_CES_VOICE`` / ``GOOGLE_CES_CHAT``) it pulls the version the agent's
deployment serves (``branch_id="draft"`` for the editable draft, or a version id): every agent,
its tools and handoffs.
**Requires explicit user confirmation.** This call REPLACES Bluejay's stored workflow
with whatever the upstream provider currently has; any unsaved Bluejay edits are lost.
Calling pattern:
1. First call with ``confirmed=False`` (the default) — returns ``{needs_confirmation: true,
preview: "...", ...}`` describing what would happen.
2. Relay the preview to the user verbatim and ask "Do you want me to proceed?" (or similar).
3. ONLY after the user explicitly approves, call again with ``confirmed=True``.
``branch_id`` is opaque metadata — providers without branching (Retell, VAPI) ignore it; for
Bland it selects a pathway version number.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Bluejay id of the agent to refresh (from list_agents); it must be linked to a supported provider.
Clear enough to supply this argument.
branch_id
Which upstream version to pull: an ElevenLabs branch id (from list_elevenlabs_branches), a Bland pathway version number, or draft or a version id for Google CES. Omit for the provider's default; Retell and VAPI ignore it.
Clear enough to supply this argument.
confirmed
Leave false to get a preview; set true only after the user approves replacing Bluejay's stored workflow.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The tool to call again with confirmed=true once the user approves."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "\"ok\" once the workflow was pulled and stored."
},
"preview": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the call would do; relay it to the user verbatim."
},
"agent_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The agent_id you passed."
},
"branch_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The branch or version that was pulled, when one applies."
},
"to_proceed": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "How to proceed after the user approves."
},
"needs_confirmation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when nothing was done yet and the user must approve first."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "sync_agent_workflow",
"title": "Sync agent workflow",
"description": "Pull the latest workflow from the agent's source provider into Bluejay.\n\nReturns a confirmation preview first; once confirmed, status \"ok\" with the agent_id and the\nbranch_id pulled. Read the result with get_workflow_summary.\n\nSupported for **ElevenLabs**, **Google Dialogflow CX** (``GOOGLE_DFCX_VOICE`` /\n``GOOGLE_DFCX_CHAT``), **VAPI**, **Retell**, **Amelia**, and **Bland**. For DFCX this pulls the\nagent's flows, pages, intents, playbooks, and transition routes so you can inspect and edit\nthem before pushing. For Amelia it pulls the latest revision of the agent's\n``amelia_flow_name`` flow (inspect only, edits happen in Amelia). For Bland it pulls the\npathway named by ``bland_pathway_id`` (draft, or the version pinned by ``branch_id``).\nFor Google CES (``GOOGLE_CES_VOICE`` / ``GOOGLE_CES_CHAT``) it pulls the version the agent's\ndeployment serves (``branch_id=\"draft\"`` for the editable draft, or a version id): every agent,\nits tools and handoffs.\n\n**Requires explicit user confirmation.** This call REPLACES Bluejay's stored workflow\nwith whatever the upstream provider currently has; any unsaved Bluejay edits are lost.\n\nCalling pattern:\n 1. First call with ``confirmed=False`` (the default) — returns ``{needs_confirmation: true,\n preview: \"...\", ...}`` describing what would happen.\n 2. Relay the preview to the user verbatim and ask \"Do you want me to proceed?\" (or similar).\n 3. ONLY after the user explicitly approves, call again with ``confirmed=True``.\n\n``branch_id`` is opaque metadata — providers without branching (Retell, VAPI) ignore it; for\nBland it selects a pathway version number.\n",
"inputSchema": {
"type": "object",
"title": "sync_agent_workflowArguments",
"required": [
"agent_id"
],
"properties": {
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "Bluejay id of the agent to refresh (from list_agents); it must be linked to a supported provider."
},
"branch_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Branch Id",
"default": null,
"description": "Which upstream version to pull: an ElevenLabs branch id (from list_elevenlabs_branches), a Bland pathway version number, or draft or a version id for Google CES. Omit for the provider's default; Retell and VAPI ignore it."
},
"confirmed": {
"type": "boolean",
"title": "Confirmed",
"default": false,
"description": "Leave false to get a preview; set true only after the user approves replacing Bluejay's stored workflow."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The tool to call again with confirmed=true once the user approves."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "\"ok\" once the workflow was pulled and stored."
},
"preview": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the call would do; relay it to the user verbatim."
},
"agent_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The agent_id you passed."
},
"branch_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The branch or version that was pulled, when one applies."
},
"to_proceed": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "How to proceed after the user approves."
},
"needs_confirmation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when nothing was done yet and the user must approve first."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Push Bluejay's stored workflow back to the agent's source provider (makes the change live).
Supported for **ElevenLabs**, **Google Dialogflow CX** (``GOOGLE_DFCX_VOICE`` /
``GOOGLE_DFCX_CHAT``), **VAPI**, **Retell**, **Amelia**, and **Bland**. For DFCX this writes
your page/playbook prompt edits and added/removed transition routes back into the live
Dialogflow CX agent; it fails with HTTP 409 if the remote agent drifted. For Amelia it
publishes the stored revision back to the flow; it requires a prior sync. For Bland, prompt
edits land on the live pathway draft; a routing change on a pathway with branch conditions is
refused, since Bland's update API would drop them. Returns status with agent_id and branch_id.
**Requires explicit user confirmation.** Anything pushed becomes immediately visible to live
callers of the agent. Bluejay-side ``update_workflow_node`` edits stay local until pushed.
Calling pattern:
1. First call with ``confirmed=False`` (the default) — returns ``{needs_confirmation: true,
preview: "...", ...}`` describing what would happen.
2. Relay the preview to the user verbatim and ask "Do you want me to push these changes
live to the agent's source provider?".
3. ONLY after the user explicitly approves, call again with ``confirmed=True``.
``branch_id`` is opaque metadata — providers without branching ignore it.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
agent_id
Bluejay id of the agent (from list_agents) whose stored workflow to publish to its provider.
Clear enough to supply this argument.
branch_id
ElevenLabs branch to write to (from list_elevenlabs_branches); omit for the default. Providers without branches ignore it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
confirmed
Leave false to get a preview; set true only after the user approves pushing the change live.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The tool to call again with confirmed=true once the user approves."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "\"ok\" once the workflow was pushed. A partial DFCX push answers HTTP 207 with {results} instead."
},
"preview": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the call would do; relay it to the user verbatim."
},
"agent_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The agent_id you passed."
},
"branch_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The branch the push targeted, when one was given."
},
"to_proceed": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "How to proceed after the user approves."
},
"needs_confirmation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when nothing was done yet and the user must approve first."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "push_agent_workflow",
"title": "Push agent workflow",
"description": "Push Bluejay's stored workflow back to the agent's source provider (makes the change live).\n\nSupported for **ElevenLabs**, **Google Dialogflow CX** (``GOOGLE_DFCX_VOICE`` /\n``GOOGLE_DFCX_CHAT``), **VAPI**, **Retell**, **Amelia**, and **Bland**. For DFCX this writes\nyour page/playbook prompt edits and added/removed transition routes back into the live\nDialogflow CX agent; it fails with HTTP 409 if the remote agent drifted. For Amelia it\npublishes the stored revision back to the flow; it requires a prior sync. For Bland, prompt\nedits land on the live pathway draft; a routing change on a pathway with branch conditions is\nrefused, since Bland's update API would drop them. Returns status with agent_id and branch_id.\n\n**Requires explicit user confirmation.** Anything pushed becomes immediately visible to live\ncallers of the agent. Bluejay-side ``update_workflow_node`` edits stay local until pushed.\n\nCalling pattern:\n 1. First call with ``confirmed=False`` (the default) — returns ``{needs_confirmation: true,\n preview: \"...\", ...}`` describing what would happen.\n 2. Relay the preview to the user verbatim and ask \"Do you want me to push these changes\n live to the agent's source provider?\".\n 3. ONLY after the user explicitly approves, call again with ``confirmed=True``.\n\n``branch_id`` is opaque metadata — providers without branching ignore it.\n",
"inputSchema": {
"type": "object",
"title": "push_agent_workflowArguments",
"required": [
"agent_id"
],
"properties": {
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "Bluejay id of the agent (from list_agents) whose stored workflow to publish to its provider."
},
"branch_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Branch Id",
"default": null,
"description": "ElevenLabs branch to write to (from list_elevenlabs_branches); omit for the default. Providers without branches ignore it."
},
"confirmed": {
"type": "boolean",
"title": "Confirmed",
"default": false,
"description": "Leave false to get a preview; set true only after the user approves pushing the change live."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The tool to call again with confirmed=true once the user approves."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "\"ok\" once the workflow was pushed. A partial DFCX push answers HTTP 207 with {results} instead."
},
"preview": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the call would do; relay it to the user verbatim."
},
"agent_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The agent_id you passed."
},
"branch_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The branch the push targeted, when one was given."
},
"to_proceed": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "How to proceed after the user approves."
},
"needs_confirmation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when nothing was done yet and the user must approve first."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description87/100
Enumerate every distinct path through the agent's workflow as stored in Bluejay (read-only).
Each path: ``{"index": int, "label": str, "sub_agent_chain": [{agent_id, name,
prompt_excerpt, incoming_edge_condition}], "node_ids": [...], "truncated": bool}``. Powers
Generate-From-Workflow.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Bluejay id of the agent (from list_agents) whose stored workflow to use. It needs a workflow already pulled with sync_agent_workflow.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description87/100
List the Convai agents in the org's ElevenLabs account, read live with the org's stored
ElevenLabs API key. Read-only: nothing is attached or changed.
Returns ``{"agents": [{agent_id, name}], "error": null}``, where agent_id is the ElevenLabs id,
not a Bluejay id. Use it when adding an ElevenLabs agent: the user picks one, then add_agent
links it by passing that agent_id as eleven_labs_agent_id.
Resolve contradictions between the description, input schema, and annotations.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List a Convai agent's branches (Main + drafts + custom), read live from ElevenLabs. Read-only.
Returns ``{"branches": [{id, name, is_main, ...}], "main_branch_id": str | null}``.
Use the returned ``id`` as the ``branch_id`` parameter for ``sync_agent_workflow`` /
``push_agent_workflow`` when you want to read/write a non-default branch.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Bluejay id (from list_agents) of an agent linked to ElevenLabs through eleven_labs_agent_id; not the ElevenLabs agent id.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Merge an Experiment branch into Main (or any source → target) on the Convai agent, in
ElevenLabs itself. Bluejay's stored workflow is unchanged until you sync_agent_workflow.
Returns a confirmation preview first, then status "ok" with both branch ids.
**Requires explicit user confirmation.** Merging into Main typically makes a draft go live
for callers — same blast radius as a push.
Calling pattern:
1. First call with ``confirmed=False`` (the default) — returns ``{needs_confirmation: true,
preview: "..."}`` describing what would happen.
2. Relay the preview to the user and ask "Do you want me to merge?".
3. ONLY after the user explicitly approves, call again with ``confirmed=True``.
``archive_source=True`` archives the source branch on success. ``force=True`` overrides
conflict detection on the ElevenLabs side.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Bluejay id (from list_agents) of an agent linked to ElevenLabs through eleven_labs_agent_id; not the ElevenLabs agent id.
Clear enough to supply this argument.
source_branch_id
Branch whose changes to merge: an id from list_elevenlabs_branches.
Clear enough to supply this argument.
target_branch_id
Branch to merge into, usually main_branch_id from list_elevenlabs_branches.
Clear enough to supply this argument.
archive_source
Set true to archive the source branch once the merge succeeds.
Clear enough to supply this argument.
force
Set true to bypass ElevenLabs' conflict detection and merge anyway.
Clear enough to supply this argument.
confirmed
Leave false to get a preview; set true only after the user approves the merge.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"force": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Whether conflict detection will be bypassed."
},
"action": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The tool to call again with confirmed=true once the user approves."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "\"ok\" once ElevenLabs merged the branches."
},
"preview": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the merge would do; relay it to the user."
},
"agent_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The Bluejay agent id you passed."
},
"to_proceed": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "How to proceed after the user approves."
},
"archive_source": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Whether the source branch will be archived."
},
"source_branch_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The branch merged from."
},
"target_branch_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The branch merged into."
},
"needs_confirmation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when nothing was done yet and the user must approve first."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "merge_elevenlabs_branches",
"title": "Merge ElevenLabs branches",
"description": "Merge an Experiment branch into Main (or any source → target) on the Convai agent, in\nElevenLabs itself. Bluejay's stored workflow is unchanged until you sync_agent_workflow.\nReturns a confirmation preview first, then status \"ok\" with both branch ids.\n\n**Requires explicit user confirmation.** Merging into Main typically makes a draft go live\nfor callers — same blast radius as a push.\n\nCalling pattern:\n 1. First call with ``confirmed=False`` (the default) — returns ``{needs_confirmation: true,\n preview: \"...\"}`` describing what would happen.\n 2. Relay the preview to the user and ask \"Do you want me to merge?\".\n 3. ONLY after the user explicitly approves, call again with ``confirmed=True``.\n\n``archive_source=True`` archives the source branch on success. ``force=True`` overrides\nconflict detection on the ElevenLabs side.\n",
"inputSchema": {
"type": "object",
"title": "merge_elevenlabs_branchesArguments",
"required": [
"agent_id",
"source_branch_id",
"target_branch_id"
],
"properties": {
"force": {
"type": "boolean",
"title": "Force",
"default": false,
"description": "Set true to bypass ElevenLabs' conflict detection and merge anyway."
},
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "Bluejay id (from list_agents) of an agent linked to ElevenLabs through eleven_labs_agent_id; not the ElevenLabs agent id."
},
"confirmed": {
"type": "boolean",
"title": "Confirmed",
"default": false,
"description": "Leave false to get a preview; set true only after the user approves the merge."
},
"archive_source": {
"type": "boolean",
"title": "Archive Source",
"default": false,
"description": "Set true to archive the source branch once the merge succeeds."
},
"source_branch_id": {
"type": "string",
"title": "Source Branch Id",
"description": "Branch whose changes to merge: an id from list_elevenlabs_branches."
},
"target_branch_id": {
"type": "string",
"title": "Target Branch Id",
"description": "Branch to merge into, usually main_branch_id from list_elevenlabs_branches."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"force": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Whether conflict detection will be bypassed."
},
"action": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The tool to call again with confirmed=true once the user approves."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "\"ok\" once ElevenLabs merged the branches."
},
"preview": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the merge would do; relay it to the user."
},
"agent_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The Bluejay agent id you passed."
},
"to_proceed": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "How to proceed after the user approves."
},
"archive_source": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "Whether the source branch will be archived."
},
"source_branch_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The branch merged from."
},
"target_branch_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The branch merged into."
},
"needs_confirmation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when nothing was done yet and the user must approve first."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
List the pathways in the org's Bland account, read live with the org's stored Bland API key.
Read-only.
Returns ``{"pathways": [{pathway_id, name, description, production_version_number}],
"error": null}``. Use during Add-Agent flows to pick which pathway to attach; the chosen
``pathway_id`` goes on the agent as ``bland_pathway_id``.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Start a re-pull of the org's knowledge bases from Bland (agents are left alone). It
overwrites Bluejay's stored copy of each knowledge base with Bland's current text and records
what changed.
Returns {status, started_at, error} straight away; the resync runs in the background and can
take a few minutes for a large library. Next, call get_bland_knowledge_base_changes with
wait_for_sync_after=started_at (and since=<start of the last knowledge test run>): each call
waits on the server for this resync to finish, so do not add your own delays. Limited to one
call a minute per org.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "\"sync_started\" once the background resync was queued."
},
"started_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "ISO 8601 time the resync started; pass it to get_bland_knowledge_base_changes as wait_for_sync_after."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "sync_bland_knowledge_bases",
"title": "Sync Bland knowledge bases",
"description": "Start a re-pull of the org's knowledge bases from Bland (agents are left alone). It\noverwrites Bluejay's stored copy of each knowledge base with Bland's current text and records\nwhat changed.\n\nReturns {status, started_at, error} straight away; the resync runs in the background and can\ntake a few minutes for a large library. Next, call get_bland_knowledge_base_changes with\nwait_for_sync_after=started_at (and since=<start of the last knowledge test run>): each call\nwaits on the server for this resync to finish, so do not add your own delays. Limited to one\ncall a minute per org.\n",
"inputSchema": {
"type": "object",
"title": "sync_bland_knowledge_basesArguments",
"properties": {}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "\"sync_started\" once the background resync was queued."
},
"started_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "ISO 8601 time the resync started; pass it to get_bland_knowledge_base_changes as wait_for_sync_after."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List the org's Bland knowledge bases whose text changed on a resync, newest first. Read-only.
After sync_bland_knowledge_bases, call this with wait_for_sync_after set to the
started_at it returned: the server holds the answer until that resync finishes (up to about
36 seconds). Pass since (ISO 8601), e.g. the start of the last knowledge test run, so
already-tested changes drop out. If sync_complete comes back false the resync is still running:
call this again with the same arguments, up to 5 calls in total (about 3 minutes), then continue
with what came back and say the resync was still running. Without wait_for_sync_after it answers
at once.
Returns {sync_complete, last_synced_at, sync_error, changes, error}. Each change is
{knowledge_base_id, name, changed_at, added, diff, truncated}: diff is a unified diff of the
document text, before -> after, and added is true for a knowledge base that is new since the
previous sync. sync_error is set when the last resync failed for some or all knowledge bases.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
since
ISO 8601 time, e.g. the start of the last knowledge test run; only changes after it are listed. Omit to list every recorded change.
Clear enough to supply this argument.
wait_for_sync_after
The started_at returned by sync_bland_knowledge_bases; the server waits up to about 36 seconds for that resync to finish before answering. Omit to answer at once.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"changes": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"diff": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Unified diff of the document text, before -> after."
},
"name": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Knowledge base name."
},
"added": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "True for a knowledge base that is new since the previous sync."
},
"truncated": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "True when the diff was cut to fit."
},
"changed_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "ISO 8601 time the change was recorded."
},
"knowledge_base_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Bluejay knowledge base id."
}
},
"description": "One knowledge base whose text changed on a resync.",
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Knowledge bases whose text changed, newest first."
},
"sync_error": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Why the last resync failed for some or all knowledge bases; null when it succeeded."
},
"sync_complete": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "False while the resync named by wait_for_sync_after is still running; call again."
},
"last_synced_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "ISO 8601 time the last knowledge base resync finished."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "get_bland_knowledge_base_changes",
"title": "Get Bland knowledge base changes",
"description": "List the org's Bland knowledge bases whose text changed on a resync, newest first. Read-only.\n\nAfter sync_bland_knowledge_bases, call this with wait_for_sync_after set to the\nstarted_at it returned: the server holds the answer until that resync finishes (up to about\n36 seconds). Pass since (ISO 8601), e.g. the start of the last knowledge test run, so\nalready-tested changes drop out. If sync_complete comes back false the resync is still running:\ncall this again with the same arguments, up to 5 calls in total (about 3 minutes), then continue\nwith what came back and say the resync was still running. Without wait_for_sync_after it answers\nat once.\n\nReturns {sync_complete, last_synced_at, sync_error, changes, error}. Each change is\n{knowledge_base_id, name, changed_at, added, diff, truncated}: diff is a unified diff of the\ndocument text, before -> after, and added is true for a knowledge base that is new since the\nprevious sync. sync_error is set when the last resync failed for some or all knowledge bases.\n",
"inputSchema": {
"type": "object",
"title": "get_bland_knowledge_base_changesArguments",
"properties": {
"since": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Since",
"default": null,
"description": "ISO 8601 time, e.g. the start of the last knowledge test run; only changes after it are listed. Omit to list every recorded change."
},
"wait_for_sync_after": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Wait For Sync After",
"default": null,
"description": "The started_at returned by sync_bland_knowledge_bases; the server waits up to about 36 seconds for that resync to finish before answering. Omit to answer at once."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"changes": {
"anyOf": [
{
"type": [
"array",
"object",
"null"
],
"items": {
"type": [
"object",
"array",
"null"
],
"properties": {
"diff": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Unified diff of the document text, before -> after."
},
"name": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Knowledge base name."
},
"added": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "True for a knowledge base that is new since the previous sync."
},
"truncated": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "True when the diff was cut to fit."
},
"changed_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "ISO 8601 time the change was recorded."
},
"knowledge_base_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Bluejay knowledge base id."
}
},
"description": "One knowledge base whose text changed on a resync.",
"additionalProperties": true
},
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Knowledge bases whose text changed, newest first."
},
"sync_error": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Why the last resync failed for some or all knowledge bases; null when it succeeded."
},
"sync_complete": {
"anyOf": [
{
"type": [
"boolean",
"integer",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "False while the resync named by wait_for_sync_after is still running; call again."
},
"last_synced_at": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "ISO 8601 time the last knowledge base resync finished."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Import every assistant and squad from the organization's connected Vapi account as Bluejay agents.
Use it to bring Vapi agents into Bluejay for testing, or to refresh them after they changed in
Vapi; follow up with list_agents to find their ids. Rate-limited to one call a minute.
Overwrites the name, prompt and stored workflow of agents already synced from Vapi; new
assistants and squads become new agents. The sync runs in the background. Without
``confirmed=true`` nothing changes: the call returns a preview to show the user, and only a
second call with ``confirmed=true`` starts the sync. Returns the sync ``status``.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
confirmed
Leave false to get a preview; set true only after the user approves overwriting agents already synced from Vapi.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The tool to call again with confirmed=true once the user approves."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "\"sync_started\" once the background sync was queued."
},
"preview": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the sync would do; relay it to the user."
},
"to_proceed": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "How to proceed after the user approves."
},
"needs_confirmation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when nothing was done yet and the user must approve first."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "sync_vapi_agents",
"title": "Sync Vapi agents",
"description": "Import every assistant and squad from the organization's connected Vapi account as Bluejay agents.\n\nUse it to bring Vapi agents into Bluejay for testing, or to refresh them after they changed in\nVapi; follow up with list_agents to find their ids. Rate-limited to one call a minute.\n\nOverwrites the name, prompt and stored workflow of agents already synced from Vapi; new\nassistants and squads become new agents. The sync runs in the background. Without\n``confirmed=true`` nothing changes: the call returns a preview to show the user, and only a\nsecond call with ``confirmed=true`` starts the sync. Returns the sync ``status``.",
"inputSchema": {
"type": "object",
"title": "sync_vapi_agentsArguments",
"properties": {
"confirmed": {
"type": "boolean",
"title": "Confirmed",
"default": false,
"description": "Leave false to get a preview; set true only after the user approves overwriting agents already synced from Vapi."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"action": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The tool to call again with confirmed=true once the user approves."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "\"sync_started\" once the background sync was queued."
},
"preview": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "What the sync would do; relay it to the user."
},
"to_proceed": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "How to proceed after the user approves."
},
"needs_confirmation": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when nothing was done yet and the user must approve first."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Create a new Bluejay squad agent that hands calls between already-synced Vapi assistants.
Use it to test several synced Vapi assistants together as one multi-assistant agent.
``member_agent_ids`` are Bluejay agent ids (from ``list_agents``) of agents synced from Vapi,
without duplicates; the first one is the squad's starting assistant. The squad is stored in
Bluejay only, not created in Vapi. Returns the new squad's ``agent_id``.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
name
Display name for the new squad agent.
Clear enough to supply this argument.
member_agent_ids
Bluejay ids (from list_agents) of agents synced from Vapi, without duplicates; the first is the squad's starting assistant.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"agent_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Bluejay id of the new squad agent; use it like any agent id."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "create_vapi_squad",
"title": "Create Vapi squad",
"description": "Create a new Bluejay squad agent that hands calls between already-synced Vapi assistants.\n\nUse it to test several synced Vapi assistants together as one multi-assistant agent.\n\n``member_agent_ids`` are Bluejay agent ids (from ``list_agents``) of agents synced from Vapi,\nwithout duplicates; the first one is the squad's starting assistant. The squad is stored in\nBluejay only, not created in Vapi. Returns the new squad's ``agent_id``.",
"inputSchema": {
"type": "object",
"title": "create_vapi_squadArguments",
"required": [
"name",
"member_agent_ids"
],
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "Display name for the new squad agent."
},
"member_agent_ids": {
"type": "array",
"items": {
"type": "integer"
},
"title": "Member Agent Ids",
"description": "Bluejay ids (from list_agents) of agents synced from Vapi, without duplicates; the first is the squad's starting assistant."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"agent_id": {
"anyOf": [
{
"type": [
"integer",
"number",
"string",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "Bluejay id of the new squad agent; use it like any agent id."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
List the tools in the organization's Vapi tool library, read live from Vapi. Read-only.
Use it to find a tool_id before attaching a tool to an assistant.
Each entry has ``id``, ``type``, ``name`` and ``description``; pass an ``id`` to
``add_vapi_assistant_tool`` to attach that tool to an assistant.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
List the tools attached to one synced Vapi assistant, excluding squad handoff tools. Read-only.
Use it to see what an assistant can call, or to find a tool_id before removing one.
``agent_id`` is the Bluejay id of a single synced assistant, not a squad agent. Each entry
has ``id``, ``type``, ``name``, ``description`` and ``source`` (``inline`` on the assistant,
or ``library`` for a shared Vapi tool).
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Bluejay id (from list_agents) of one assistant synced from Vapi, not a squad agent.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Attach a tool from the organization's Vapi tool library to one synced assistant.
``agent_id`` is the Bluejay id of a single synced assistant (not a squad); ``tool_id`` comes
from ``list_vapi_tools``. Updates Bluejay's stored copy of the assistant only; use
``push_agent_workflow`` to send the change to Vapi. Fails if the tool is already attached.
Use it to give an assistant a library tool it should be able to call. Returns status and the
attached tool.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Bluejay id (from list_agents) of one assistant synced from Vapi, not a squad agent.
Clear enough to supply this argument.
tool_id
Id of a tool in the org's Vapi tool library, from list_vapi_tools.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Detach a tool from one synced Vapi assistant. An inline tool is deleted from Bluejay's copy;
a library tool stays in the library.
``tool_id`` comes from ``list_vapi_assistant_tools`` and may be a library or inline tool.
Updates Bluejay's stored copy of the assistant only; use ``push_agent_workflow`` to send the
change to Vapi. Use it to stop an assistant from calling a tool. Returns status and the tool_id.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
agent_id
Bluejay id (from list_agents) of one assistant synced from Vapi, not a squad agent.
Clear enough to supply this argument.
tool_id
Id of a tool attached to the assistant, from list_vapi_assistant_tools; library or inline.
{
"name": "remove_vapi_assistant_tool",
"title": "Remove Vapi assistant tool",
"description": "Detach a tool from one synced Vapi assistant. An inline tool is deleted from Bluejay's copy;\na library tool stays in the library.\n\n``tool_id`` comes from ``list_vapi_assistant_tools`` and may be a library or inline tool.\nUpdates Bluejay's stored copy of the assistant only; use ``push_agent_workflow`` to send the\nchange to Vapi. Use it to stop an assistant from calling a tool. Returns status and the tool_id.",
"inputSchema": {
"type": "object",
"title": "remove_vapi_assistant_toolArguments",
"required": [
"agent_id",
"tool_id"
],
"properties": {
"tool_id": {
"type": "string",
"title": "Tool Id",
"description": "Id of a tool attached to the assistant, from list_vapi_assistant_tools; library or inline."
},
"agent_id": {
"type": "string",
"title": "Agent Id",
"description": "Bluejay id (from list_agents) of one assistant synced from Vapi, not a squad agent."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "\"ok\" when the tool was detached."
},
"tool_id": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The tool_id you passed."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
List the organization's connected GitHub accounts via GET /v1/ci/connections. Read-only.
Also lists GitLab and Azure DevOps connections. Returns ``connections``, each with its
id (the connection_id create_ci_trigger needs), provider, account_login, revoked flag and
workspace. An empty list means GitHub is not connected: call get_github_install_url and
return that link to the user.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
Align the title with the capability actually described by this tool.
Description99/100
Get the link that connects GitHub or GitLab.
GitHub uses GET /v1/ci/github/install-url and GitLab uses GET /v1/ci/gitlab/authorize-url.
Connecting needs one browser click by the user, so return the link to them; it
cannot be completed from here. Getting the link changes nothing; the connection is
created only when the user finishes in the browser, after which list_ci_connections
shows it.
Returns ``url``: the install (GitHub) or authorize (GitLab) link.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Input documentation gives an agent enough context to populate the arguments.
return_path
App path to send the user back to afterwards, such as the simulation page they started from (must start with /). Defaults to the app's home page.
Clear enough to supply this argument.
provider
Which service to connect: github (the default) or gitlab.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The link for the user to open in a browser to install the GitHub App or authorize GitLab. Signed for your organization and workspace."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "get_github_install_url",
"title": "Get Git provider connect link",
"description": "Get the link that connects GitHub or GitLab.\n\nGitHub uses GET /v1/ci/github/install-url and GitLab uses GET /v1/ci/gitlab/authorize-url.\nConnecting needs one browser click by the user, so return the link to them; it\ncannot be completed from here. Getting the link changes nothing; the connection is\ncreated only when the user finishes in the browser, after which list_ci_connections\nshows it.\n\nReturns ``url``: the install (GitHub) or authorize (GitLab) link.\n",
"inputSchema": {
"type": "object",
"title": "get_github_install_urlArguments",
"properties": {
"provider": {
"type": "string",
"title": "Provider",
"default": "github",
"description": "Which service to connect: github (the default) or gitlab."
},
"return_path": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Return Path",
"default": null,
"description": "App path to send the user back to afterwards, such as the simulation page they started from (must start with /). Defaults to the app's home page."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"url": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The link for the user to open in a browser to install the GitHub App or authorize GitLab. Signed for your organization and workspace."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
List CI triggers via GET /v1/ci/triggers. Read-only.
Returns ``triggers``; each carries its id, ci_connection_id, simulation_id, repository
(owner/name), environment, min_score, endpoint_template, preview_host_suffix,
bypass_header_name, enabled and has_bypass_header (the header value is never
returned). If the user has no GitHub connection, call get_github_install_url and
return that link.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
simulation_id
Only triggers that run this simulation: its id from list_simulations. Omit for all.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Run a simulation on every successful GitHub deployment via POST /v1/ci/triggers.
Creates a trigger: whenever the repository deploys successfully to ``environment``,
Bluejay runs the simulation (against the preview when endpoint_template is set), which
places calls and spends credits each time, and posts the score back to the commit as a
check that passes at min_score. One trigger per simulation, repository and environment.
GitLab and Azure DevOps connections also get a webhook registered on the project.
Needs a GitHub connection: if list_ci_connections is empty, call
get_github_install_url and return that link instead.
Returns the stored trigger: its ``id`` (for update_ci_trigger and delete_ci_trigger),
simulation_id, ci_connection_id, repository, environment, min_score, endpoint_template,
preview_host_suffix, bypass_header_name, has_bypass_header and enabled.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Input documentation gives an agent enough context to populate the arguments.
simulation_id
The simulation to run on each deployment: its id from list_simulations.
Clear enough to supply this argument.
connection_id
The Git connection to watch through: id from list_ci_connections. It must be in the simulation's workspace.
Clear enough to supply this argument.
repository
The repository to watch, as owner/name (the project path on GitLab). The connection must have access to it.
Clear enough to supply this argument.
environment
Exact name of the deployment environment that fires the trigger, such as Production or Preview. For Azure DevOps, the branch.
Clear enough to supply this argument.
min_score
Pass mark for the commit check: the run's score out of 100 must reach it.
Clear enough to supply this argument.
endpoint_template
Where the agent under test lives for a preview deployment, e.g. https://{environment_url_host}/api/agent. Placeholders: {environment_url}, {environment_url_host}, {sha}, {short_sha}, {pr_number}, {environment}. Omit to run the saved agent as-is.
Clear enough to supply this argument.
preview_host_suffix
Domain the rendered preview host must end with, such as vercel.app. Required when endpoint_template uses {environment_url} or {environment_url_host}.
Clear enough to supply this argument.
bypass_header_name
Header name that lets Bluejay through a protected preview, such as x-vercel-protection-bypass. Give it with bypass_header_value.
Clear enough to supply this argument.
bypass_header_value
Secret value for the bypass header. Stored encrypted and never returned. Give it with bypass_header_name.
Clear enough to supply this argument.
enabled
False to save the trigger without letting it fire yet.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Change a CI trigger via PATCH /v1/ci/triggers/{trigger_id}. Only given fields change.
At least one field is required. New values overwrite the stored ones with no history and
apply from the next deployment; an empty string clears endpoint_template,
preview_host_suffix or the bypass header. On GitLab and Azure DevOps, moving the trigger
to another repository (or Azure branch) swaps the webhook registered on the provider.
Returns the updated trigger: id, simulation_id, ci_connection_id, repository,
environment, min_score, endpoint_template, preview_host_suffix, bypass_header_name,
has_bypass_header and enabled.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
trigger_id
The CI trigger's id (a UUID) from list_ci_triggers or create_ci_trigger.
Clear enough to supply this argument.
repository
New repository to watch, as owner/name. Omit to keep the current one.
Clear enough to supply this argument.
environment
New deployment environment name (for Azure DevOps, the branch). Omit to keep the current one.
Clear enough to supply this argument.
min_score
New pass mark for the commit check, out of 100. Omit to keep the current one.
Clear enough to supply this argument.
endpoint_template
New preview endpoint. Where the agent under test lives for a preview deployment, e.g. https://{environment_url_host}/api/agent. Placeholders: {environment_url}, {environment_url_host}, {sha}, {short_sha}, {pr_number}, {environment}. Null or an empty string clears it; omit to keep it.
Clear enough to supply this argument.
preview_host_suffix
Domain the rendered preview host must end with, such as vercel.app. Required when endpoint_template uses {environment_url} or {environment_url_host}. Null or an empty string clears it; omit to keep it.
Clear enough to supply this argument.
bypass_header_name
Header name that lets Bluejay through a protected preview, such as x-vercel-protection-bypass. Renaming it needs bypass_header_value again; empty strings for both clear the header.
Clear enough to supply this argument.
bypass_header_value
Secret value for the bypass header. Stored encrypted and never returned. Omit to keep the stored value.
Clear enough to supply this argument.
enabled
False to pause the trigger without deleting it, true to resume. Omit to keep the current state.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Delete a CI trigger via DELETE /v1/ci/triggers/{trigger_id}.
Permanent: the trigger is removed (no Recently Deleted copy), any webhook it registered
on GitLab or Azure DevOps is removed, and deployments stop running the simulation. The
simulation itself is not touched. To pause instead, use update_ci_trigger with
enabled=false. Confirm with the user before calling. Returns ``deleted`` and
``trigger_id``.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
trigger_id
The CI trigger's id (a UUID) from list_ci_triggers or create_ci_trigger.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the trigger was deleted."
},
"trigger_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The id of the deleted trigger."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "delete_ci_trigger",
"title": "Delete CI trigger",
"description": "Delete a CI trigger via DELETE /v1/ci/triggers/{trigger_id}.\n\nPermanent: the trigger is removed (no Recently Deleted copy), any webhook it registered\non GitLab or Azure DevOps is removed, and deployments stop running the simulation. The\nsimulation itself is not touched. To pause instead, use update_ci_trigger with\nenabled=false. Confirm with the user before calling. Returns ``deleted`` and\n``trigger_id``.\n",
"inputSchema": {
"type": "object",
"title": "delete_ci_triggerArguments",
"required": [
"trigger_id"
],
"properties": {
"trigger_id": {
"type": "string",
"title": "Trigger Id",
"description": "The CI trigger's id (a UUID) from list_ci_triggers or create_ci_trigger."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"deleted": {
"type": [
"boolean",
"integer",
"string",
"null"
],
"description": "True when the trigger was deleted."
},
"trigger_id": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "The id of the deleted trigger."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Query this organization's production conversations (calls). Read-only.
Filters (status, agent_ids, label_ids or label, initiation_direction,
caller_number, duration in ms, tags, conversation_ids, issue_ids, interface,
metadata, metric results) all combine.
Leave group_by unset to get conversation rows in `data`, each with
`metric_results` (how every metric scored that call), and `total` for
everything matching the filters. Set group_by for counts per group in
`breakdown` instead, which is what a "how many" question needs:
- 'metric_value' with metric_name: how a metric came out, e.g. how many calls
were scored Readback Frustration. Find exact names with list_custom_metrics.
Returns not_applicable separately and an average for numeric metrics.
- 'label': per store, location or branch.
- 'metadata' with metadata_path: per store when the code is in call metadata
rather than a label, e.g. metadata_path='restaurant_code'.
- 'day': a trend over time.
- 'status', 'agent', 'interface', 'direction', 'ended_by': as named.
To count one metric for one store over a day: label='<store>',
metric_name='<metric>', group_by='metric_value', last='1day'. To see the
conversations where a metric came out a particular way, filter with
metric_name plus metric_value (or metric_min/metric_max) and leave group_by
unset.
Counts use the human-corrected outcome wherever someone edited one, so they
match the app. Check groups_truncated: when true, more groups matched than
were returned. Open one conversation with get_conversation.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
status
Only conversations in these states, e.g. COMPLETED, NOT_EVALUATED (stored, not scored), SYSTEM_ERROR, CALL_DROPPED, NO_ANSWER.
Clear enough to supply this argument.
agent_ids
Only conversations handled by these agents: Bluejay agent ids from list_agents.
Clear enough to supply this argument.
label_ids
Only conversations under these labels (a store, location or branch): label ids (UUIDs) from list_labels. Use label instead to give the text.
Clear enough to supply this argument.
label
A label's text, such as a store or branch name, resolved to its id for you.
Clear enough to supply this argument.
initiation_direction
Only conversations started this way, from the agent's side: INBOUND, OUTBOUND.
Clear enough to supply this argument.
caller_number
Only conversations with a participant on this phone number, in E.164 form (e.g. +14155550123).
Clear enough to supply this argument.
duration_min
Only conversations at least this long, in milliseconds.
Clear enough to supply this argument.
duration_max
Only conversations at most this long, in milliseconds.
Clear enough to supply this argument.
tags
Only conversations carrying any of these tags (set when the conversation was submitted).
Clear enough to supply this argument.
conversation_ids
Only these conversations: their ids (UUIDs), e.g. the call_id evaluate returns.
Clear enough to supply this argument.
issue_ids
Only conversations linked to any of these issues: issue ids (UUIDs) from GET /v1/issues.
Clear enough to supply this argument.
interface
Only conversations over these channels: PHONE, WEB.
Clear enough to supply this argument.
metadata_path
A key in the conversation's metadata, e.g. restaurant_code. Needed for group_by=metadata and for metadata_value.
Clear enough to supply this argument.
metadata_value
Only conversations whose metadata_path key equals this value.
Clear enough to supply this argument.
metric_name
A metric's exact name (from list_custom_metrics), for group_by=metric_value or the metric_value, metric_min and metric_max filters. Or give metric_id.
Clear enough to supply this argument.
metric_id
The metric's id (UUID from list_custom_metrics), instead of metric_name.
Clear enough to supply this argument.
metric_value
Only conversations where the metric came out as one of these values, e.g. true or Readback Frustration. Needs metric_name or metric_id. This is the filter, not the grouping.
Clear enough to supply this argument.
metric_min
Numeric metrics: only conversations scoring at or above this. Needs metric_name or metric_id.
Clear enough to supply this argument.
metric_max
Numeric metrics: only conversations scoring at or below this. Needs metric_name or metric_id.
Clear enough to supply this argument.
group_by
Leave unset for conversation rows; set it for counts per group: status, agent, label, day, interface, direction, ended_by, metadata (needs metadata_path) or metric_value (needs metric_name or metric_id).
Clear enough to supply this argument.
last
How far back to look from now; all means no time limit.
Clear enough to supply this argument.
sort_order
Row order by start time: desc for newest first, asc for oldest first.
Clear enough to supply this argument.
page_size
Rows per page, up to 100. Omitted means 20.
Clear enough to supply this argument.
page
Which page of rows to return, starting at 1. Omitted means 1.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Open one production conversation: its transcript, tool calls, any error, and
how every metric scored it. Read-only.
Use this once list_conversations points at a specific conversation, to see
what actually happened on it. Set include_transcript to false when only the
metric results and outcome are needed, which makes the read cheaper.
Returns ``conversation`` (the stored record, including trace_ids for
get_trace), ``transcript``, ``tool_calls``, ``metric_results`` (value and
reasoning per metric) and error_code/error_message when it failed.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
conversation_id
The production conversation's id (a UUID): obs_conversation_id from list_conversations, or the call_id evaluate returns.
Clear enough to supply this argument.
include_transcript
False to skip the transcript when only the metric results and outcome are needed, which makes the read cheaper.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Retrieve a trace by ID via Bluejay POST /v1/traces/{trace_id}. Read-only despite the POST.
Returns the full trace with spans from the observability backend: ``status`` and a
``data`` envelope whose rows hold every span (span_id, parent_span_id, name, timestamp,
duration_nano, has_error, status, attributes, resource, events). Use it to see what the
agent did on a call, such as tool executions, LLM calls and which step failed. Open one
span with get_span.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
trace_id
The trace's id (a hex string): trace_id from list_traces, or one of a conversation's trace_ids from get_conversation.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"properties": {
"data": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The trace envelope. Spans are at data.data.results[0].rows[].data, each with span_id, parent_span_id, name, timestamp, duration_nano, has_error, kind_string, status_code_string, attributes, resource and events."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "success when the trace was read."
}
},
"additionalProperties": true
}
Original tool metadata
{
"name": "get_trace",
"title": "Get trace",
"description": "Retrieve a trace by ID via Bluejay POST /v1/traces/{trace_id}. Read-only despite the POST.\n\nReturns the full trace with spans from the observability backend: ``status`` and a\n``data`` envelope whose rows hold every span (span_id, parent_span_id, name, timestamp,\nduration_nano, has_error, status, attributes, resource, events). Use it to see what the\nagent did on a call, such as tool executions, LLM calls and which step failed. Open one\nspan with get_span.\n",
"inputSchema": {
"type": "object",
"title": "get_traceArguments",
"required": [
"trace_id"
],
"properties": {
"trace_id": {
"type": "string",
"title": "Trace Id",
"description": "The trace's id (a hex string): trace_id from list_traces, or one of a conversation's trace_ids from get_conversation."
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"data": {
"anyOf": [
{
"type": [
"object",
"array",
"null"
],
"properties": {},
"additionalProperties": true
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "The trace envelope. Spans are at data.data.results[0].rows[].data, each with span_id, parent_span_id, name, timestamp, duration_nano, has_error, kind_string, status_code_string, attributes, resource and events."
},
"error": {
"type": [
"string",
"integer",
"number",
"null"
],
"description": "Why the call failed; null when it succeeded."
},
"status": {
"anyOf": [
{
"type": [
"string",
"integer",
"number",
"null"
]
},
{
"type": [
"null"
]
},
{
"type": "null"
}
],
"description": "success when the trace was read."
}
},
"additionalProperties": true
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Retrieve a single span via Bluejay POST /v1/spans/{trace_id}/{span_id}. Read-only.
Returns that one span's fields: span_id, trace_id, parent_span_id, name, timestamp,
duration_nano, has_error, kind and status code, its attributes (e.g. a tool call's input
and output), resource attributes and events. Use it to inspect one step found in
get_trace without reading the whole trace.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
trace_id
The trace's id (a hex string): trace_id from list_traces, or one of a conversation's trace_ids from get_conversation.
Clear enough to supply this argument.
span_id
The span's span_id, as listed in get_trace's spans.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Find this organization's traces, or count them. Read-only.
Every read covers one time window: `since` and `until` are ISO timestamps,
at most 7 days apart. With neither set the window is the last 7 days; with
only since it is the 7 days after it. To look
further back (traces are kept 90 days), step since back a week at a time.
The response echoes the window it used. Filters:
- has_error: true for traces with at least one errored span, false for clean ones.
- service_name: the service of the trace's root span.
- root_span_name: the name of the trace's root span.
- error_span_name: traces where a span with this exact name errored,
e.g. 'execute_tool verify_identity'.
Leave group_by unset to get `traces`, newest first, each with trace_id,
service_name, root_span_name, start_time, duration_ms, span_count and
error_span_count, plus `total`: every trace matching the filters, not just
this page. For a single count ("how many traces errored this week"), read
`total` with limit=1.
Set group_by for counts per group instead, which is what a breakdown needs.
Each group has traces, errored_traces, spans, error_spans, avg_duration_ms
and p95_duration_ms, largest first:
- 'service_name' or 'root_span_name': as named, e.g. error rate per service.
- 'error_span_name': which spans fail most. A trace with several different
failing spans counts once in each.
- 'day' or 'hour' (UTC): a trend over time.
Filters combine with any grouping. To find what to analyze: group_by=
'error_span_name' with has_error=true, then list traces with that
error_span_name and open them with get_trace. `limit` caps traces, or groups
when group_by is set (default 20, max 100); groups_truncated is true when
more groups matched than were returned.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
has_error
True for traces with at least one errored span, false for clean ones. Omit for both.
Clear enough to supply this argument.
service_name
Only traces whose root span came from this service.
Clear enough to supply this argument.
root_span_name
Only traces whose root (top-level) span has exactly this name.
Clear enough to supply this argument.
error_span_name
Only traces where a span with exactly this name errored, e.g. 'execute_tool verify_identity'.
Clear enough to supply this argument.
since
Start of the window as an ISO timestamp, e.g. '2026-10-20T00:00:00Z'. Omitted means 7 days before until.
Clear enough to supply this argument.
until
End of the window as an ISO timestamp, no more than 7 days after since. Omitted means now, or 7 days after since when that is earlier.
Clear enough to supply this argument.
group_by
Leave unset for trace rows; set it for counts per group: service_name or root_span_name, error_span_name (a trace with several different failing spans counts once in each), or day / hour (UTC) for a trend.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Most traces to return, or most groups when group_by is set; up to 100.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Bluejay setup, tools, quality score, publishing readiness, and alternatives.
How do I add Bluejay to Claude, ChatGPT, or Cursor?
Add Bluejay to Claude, ChatGPT, or Cursor by connecting its remote MCP URL in each client's MCP settings. In Claude, add a custom connector. In ChatGPT, add an MCP app. In Cursor, add an MCP server under Settings. The MCP URL is https://api.getbluejay.ai/mcp.
Is Bluejay MCP ready for ChatGPT and Claude?
As of November 5, 2026, Bluejay scores 96/100 on Manufact's MCP publishing checklist. The scan meets ChatGPT publishing checks and meets Claude publishing checks. Passing these checks does not guarantee marketplace approval.
How clear is Bluejay's MCP tool documentation?
As of November 5, 2026, Bluejay scores 94/100 in Manufact's review of tool titles, descriptions, input and output schemas, and behavior annotations. The review covers 161 of 161 discovered tools. The quality score measures documentation clarity; runtime behavior and marketplace readiness require separate checks.
What are the best alternatives to Bluejay?
As of November 10, 2026, alternatives to Bluejay in developer-tools on the Manufact MCP leaderboard include Speko, Manufact, AgentMail, Context, and Speko.
Not your MCP?
Review any public or OAuth MCP server for protocol compatibility, tool documentation, and ChatGPT and Claude publishing readiness. No account required.