The Chat API is available on Premium and Enterprise plans.
Endpoint
The endpoint has the following structure:Overview
The Chat API enables real-time streaming conversations with Cube’s AI agents. This endpoint allows applications to integrate AI-powered analytics conversations directly into their user interfaces.Authentication
All users created using this API are ephemeral by default and will be removed after
sessionSettings.ephemeralTtlSeconds (1 week by default). If users need to be persisted, pass isEphemeral: false in sessionSettings. Ephemeral users are guaranteed to not live longer than sessionSettings.ephemeralTtlSeconds.- API key authentication — pass a Cube API key in the
Authorizationheader. - Cube token authentication — pass your deployment’s own Cube token (JWT) in the
X-Cube-Auth-Tokenheader.
API key authentication
Pass your API key directly to the Chat API endpoint. The session will be created automatically based on theexternalId provided:
Cube token authentication
Cube token authentication for the Chat API is disabled by default. You can
enable it in your deployment settings: Settings → Configuration →
Use Cube authentication for Chat and embedding APIs.
check_auth implementation.
This is useful for headless embedding: your
application issues a single kind of token, and the same token works for both
data queries and AI-powered conversations.
Pass the token in the X-Cube-Auth-Token header instead of the
Authorization header:
externalId(required) — unique identifier for the external user. Normalized to lowercase, so ids that differ only in casing map to the same user. WhenexternalIdis not present, the standard JWTsubclaim is used instead.scope(required) — an array of scopes that must includechat.email(optional) — email address to store on the provisioned external user.
The
chat scope is asserted on the token’s resolved security context.
With the default JWT authentication the security context is simply the
token payload, so including scope: ["chat"] in the token is enough. If
your deployment uses a custom check_auth
implementation that rewrites the security context, make sure the resolved
security context carries scope: ["chat"] for tokens that should be
allowed to use the Chat API.- The external user is identified by the
externalId(orsub) claim, and their security context is resolved from the token claims — so you don’t need to pass identity fields insessionSettings; users are provisioned automatically from the token. - The agent queries the deployment with the same token you sent, so row-level security and any other security-context-based access controls apply to the conversation exactly as they apply to your direct API queries.
- Tokens that are invalid for the deployment, miss the
externalId(orsub) claim, or don’t carry thechatscope are rejected.
When using
internalId, the user must already exist in Cube Cloud. You cannot specify roles, groups, userAttributes, or securityContext with internalId — the internal user’s existing permissions are used instead.User Attributes
User attributes allow you to pass contextual information about the user to the AI agent. This enables personalized responses and automatic data filtering based on user permissions through row-level security policies.User attributes must first be configured in your Cube admin panel before they can be used. See the User Attributes documentation for setup instructions.
externalId(optional): Unique identifier for the external user. EitherexternalIdorinternalIdshould be provided.internalId(optional): Email address of an internal Cube Cloud user. The user must already exist. EitherexternalIdorinternalIdshould be provided.email(optional): User’s email addressuserAttributes(optional): Array of key-value pairs containing user metadata. Only available withexternalId.
- Row-Level Security: Automatically filter data based on user attributes through access policies
- Personalized Responses: AI agent can tailor responses based on user context
- Access Control: Restrict data access to only what the user should see
- Filter sales data by user’s assigned territory
- Show only customers from user’s city
- Limit financial data based on user’s department
- Personalize dashboards by user role
userAttributes.{attributeName} for use in access policies.
Endpoint Reference
POSTCopy the complete Chat API URL from your agent settings (Chat API URL field) in Admin → Agents.
Path Parameters
cloudRegion(string): The cloud region identifier (e.g., “gcp-us-central1”)accountName(string, required): The account identifier (e.g., “acme”). It is in your account URL, e.g. https://acme.cubecloud.devagentId(string, required): The AI agent identifier (e.g., “1”). You can find it in Admin → Agents → Click on Agent row in the table.
Request Body
input(string): User message or query to send to the AI agent, e.g. “What is our revenue last month?”. If omitted, returns current state of thread with providedchatId.chatId(string): Chat thread ID. If omitted, a new thread is created automatically. If provided, it should match the previously returnedchatIdfrom a message with id__cutoff__.messageId(string): Client-provided identifier for the user message. Must match the format<timestamp>-message(a 13+ digit Unix timestamp in milliseconds followed by-message), e.g.1717500000000-message. Used to make requests idempotent — see Idempotency.sessionSettings(object, required for API key authentication; ignored with Cube token authentication, where identity comes from the token claims): Session configuration for the userexternalId(string): Unique identifier for the external user. EitherexternalIdorinternalIdshould be provided.internalId(string): Email address of an internal Cube Cloud user. The user must already exist. EitherexternalIdorinternalIdshould be provided.email(string): User’s email addressuserAttributes(array): Array of{name, value}pairs for row-level security. Not allowed withinternalId.groups(string[]): Array of group names for user. Not allowed withinternalId.securityContext(object): Custom security context object passed to Cube queries. Not allowed withinternalId.
activeBranchName(string): Name of a development branch to use for the chat session. When provided, queries run against the specified branch instead of the main branch.isDefaultBranch(boolean): Whether the specifiedactiveBranchNameis the default branch. Defaults totruewhenactiveBranchNameis not set, andfalsewhen it is. Set totrueif passing the main/production branch name.
Idempotency
You can pass a client-providedmessageId in the request body to make Chat API
requests idempotent. The value must match the format <timestamp>-message,
where <timestamp> is a Unix timestamp in milliseconds with 13 or more digits,
e.g. 1717500000000-message.
If a request with the same messageId arrives while a stream for that message
is still active on the thread, the API resubscribes the new request to the
existing stream instead of starting a new one. This is useful for retrying
after a dropped connection: the client can replay the same request and resume
receiving the stream from the current point without producing duplicate
assistant messages.
Without a matching messageId, sending a new message to a thread that is
already streaming returns a Streaming for thread is in progress error.
Response Format
The API returns streaming JSON responses. Each line contains a separate JSON object representing a chat message or state update.
Response Fields
id(string): Unique message identifierrole(string): Message sender:"user"or"assistant"content(string): Message content (streamed incrementally for assistant messages)thinking(string): Agent’s internal reasoning process (visible in development mode)toolCall(object): Information about tool calls made by the agent during processingname(string): Name of the tool being calledinput(string): JSON string containing the input parameters for the toolresult(string): JSON string containing the tool’s response (only present when tool call is complete)
graphPath(string[]): Identifies which node of the agent graph produced this message. For example,["cube_data_analyst_agent"]for the main agent node or["cube_data_analyst_agent", "tools"]for tool calls. Messages withgraphPath[0] === "final"represent the final consolidated answer.isDelta(boolean): Whether this is an incremental content updateisInProcess(boolean): Whether the message is still being generatedsort(number): Message ordering sequence numberstate(object): Current streaming state information
Response Examples
The API returns a series of JSON objects, each on a separate line. Here’s what a typical conversation looks like: Initial State Message:Getting the Final Assistant Message
When consuming the streamed NDJSON response, you may want to extract only the final answer that the agent produced — for example, to display it in a chat UI or to store it for later reference. The agent graph emits many intermediate messages (thinking steps, tool calls, incremental deltas, state updates, etc.). To isolate the final answer, filter the streamed messages using these two conditions:role === "assistant"— only assistant messages.graphPath[0] === "final"andgraphPath.length <= 2— messages produced by the “final” node of the agent graph.
The
graphPath property is an array of strings that traces the path through
the agent’s internal execution graph. Intermediate nodes (e.g.,
["cube_data_analyst_agent"] or ["cube_data_analyst_agent", "tools"])
produce working messages, while the "final" node emits the consolidated
response that should be presented to the user.Tool Calls
When the AI agent performs actions like querying data or searching metadata, tool calls are included in the response stream. These provide transparency into the agent’s reasoning and data retrieval process.All tool results are returned as JSON strings within the
toolCall.result field, not as parsed JSON objects. You must parse these strings to access the structured data.toolCall.input- JSON string containing tool parameterstoolCall.result- JSON string containing tool response (only present whenisInProcess: false)- Both input and result contain escaped JSON that requires parsing
- Results may contain nested JSON structures, especially for complex data queries
- Error responses are also JSON strings with consistent error formatting
cubeMeta
Searches cube metadata and schema information ThecubeMeta tool returns cube schema information as a JSON string. When successful, the result contains:
searchQuery(string): Search query for data model
cubes(array): Available cube/view definitions with memberssearchQuery(string): The original search query used
cubeSqlApi
Executes SQL queries against cube data ThecubeSqlApi tool executes SQL queries and returns data with metadata. The input typically includes additional context fields:
sqlQuery(string): The SQL query to executequeryTitle(string): Human-readable title for the querydescription(string): Detailed description of what the query doesuserRequest(string): Original user request that triggered this querymemoryId(string): Reference to previous analysis or contextvegaSpec(string): Vega-Lite v5 visualization specification as JSON string (when visualization is generated)
sqlQuery(string): The executed SQL queryqueryTitle(string): Human-readable title for the querydescription(string): Detailed description of what the query doesuserRequest(string): Original user request that triggered this queryschema(array): Column definitions withnameandcolumn_typefor each fielddata(array): Query result rows as arrays of valuestotalRows(number): Total number of rows returneduuid(string): Unique identifier for this query resultvegaSpec(string): Vega-Lite v5 visualization specification as JSON string (when visualization is generated)
Loading all Results
If you need to load all the data, you need to usesqlQuery from the results to make a call to the Cube API.
Displaying charts
ThecubeSqlApi tool call returns vegaSpec that can be used to display data.
Note that it doesn’t contain data. You need to use the data from toolCall.result.data.
Styling charts
When rendering Vega charts, you can apply custom styling to match the look and feel of your application. This includes adjusting colors, fonts, and other visual elements. Here’s a configuration example that mimics Cube’s default styling:Error Handling
When a tool encounters an error, the result field contains structured error information as a JSON string: Standard Error Format: When an error occurs, theresult property of the toolCall will contain an error property.
Abort Endpoint
The Abort endpoint stops an in-progress chat stream. This is useful when the user cancels a request or navigates away while the agent is still generating a response.Endpoint
POST/stream-chat-state
with /abort.
Authentication
Supports the same authentication methods as the Chat API: an API key or, when enabled for your deployment, a Cube token.Request Body
chatId(string, required): The chat thread ID to abort. This must match thechatIdof an active or recently completed chat session.sessionSettings(object): Same session settings asstream-chat-stateto authenticate the request.externalId(string): Unique identifier for the external user.
Response
204 No Content: Chat streaming was aborted successfully.403 Forbidden: The authenticated user does not own the specified chat thread.404 Not Found: The specifiedchatIddoes not exist.
A successful cancellation is indicated solely by the
204 No Content status —
the response has no body. The aborted stream-chat-state request itself does
not fail with an HTTP error: the streaming response already returned 200 OK
when the stream opened, so treat the abort endpoint’s 204 as the
confirmation that the stream was aborted.Code Examples
Code Examples
Error Handling
- 204 No Content: (Abort endpoint only) Chat streaming was aborted successfully.
- 400 Bad Request: Invalid request body or parameters. Check required fields and data types.
- Authentication errors: Returned as a JSON-RPC error object in an HTTP 200
response. Verify your API key is correct and has the necessary permissions.
For Cube token authentication, verify the token is valid for the agent’s
deployment, identifies a user via
externalId(orsub), and carries thechatscope. - 403 Forbidden: (Abort endpoint only) The authenticated user does not own the specified chat thread.
- 404 Not Found: Agent, tenant, or chat thread not found. Verify the Chat API URL from your agent settings and the
chatId. - 500 Internal Server Error: Server processing error. Contact support if the issue persists.