Response-Agent API
The Response-Agent endpoint is used to communicate with your agent.
Use it to send a message and it returns the agent's response.
Endpoint
Authentication
Every request must include your API key as a Bearer token in the Authorization header:
Authorization header
You can generate and manage keys on the API Keys page.
Request Body
Send a JSON body with the following fields. agent_id, session_id, client_prompt,
environment, and client_platform are required; the rest are optional.
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | Yes | Which agent should handle the request. See format. |
session_id | string | Yes | The ID of the session this message belongs to. |
client_prompt | string | Yes | The message to the agent. |
environment | string | Yes | Which build of your agent to run: test or live. See values. |
client_platform | string | Yes | Where the request comes from. See values. |
reset_session | string | No | Whether to delete the message history or continue. See values. |
extra_context | object | No | Additional context for the agent to consider. See extra_context. |
Field Details
agent_id
The identifier of the agent that should answer. It's always the letters pa- followed by
exactly six digits—for example pa-123456. You'll find your agent's ID in
Agent Studio.
environment
Selects which of your agent's two builds the request runs—matching the environment toggle in Agent Studio.
live— Load the agent build from your live environment.test— Load the agent build from your test environment.
client_platform
Identifies the platform that sends the request. It accepts exactly two values, and no others.
bubble— The request comes from a Bubble app.unlisted— The request comes from anywhere else. Use this for a custom backend, a script, or any platform not named above.
Different platforms hold a request open for different lengths of time, so this field sets how
long your agent is allowed to run. bubble gets 2 minutes because Bubble's API Connector
closes the connection at its own limit no matter what we do; unlisted gets 10 minutes.
Pick the value that matches where the request is actually sent from. A Bubble app that declares
unlisted does not get a longer call—Bubble still cuts the connection, and the extra time is
spent on an answer nobody receives.
reset_session
Controls whether the agent remembers the exchanges leading up to this message.
yes— This is a new session. Delete the message history and start fresh.no— Continue the current session. Preserve the message history so the agent keeps its context.
extra_context
An optional object containing extra information you'd like the agent to take into account when responding. Use it to pass details your agent cannot infer from the prompt alone—for example:
- The caller's name — e.g.
"John Smith" - The caller's location — e.g.
"Boulder, Colorado"
Anything you include here becomes context the agent can use to tailor its answer, so it can greet the caller by name or give location-aware responses.
Response Body
A successful call comes back as 200 OK with a JSON body. Every response carries all three
fields below, whether or not your agent has a
Structured Response shape.
200 OK — a text answer
200 OK — a structured answer
| Field | Type | Description |
|---|---|---|
agent_response | string or null | The agent's reply as text. null when a structured response was provided. |
agent_structured_response | object or null | The agent's reply as an object of the shape you defined. null when one was not provided. |
agent_structured_response_status | string | provided, unavailable, or not_configured. |
Branch on agent_structured_response_status, not on whether a field is null:
| Status | Meaning | What to do |
|---|---|---|
provided | Your agent has a shape, and it answered with an object of that shape. | Read agent_structured_response. |
unavailable | Your agent has a shape, but it could not produce the object this time. | Show agent_response, then retry or alert. |
not_configured | Your agent has no shape in the environment you called. | Read agent_response. |
unavailablemeans the agent could not produce the object this time. The call is still billed.agent_responseholds a sentence you can show to the user. A retry is reasonable.not_configuredmeans the agent has no shape in the environment you called. A shape is part of the agent build, and each environment has its own build. If you expected a structured answer—the most common cause is a shape that you deployed to Test but not to Live.
Every agent without a shape returns not_configured and keeps its text in agent_response, so a
client that reads only agent_response keeps working.
Execution limit
Every request has a time limit. The limit depends on the client_platform you send:
client_platform | Limit |
|---|---|
bubble | 2 minutes |
unlisted | 10 minutes |
A request that reaches its limit is terminated, and a stock agent_response is returned. For an
agent with a Structured Response shape, the status is
unavailable. The call is still billed.
The bubble limit is lower because Bubble's API Connector closes the connection itself. See
client_platform.
Errors
Check the body for an error key
A long-running request can return 200 OK and still carry an error. Read the body on every
response—do not branch on the status code alone. See
Long-running requests for why.
Errors come back in one of two body shapes, depending on how far into the gateway the request got. The status code tells the two shapes apart.
Requests that make it past the edge come back as JSON with an error string:
Error body
Requests rejected at the edge come back as
RFC 9457 application/problem+json instead.
Problem body
| Status | Body | Meaning |
|---|---|---|
400 | problem+json | The request body is malformed—a missing or misspelled field, or an agent_id that is not in pa-000000 form. |
401 | problem+json | The Authorization header is missing or the key is not valid. |
429 | problem+json | You have gone over your requests-per-minute limit. See Rate Limits. |
402 | error | You are out of credits. Top up on the Credits page—see Pricing. |
4xx | error | Your agent rejected the request. The error string is the agent's own explanation. |
500 | error | Something failed on our side. Nothing is charged for a 500. |
503 | error | The service is temporarily busy. Wait for the time in Retry-After, then send the request again. Nothing is charged for a 503. |
A 402 carries an extra "code": "INSUFFICIENT_CREDITS" field so you can branch on it without
matching the message text, and a 429 and a 503 carry a Retry-After header.
Long-running requests
Most calls answer in a few seconds and behave exactly as the table above describes. A call that runs longer—around 20 seconds or more—switches to a different delivery mode automatically. You do not request it and you cannot turn it off.
In that mode we start the response before your agent has finished.
We do this so the API connection stays open and intermediaries do not disconnect it. Two things follow.
The status code is sent early, so it is always 200. It is committed before the outcome is
known, and it cannot be changed afterwards. A failure on a long-running call therefore arrives
as 200 OK with an error body:
200 OK — but an error
If a long request fails because the service is busy, the response has status 200 and the same
error message as a 503. It has no Retry-After header, so wait about a minute before you
send the request again.
So treat the presence of an error key as the error signal, and read the
response fields only when error is absent. This is the safe rule for short calls as well, which is why the caution above
states it for every response.
The different delivery mode mentioned above does not make an API call run longer; it only keeps the API connection open while your agent works.