MCPBundler Docs
MCPBundler Docs
Back to marketplaceGetting StartedAuthenticationTutorial - Bundle to Connected Agent
API Reference
Agent A2A Tools
Agent Channels
Agent Configuration (Staging)
Create Agent Custom ToolCreate Agent GuardrailRemove Agent System ToolDelete Agent Custom ToolDelete Agent GuardrailDiscard Staged ChangesDiff Stage Against Latest PublishedGet Stage WorkflowList Agent System ToolsList Agent Custom ToolsList Agent GuardrailsUpdate Staged Voice SettingsUpdate Staged Agent SettingsPatch Stage WorkflowRegenerate Widget Embed KeyUpdate Agent Custom ToolEnable or Configure Agent System Tool
Agent Configuration (Versions)
Agent Tools
Agents
Auth
Billing
Bundler
Bundler Tool
Bundles
Call Campaigns
Catalog
Conversations
Credentials
Deployments
Discover
Embedding
Fleet
Knowledge Bases
LLM
MCP Listings
Media
OAuth Clients
OAuth2
Observability
Organisations
Realtime
Reviews
Roadmap
SCIM
STT
Suppression
Triggers
TTS
Users
Utils
Voices
Webhooks
Workflows
API ReferenceAgent Configuration (Staging)

Update Staged Agent Settings

PATCH
/v1/agents/{agent_id}/stage/agent

Update this agent's staged (not necessarily published) prompt, LLM provider binding, conversation storage, evaluation, widget, and custom-variable settings. Reflects unpublished staged state - see GET /agents/{agent_id}/versions/latest for what's actually live.

Authorization

OAuth2AuthorizationCodeBearer
AuthorizationBearer <token>

In: header

Path Parameters

agent_id*Agent Id
Formatuuid

Query Parameters

verify_locally?Verify Locally
Defaulttrue

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

The Versioned-surface subset of what PATCH /agents/{id} used to accept in one schema - system_prompt, first_message, llm_provider, conversation_storage_enabled, evaluation settings, widget settings, and custom_variables. Every field independently optional, same omitted-means-don't-touch contract as every other patch schema in this file. voice is deliberately not here - see PATCH /agents/{id}/stage/voice's own schema instead.

conversation_storage_enabled is the owner-facing off switch the conversation-persistence design spec's "on by default" scope decision rests on - it is the mitigation that makes storing full transcripts by default acceptable, so it has to be writable from this route.

evaluation_enabled, extraction_field_defs, and evaluation_criteria_defs are independently optional - each may be sent alone or omitted. This works because Agent.extraction_field_defs and Agent.evaluation_criteria_defs are non-nullable JSONB columns with an empty-list default: the database never distinguishes "unset" from "empty", so an omitted field here unambiguously means "don't touch it" and an explicit [] unambiguously means "clear it" - there is no third state to disambiguate, so no model_validator is needed to detect a partial submission.

widget_enabled, widget_public, widget_accent_color, widget_orb_color_1, and widget_orb_color_2 follow the same independently-optional pattern as the evaluation-settings group above - none is ambiguous between "omitted" and "cleared", since all three color columns are genuinely nullable and the two booleans default False rather than needing a distinct "unset" state. widget_allowed_domains follows the list-field pattern instead (like extraction_field_defs/evaluation_criteria_defs above): the column is a non-nullable JSONB with an empty-list default, so an omitted field here unambiguously means "don't touch it" and an explicit [] unambiguously means "clear/unrestrict it" - no validator needed. widget_style_overrides follows the same list-field pattern as widget_allowed_domains (non-nullable JSONB dict, empty-dict default - omitted means "don't touch it", {} means "reset to the widget's own built-in defaults"), with an added key-allowlist validator since this dict's keys are a styling convention shared with two renderers (see WIDGET_STYLE_OVERRIDE_KEYS above), not free-form. widget_embed_key is deliberately absent from this schema: it is never owner-supplied, only generated/rotated via its own dedicated action route (POST /agents/{agent_id}/stage/widget/regenerate-key) - an owner-chosen value would be guessable, defeating its purpose as an unguessable public identifier.

custom_variables follows the same list-field pattern as widget_allowed_domains (non-nullable JSONB dict, empty-dict default - omitted means "don't touch it", {} means "clear everything"), with an added key-grammar validator: names must be plain identifiers (letters, digits, underscore only), since a "." or "[" would be ambiguous with the {{config.name}} path syntax the value is interpolated into at workflow run time.

llm_provider binds (or rebinds) the agent's LLM provider, mirroring deployment_id's own "omitted means don't touch" semantics - there is no way to explicitly clear it back to unbound via this PATCH, matching deployment_id (an agent only ever moves from unbound to bound, or from one bound value to another, never back to unbound).

llm_credential_id picks one of the org's credentials for the bound provider explicitly; null (the default) lets resolution fall through to the org's default and then the platform's metered key. Pass an explicit null to clear an earlier choice.

See docs/superpowers/specs/2026-09-05-agent-config-versioning-design.md's API surface section: this is the "stage" half of what PATCH /agents/{id} used to do in one call, the other half (deployment_id, a2a_open, a2a_discoverable) staying on that original endpoint since neither is part of the Versioned surface.

Response Body

application/json

application/json

application/json

application/json

curl -X PATCH "https://example.com/v1/agents/497f6eca-6276-4993-bfeb-53cbbbba6f08/stage/agent" \  -H "Content-Type: application/json" \  -d '{}'
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "name": "string",  "deployment_id": "6ef0ac85-9892-4664-a2a5-58bf2af5a8a6",  "llm_provider": "string",  "llm_credential_id": "9f53723b-12ec-46a5-bdaa-fe324d964044",  "org_id": "a40f5d1f-d889-42e9-94ea-b9b33585fc6b",  "event_org_id": "38381290-8ff7-413c-a0d2-e750a21c5122",  "system_prompt": "string",  "first_message": "string",  "a2a_open": true,  "a2a_discoverable": true,  "conversation_storage_enabled": true,  "voice": {    "pipeline_mode": "string",    "language": "string",    "voice_id": "2235c634-e4db-4ad6-aa15-066fb69b1c8f",    "stt_credential_id": "eb187100-9387-457a-a988-b0410c4a2c25",    "tts_credential_id": "e0d3c1fd-2fa1-4193-a64f-4bf411783f94",    "realtime_credential_id": "0abad67d-3a88-469c-b861-de9ea624ac84",    "silence_end_call_timeout_secs": 0,    "cascade": {      "stt_provider": "string",      "stt_model": "string",      "tts_provider": "string",      "tts_model": "string",      "enable_interruptions": true,      "min_words_before_interruption": 0,      "vad_confidence": 0,      "vad_start_secs": 0,      "vad_stop_secs": 0,      "vad_min_volume": 0,      "turn_model": "string",      "eagerness": "string",      "turn_timeout_secs": 0,      "asr_keywords": [        "string"      ],      "filter_background_speech": true,      "input_audio_format": "string",      "interruption_ignore_terms": [        "string"      ],      "transcribe_on_disabled_interruptions": true    },    "s2s": {      "realtime_provider": "string",      "realtime_model": "string",      "turn_detection_type": "string",      "turn_threshold": 0,      "prefix_padding_ms": 0,      "silence_duration_ms": 0,      "eagerness": "string"    }  },  "has_workflow": false,  "state_schema": {},  "evaluation_enabled": true,  "extraction_field_defs": [    {      "name": "string",      "type": "string",      "description": "string",      "enum_values": [        "string"      ]    }  ],  "evaluation_criteria_defs": [    {      "name": "string",      "description": "string"    }  ],  "pii_redaction_enabled": true,  "widget_enabled": true,  "widget_public": true,  "widget_embed_key": "string",  "widget_accent_color": "string",  "widget_orb_color_1": "string",  "widget_orb_color_2": "string",  "widget_allowed_domains": [    "string"  ],  "widget_placement": "string",  "widget_style_overrides": {    "property1": "string",    "property2": "string"  },  "custom_variables": {    "property1": "string",    "property2": "string"  },  "max_conversation_duration_seconds": 0,  "max_duration_message": "string",  "conversation_retention_days": 0,  "store_call_audio": true,  "client_events": [    "string"  ],  "chat_mode_enabled": true,  "dtmf_enabled": true,  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z"}
{  "detail": "string",  "code": "string"}
{  "detail": "string",  "code": "string"}
{  "detail": [    {      "loc": [        "string"      ],      "msg": "string",      "type": "string"    }  ]}

Update Staged Voice Settings

Previous Page

Patch Stage Workflow

Next Page

system_prompt?string|null
first_message?string|null
llm_provider?string|null
llm_credential_id?|null
pii_redaction_enabled?boolean|null
conversation_storage_enabled?boolean|null
evaluation_enabled?boolean|null
extraction_field_defs?array<>|null
evaluation_criteria_defs?array<>|null
widget_enabled?boolean|null
widget_public?boolean|null
widget_accent_color?|null
widget_orb_color_1?|null
widget_orb_color_2?|null
widget_allowed_domains?array<string>|null
widget_placement?|null
widget_style_overrides?|null
custom_variables?|null
max_conversation_duration_seconds?|null
max_duration_message?string|null
conversation_retention_days?|null
client_events?array<string>|null
chat_mode_enabled?boolean|null
dtmf_enabled?boolean|null