Overview
Query Agent
POST /api/v1/agent/query
The Query endpoint is the primary interface for interacting with Statement's AI agent. It allows you to submit natural language questions, business queries, and analytical requests against the data sources connected to your project.
The endpoint accepts a conversation history in chat format, routes the latest user message through the Statement agent router, and returns one or more generated responses.
The response format intentionally follows the OpenAI Chat Completions structure to simplify integration with existing AI clients and SDKs.
How It Works
- Your application sends a list of conversation messages.
- The final message in the conversation must be a
usermessage. - Statement analyzes the request and determines which connected services, data sources, and agents are relevant.
- The selected agents retrieve and process the required information.
- A generated response is returned along with token usage statistics and optional structured output.
Request Body
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
messages | array | Yes | Ordered conversation history. Supported roles are user and assistant. The final message must always be a user message. |
model | string | No | Optional model identifier to include in the response. If omitted, the response defaults to "default". |
agent_scope | array of strings | No | Restricts routing to specific services or agents. Useful when you want to limit the query to selected integrations. |
response_schema | object | No | JSON-schema-like definition used to request structured output instead of free-form text. |
finaliser_prompt | string | No | Additional instructions used to refine or format responses generated by delegated agents. |
conversation_id | string | No | Associates the request with a specific conversation for persistence and tracking purposes. |
Messages Format
The messages array represents the conversation context provided to the agent.
Each message contains:
| Field | Type | Description |
|---|---|---|
role | string | Message author. Supported values: user, assistant. |
content | string | The message content. |
The final message in the array must always be from the user, as this message is treated as the query to process.
Example
{
"messages": [
{
"role": "user",
"content": "What is my MRR?"
}
]
}
Basic Query
Use a simple request when asking a standalone question.
{
"messages": [
{
"role": "user",
"content": "What is my MRR?"
}
]
}
Scoped Query
You can limit agent routing to specific connected services using agent_scope.
This is useful when multiple integrations contain similar information and you want to control which data sources are used.
{
"model": "statement",
"agent_scope": ["stripe", "xero"],
"messages": [
{
"role": "user",
"content": "What is my MRR?"
}
]
}
In this example, the agent will only consider data from the Stripe and Xero integrations.
Query With Conversation History
Previous conversation messages can be included to provide context.
{
"messages": [
{
"role": "user",
"content": "hello"
},
{
"role": "assistant",
"content": "Hi, how can I help?"
},
{
"role": "user",
"content": "Compare this month's revenue with last month."
}
]
}
Including conversation history enables more natural follow-up questions and contextual responses.
Structured Output
For applications that require machine-readable responses, provide a response_schema.
When the generated output matches the schema, Statement returns both:
- A serialized JSON string inside
choices[].message.content - A parsed object inside
choices[].structured
Example Request
{
"messages": [
{
"role": "user",
"content": "Analyze this: Revenue increased by 20%, expenses by 10%."
}
],
"response_schema": {
"type": "object",
"properties": {
"summary": {
"type": "string"
},
"financial_metrics": {
"type": "object",
"properties": {
"revenue_growth": {
"type": "number"
},
"expense_growth": {
"type": "number"
}
},
"required": [
"revenue_growth",
"expense_growth"
]
},
"risk_level": {
"type": "string",
"enum": ["low", "medium", "high"]
}
},
"required": [
"summary",
"financial_metrics",
"risk_level"
]
}
}
Example Response
{
"id": "5cccf684-6547-4e1c-8d32-daf4fcbf8c24",
"object": "chat.completion",
"model": "statement",
"created": 1712345678,
"usage": {
"prompt_tokens": 48,
"completion_tokens": 85,
"total_tokens": 133,
"input_tokens": 48,
"output_tokens": 85
},
"choices": [
{
"message": {
"role": "assistant",
"content": "{\"summary\":\"Healthy growth\",\"financial_metrics\":{\"revenue_growth\":20,\"expense_growth\":10},\"risk_level\":\"low\"}"
},
"structured": {
"summary": "Healthy growth",
"financial_metrics": {
"revenue_growth": 20,
"expense_growth": 10
},
"risk_level": "low"
},
"finish_reason": "stop"
}
]
}
Response Fields
Top-Level Fields
| Field | Description |
|---|---|
id | Unique identifier for the generated completion. |
object | Response type. Currently always returns "chat.completion" for compatibility with existing clients. |
model | Echoes the requested model value or returns "default" when not provided. |
created | Unix timestamp representing when the response was generated. |
usage | Token usage information for the request and response. |
choices | List of generated response candidates. |
Usage Object
| Field | Description |
|---|---|
prompt_tokens | Number of tokens consumed by the request. |
input_tokens | Alias of prompt_tokens. |
completion_tokens | Number of tokens generated in the response. |
output_tokens | Alias of completion_tokens. |
total_tokens | Combined input and output token count. |
Choice Object
Each entry in the choices array contains:
| Field | Description |
|---|---|
message | Generated assistant response. |
structured | Parsed structured output when a matching response_schema is provided. |
finish_reason | Reason generation stopped. Typically "stop". |
Notes
- The response format is intentionally compatible with OpenAI-style chat completion APIs.
choices[].structuredis only returned when the generated output successfully matches the requested schema.- Token usage aliases (
prompt_tokens/input_tokensandcompletion_tokens/output_tokens) are provided for compatibility across different client implementations. - In rare cases,
choicesmay be empty if no usable response can be generated from the upstream agents. - Agent routing and service selection occur automatically unless restricted through
agent_scope.