Skip to content
GitHub

Response Components API

Set how often an agent answers with an interactive response component, over the agents REST API.


On this page

An agent can attach a response component to its reply in the Web SDK — a clickable confirm, a select list, or a formatted card. How often it reaches for one is a per-agent setting, responseComponents.frequency, carried on the public agents API.

Authenticate with a bearer API key, created under Settings → API Keys. Full request and response schemas live in the OpenAPI reference.

Endpoints#

EndpointPurpose
GET /v1/agents?ids=…Read the level for several agents. ids is required — a comma-separated list of up to 100 agent ids; omitting it is a 400
GET /v1/agents/{id}Read the level for one agent
PATCH /v1/agents/{id}Set the level

PATCH requires an API key with the manageAgents capability. Reads do not. That capability is the public-surface equivalent of the dashboard's feature:write permission, which is a per-user dashboard permission with no representation on an API key — so do not look for feature:write on a key, and do not expect a key to inherit the dashboard permissions of whoever created it. Keys are issued from the dashboard by an organization admin or owner.

POST /v1/agents does not accept responseComponents; the field is ignored rather than rejected, so a create carrying it still returns 201 with the dial at off. Create the agent, then set the dial with a follow-up PATCH.

Reading the level#

responseComponents is a required field on every agent payload — GET /v1/agents, GET /v1/agents/{id}, and the create and update responses. Abridged to the relevant fields:

{
  "id": "0f2b7d1e-9c34-4a5b-8f61-2ad0c5e7b913",
  "name": "Support agent",
  "longTermMemory": { "enabled": true },
  "responseComponents": { "frequency": "medium" }
}

An agent that has never had the dial set reads back as "off".

Setting the level#

curl -X PATCH https://api.runbear.io/v1/agents/0f2b7d1e-9c34-4a5b-8f61-2ad0c5e7b913 \
  -H "Authorization: Bearer $RUNBEAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"responseComponents":{"frequency":"medium"}}'

The response is the full agent, with responseComponents.frequency reflecting the write.

The levels#

LevelWhat it does
offThe agent is not offered the components at all on this channel. This is the default, and the value an unset or unrecognized stored level reads back as.
lowOffer buttons sparingly: only when the next reply is unambiguously one of a few concrete options, and at most once per turn.
mediumThe balanced setting. Offer buttons whenever the next reply is plausibly one of a few concrete options; answer in prose when the question is genuinely open-ended.
highOffer buttons at every reasonable opportunity — whenever the turn would end in a question, a list of suggestions, or any choice the visitor could type back.

What else has to be true#

The dial is necessary but not sufficient. A non-off level produces components in the Web SDK only when all of these also hold:

  • The beta is enabled for your organization. Response components are a closed beta; Runbear turns them on per organization. Until then a non-off level stores and reads back correctly and produces nothing.
  • The agent's Choice Buttons setting is on. Turning it off withdraws interactive prompts on every surface, and it is checked before this dial. An agent opted out there never gains web components, whatever the level says.
  • Your widget is on an SDK release that carries the renderers. On an earlier release the component arrives on the wire and the widget shows its prose fallback. Your Runbear contact confirms the minimum version when they enable the beta.

Which components the agent can reach for also depends on its type. anthropic and openai-responses agents can emit all three; a claude-agent-sdk agent emits confirm and select only, and never a card, at any level. gemini emits none, which is why the dial refuses to leave off there at all.

Because the beta's per-organization switch and the Choice Buttons setting are separate, a GET returning "frequency": "high" is a statement about this agent's configuration, not a promise that a visitor will see a button.

Errors#

StatusBodyCause
400{ "error": "bad_request", … }frequency is not one of off, low, medium, high.
422{ "error": "unsupported_for_agent_type", "message": … }A non-off level was written to an agent whose type cannot emit response components.

The 422 is terminal for that agent: the dial is only meaningful on a type that supports the components, and no retry changes that. On the public agents API this is refused for gemini, which registers no tools at all. The agent types that predate this API — perplexity, upstage and openai-assistant — also cannot emit components, but they are not exposed on /v1/agents and so cannot be reached to be refused.

Writing "off" is accepted on every type, so an agent can always be returned to the default even if it could not be given a level in the first place.

  • Web SDK — the rendering contract: the wire event, the props shapes, and what a click does
  • Choice buttons — the dashboard switch this dial sits behind
  • API keys — creating the key that carries manageAgents
  • OpenAPI reference — exact schemas for the agents endpoints