Trellis Data Logo
Developers Doc

Chat Completions API

Sample requests and responses for building with the Agentaus API.

Endpoint

POST
/api/v1/chat/completions

Chat Completions

Requires headers Authorization: Bearer <token> and Content-Type: application/json. See Getting Started to obtain a token.
Body parameters
messages
Required
array
The conversation so far. See below.
stream
Optional
boolean
Stream via Server-Sent Events, or return the full payload at once. Defaults to true. See below.
tools
Optional
array
Tools available to the model. See below.
tool_choice
Optional
string / object
Controls which tools may be called; defaults to "auto" if tools is given. See below.
temperature
Optional
float
Sampling temperature — higher is more random, lower is more focused. See below.
top_p
Optional
float
Nucleus sampling, an alternative to temperature. See below.
curl -X POST https://<host>/api/v1/chat/completions \
  -H "Authorization: Bearer $AGENTAUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "messages": [{"role": "user", "content": "Hello"}], 
      "stream": false
      }'
Response
{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null,
      "message": {
        "content": "Hello! How can I assist you today?",
        "refusal": null,
        "role": "assistant",
        "tool_calls": []
      }
    }
  ],
  "created": 1781059264,
  "id": "chatcmpl-1781059264",
  "model": "agentaus",
  "object": "chat.completion",
  "usage": {
    "input_tokens": 2440,
    "output_tokens": 70
  }
}

To ground the response in your own data, add a agentaus_dataset_search entry to tools instead.

messages

An array of message objects — the conversation so far. Required on every request.
role
Typestring
Used byevery message
NotesConventionally system, user, assistant, or tool (not enforced server-side)
content
Typestring | null
Used byevery message
NotesThe message text. null on an assistant message that only carries a tool call
tool_calls
Typearray
Used byassistant
NotesThe tool call(s) that message made — echo it back unchanged in the next request
tool_call_id
Typestring
Used bytool
NotesMatches the id of the tool_calls entry this message answers
…
Type—
Used byany
NotesAny other OpenAI-style key is preserved and read back unchanged
graph LR
A["<b style='color:#9370db'>system</b><br/>once, at the start"] --> B["<b style='color:#1aa0fe'>user</b>"] --> C["<b style='color:#007f31'>assistant</b><br/>calls a tool"] --> D["<b style='color:#ff6d2f'>tool</b><br/>the result"] --> E["<b style='color:#007f31'>assistant</b><br/>final answer"]
classDef purple fill:#ececff,stroke:#9370db,color:#3d3163;
  classDef blue fill:#e0f2fe,stroke:#1aa0fe,color:#0c4a6e;
  classDef green fill:#e3fbf1,stroke:#007f31,color:#10704b;
  classDef orange fill:#fff1e6,stroke:#ff6d2f,color:#9a3f12;
  classDef gray fill:#f1f1f1,stroke:#9ca3af,color:#4b5563;
class A purple
class B blue
class C,E green
class D orange
linkStyle 0 stroke:#1aa0fe,stroke-width:2px;
  linkStyle 1 stroke:#007f31,stroke-width:2px;
  linkStyle 2 stroke:#ff6d2f,stroke-width:2px;
  linkStyle 3 stroke:#007f31,stroke-width:2px;
This endpoint is stateless — there is no session id to reuse across calls. Every request above must be sent in full, from system onward, exactly as shown — not just the newest message.
A system message is layered on top of the built-in system prompt rather than replacing it — there is no way to fully override it.
json
{
  "messages": [
    { "role": "system", "content": "You are a terse coding assistant." },
    { "role": "user", "content": "What does this function do?" },
    { "role": "assistant", "content": "It reverses a linked list in place." },
    { "role": "user", "content": "Now add a docstring." }
  ]
}

stream

Stream the response as it is generated.
true
BehaviorSent via Server-Sent Events as tokens are generated (default)
false
BehaviorThe full response is returned in a single JSON payload.

tools

The catalog of tools available to the model — built-in or custom functions you implement. Without tools, the model can only reply with text.
Three built-in tools are available:
agentaus_web_search
DescriptionSearches the web for current information using a query string. Returns up to 10 results with titles, URLs, and content snippets.
agentaus_web_fetch
DescriptionFetches and extracts the full text content of a specific URL. Designed to be used after agentaus_web_search to read a discovered page.
DescriptionGrounds the response in your own data (retrieval-augmented generation) — the server runs retrieval itself, before inference starts. See below for details.
If tools is omitted entirely, the model has access to agentaus_web_search and agentaus_web_fetch by default. agentaus_dataset_search must always be added explicitly, since it needs a dataset_ids field.
agentaus_web_search and agentaus_web_fetch are each just an object with a type field, set to the tool's name:
json
{
  "messages": [...],
  "tools": [
    {"type": "agentaus_web_fetch"}
  ],
  ...
}

Custom tools

Custom tools set type to "function" and include a function object:
type
Typestring
NotesAlways "function"
function.name
Typestring
NotesName the model uses to call this function
function.description
Typestring
NotesWhat the function does — helps the model decide when and how to call it
function.parameters
Typeobject
NotesJSON Schema describing the function's arguments — same shape as OpenAI
function.required
Typearray
NotesRequired parameter names
json
{
  "type": "function",
  "function": {
    "name": "get_exchange_rate",
    "description": "Get the exchange rate between two currencies",
    "parameters": {
      "type": "object",
      "properties": {
        "from": {"type": "string", "description": "Source currency code"},
        "to": {"type": "string", "description": "Target currency code"}
      },
      "required": ["from", "to"]
    }
  }
}
A catalog can hold more than one tool — list every function the model may call this turn:
json
{
  "messages": [
    { "role": "user", "content": "What's the weather in Sydney, and what's on my calendar today?" }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_current_weather",
        "description": "Get the current weather in a given location",
        "parameters": {
          "type": "object",
          "properties": {
            "location": { "type": "string", "description": "City and state" }
          },
          "required": ["location"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "get_calendar_events",
        "description": "List the user's calendar events for a given date",
        "parameters": {
          "type": "object",
          "properties": {
            "date": { "type": "string", "description": "ISO 8601 date, e.g. 2026-09-16" }
          },
          "required": ["date"]
        }
      }
    }
  ],
  "tool_choice": "auto",
  "stream": false
}
With tool_choice: "auto", the model decides whether to call get_current_weather, get_calendar_events, or neither — though only one tool call is returned per response (see below).
  • When the model responds with a tool call, only one tool call is returned per response.
  • Mixing built-in and custom tools in the same request is not yet supported.
Grounds the response in your own data (retrieval-augmented generation). There is no top-level dataset field — this tool entry is how you ground a response instead.
type
Typestring
NotesAlways "agentaus_dataset_search"
dataset_ids
Typearray
NotesThe dataset ids to search — the same ids returned when a dataset is created (e.g. the Managed RAG API's id field, or a dataset created via the Trellis UI)
json
{
  "messages": [...],
  "tools": [
    {
      "type": "agentaus_dataset_search",
      "dataset_ids": ["5a1f7e2c-...", "9c3d1a44-..."]
    }
  ],
  ...
}
Unlike custom tools, this entry has no function block — just type and dataset_ids. It can be combined with your own function tools in the same tools array, in any order.
Every dataset id is checked. Only one agentaus_dataset_search entry is allowed per request; a second one fails the whole request. Omit it entirely for a plain chat request with no retrieval.

tool_choice

Controls which tools the model may call. Has no effect if tools is empty or omitted.
graph TD
T["<b style='color:#1aa0fe'>tools</b><br/>catalog: A, B, C"] --> TC{tool_choice}
TC -->|"<span style='padding:1px 8px; font-weight:bold;'>auto</span>"| AUTO["model may call A, B, or C —<br/>or reply with text"]
TC -->|"<span style='padding:1px 8px; font-weight:bold;'>required</span>"| REQ["model must call<br/>one of A, B, C"]
TC -->|"<span style='padding:1px 8px; font-weight:bold;'>none</span>"| NONE["model must reply<br/>with text"]
TC -->|"<span style='padding:1px 8px; font-weight:bold;'>allowed_tools<br/>{A, B}</span>"| SUB["<b style='color:#9370db'>narrowed to A, B</b><br/>(tools ∩ allowlist)"]
SUB -->|"<span style='padding:1px 8px; font-weight:bold;'>mode: auto</span>"| SUBAUTO["may call A or B —<br/>or reply with text"]
SUB -->|"<span style='padding:1px 8px; font-weight:bold;'>mode: required</span>"| SUBREQ["must call A or B"]
classDef purple fill:#ececff,stroke:#9370db,color:#3d3163;
  classDef blue fill:#e0f2fe,stroke:#1aa0fe,color:#0c4a6e;
  classDef green fill:#e3fbf1,stroke:#007f31,color:#10704b;
  classDef orange fill:#fff1e6,stroke:#ff6d2f,color:#9a3f12;
  classDef gray fill:#f1f1f1,stroke:#9ca3af,color:#4b5563;
class T,TC blue
class AUTO,SUBAUTO green
class REQ,SUBREQ orange
class NONE gray
class SUB purple
linkStyle 0 stroke:#9370db,stroke-width:2px;
  linkStyle 1 stroke:#007f31,stroke-width:2px;
  linkStyle 2 stroke:#ff6d2f,stroke-width:2px;
  linkStyle 3 stroke:#9ca3af,stroke-width:2px;
  linkStyle 4 stroke:#9370db,stroke-width:2px;
  linkStyle 5 stroke:#007f31,stroke-width:2px;
  linkStyle 6 stroke:#ff6d2f,stroke-width:2px;
auto (default)
EffectModel decides for itself whether to reply with text or call one of the listed tools. Also the default when tool_choice is omitted and tools is non-empty.
required
EffectModel must call one of the listed tools — it cannot reply with plain text this turn.
none
EffectModel must not call any tool, even though tools were provided — forces a plain text reply.
allowed_tools
EffectObject. Narrows the model's choice to a subset of tools. mode is "auto" (may still skip calling one) or "required" (must call one of the listed subset).

required

Force a tool call even for a vague prompt, instead of letting the model reply conversationally.
json
{
  "messages": [{"role": "user", "content": "Sydney"}],
  "tools": [ /* get_current_weather, as above */ ],
  "tool_choice": "required",
  "stream": false
}

none

Keep tools on the request (e.g. because the rest of your integration always sends the same catalog) but suppress tool calls for this particular turn, forcing a plain text reply.
json
{
  "messages": [
    {"role": "user", "content": "Never mind the live lookup — just tell me in general terms what Sydney's weather is like in September."}
  ],
  "tools": [ /* get_current_weather, as above */ ],
  "tool_choice": "none",
  "stream": false
}

allowed_tools

Restricts the model to a subset of a larger catalog. Only tools present in both the allowlist and the tools array are visible to the model.
Useful when you expose many tools overall but only some are appropriate for the current step of a workflow — or when you want to vary available tools across requests without changing the tools payload, which preserves prompt cache. Constraints:
type
NotesMust be allowed_tools
mode
Notes"auto" (model may still skip calling a tool) or "required" (model must call one of the listed subset)
tools
NotesEach entry must include type and name
json
{
  "messages": [
    {"role": "user", "content": "What's the weather in Sydney, and what's on my calendar today?"}
  ],
  "tools": [
    {
      "type": "function",
      "function": { "name": "get_current_weather", "description": "...", "parameters": {} }
    },
    {
      "type": "function",
      "function": { "name": "get_calendar_events", "description": "...", "parameters": {} }
    },
    {
      "type": "function",
      "function": { "name": "send_email", "description": "...", "parameters": {} }
    }
  ],
  "tool_choice": {
    "type": "allowed_tools",
    "mode": "required",
    "tools": [
      {"type": "function", "name": "get_current_weather"},
      {"type": "function", "name": "get_calendar_events"}
    ]
  },
  "stream": false
}
Here the model must call get_current_weather and/or get_calendar_events — it cannot call send_email even though it's part of tools, and (because mode is "required") it cannot reply with plain text either. Use "mode": "auto" instead if the model should remain free to reply with text or skip calling a tool, just restricted to that narrower subset whenever it does call one.

temperature

Sampling temperature. Higher values make output more random, lower values make it more focused and deterministic. Valid range: 0–2.
0
EffectFully deterministic — the same input reliably produces the same output.
0.2
EffectLow randomness — focused, consistent completions.
0.8
EffectHigher randomness — more varied, exploratory completions.
2
EffectMaximum randomness allowed.
We generally recommend altering this or top_p — see below — but not both.

top_p

Nucleus sampling — an alternative to temperature. The model considers only the tokens comprising the top top_p probability mass. Valid range: 0–1, excluding 0.
0.1
EffectOnly the tokens comprising the top 10% probability mass are considered — very focused.
0.5
EffectOnly the tokens comprising the top 50% probability mass are considered.
1
EffectAll tokens are considered — no nucleus restriction.
We generally recommend altering this or temperature — see above — but not both.

Response

The API returns a JSON object with the following fields:
Typearray
NotesArray of completion choices (currently always one element)
created
Typeinteger
NotesUnix timestamp of when the completion was created
id
Typestring
NotesUnique completion identifier
model
Typestring
NotesModel used (e.g. agentaus)
object
Typestring
NotesAlways chat.completion
Typeobject
NotesToken usage statistics for the request

Fields

choices

The completion choices returned by the model — currently always exactly one element. Each item:
index
Typeinteger
NotesIndex of the choice
Typestring | null
NotesReason the model stopped: stop (final answer) or tool_calls (model wants to call a tool). null on intermediate streaming chunks, while the response is still being generated
logprobs
Typenull
NotesAlways null
Typeobject
NotesThe generated message
finish_reason
null — no reason yet, because generation hasn't finished; this can appear on intermediate streaming chunks (see Streaming) as well as in a non-streaming response.
stop — a normal text reply:
json
"choices": [
  {
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "...",
      "refusal": null,
      "tool_calls": []
    },
    "logprobs": null,
    "finish_reason": "stop"
  }
]
tool_calls — the model wants to call a tool instead of replying with text.:
json
"choices": [
  {
    "message": {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "id": "call_abc123",
          "type": "function",
          "function": {
            "name": "get_current_weather",
            "arguments": "{\"location\": \"Sydney, NSW\"}"
          }
        }
      ]
    },
    "finish_reason": "tool_calls"
  }
]
message
The message generated by the model for this choice.
content
Typestring | null
NotesThe generated text, or null when finish_reason is tool_calls
refusal
Typestring | null
NotesRefusal message, if the model declined to answer
role
Typestring
NotesAlways assistant
Typearray
NotesPresent only when finish_reason is tool_calls
tool_calls
The tool call(s) the model wants to make, present only when finish_reason is tool_calls. Each item:
id
Typestring
NotesIdentifier of the tool call
type
Typestring
NotesAlways function
Typeobject
NotesThe function the model wants to call
function
The function the model wants to call, as part of a tool call.
name
Typestring
NotesName of the function to call
arguments
Typestring
NotesArguments as a JSON-encoded string

usage

Token usage statistics for this request.
input_tokens
Typeinteger
NotesTotal number of input tokens processed
output_tokens
Typeinteger
NotesNumber of tokens generated in the response
json
"usage": { "input_tokens": 14, "output_tokens": 21 }

Streaming

The stream body parameter picks between two very different response shapes:
graph LR
R["Request"] -->|"<span style='padding:1px 8px; font-weight:bold;'>stream: false</span>"| J["<b style='color:#007f31'>Single JSON object</b><br/>200 OK, all at once"]
R -->|"<span style='padding:1px 8px; font-weight:bold;'>stream: true (default)</span>"| S["<b style='color:#1aa0fe'>SSE chunks</b><br/>tokens/deltas as they're generated"] --> D["data: [DONE]"]
classDef purple fill:#ececff,stroke:#9370db,color:#3d3163;
  classDef blue fill:#e0f2fe,stroke:#1aa0fe,color:#0c4a6e;
  classDef green fill:#e3fbf1,stroke:#007f31,color:#10704b;
  classDef orange fill:#fff1e6,stroke:#ff6d2f,color:#9a3f12;
  classDef gray fill:#f1f1f1,stroke:#9ca3af,color:#4b5563;
class R purple
class J green
class S blue
class D gray
linkStyle 0 stroke:#007f31,stroke-width:2px;
  linkStyle 1 stroke:#1aa0fe,stroke-width:2px;

stream: false

A single JSON object, 200 OK, all at once. The fields documented below (choices, message, tool_calls, usage) describe this shape:
json
{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null,
      "message": {
        "content": "Hello! How can I assist you today?",
        "refusal": null,
        "role": "assistant",
        "tool_calls": []
      }
    }
  ],
  "created": 1781059264,
  "id": "chatcmpl-1781059264",
  "model": "agentaus",
  "object": "chat.completion",
  "usage": {
    "input_tokens": 2440,
    "output_tokens": 70
  }
}

stream: true (default)

200 OK with Content-Type: text/event-stream. Each event is a data: <json> line, ending in a literal data: [DONE] — identical in shape to OpenAI's streaming chat completions.
Text reply — streamed incrementally as delta.content chunks, a few tokens at a time:
text
data: {"id":"resp_42","object":"chat.completion.chunk","created":1757930000,"model":"agentaus","choices":[{"text":"A ","index":0,"delta":{"role":"assistant","content":"A "},"finish_reason":null}]}

data: {"id":"resp_42","object":"chat.completion.chunk","created":1757930001,"model":"agentaus","choices":[{"text":"function ","index":0,"delta":{"role":"assistant","content":"function "},"finish_reason":null}]}

... (more chunks) ...

data: {"id":"resp_42","object":"chat.completion.chunk","created":1757930005,"model":"agentaus","choices":[{"delta":{},"finish_reason":"stop","index":0}],"usage":null}

data: {"id":"resp_42","object":"chat.completion.chunk","created":1757930005,"model":"agentaus","choices":[],"usage":{"input_tokens":14,"output_tokens":21}}

data: [DONE]
Tool call — sent as a single delta.tool_calls chunk once the model has decided to call a tool, not streamed token-by-token like text is:
text
data: {"id":"resp_42","object":"chat.completion.chunk","created":1757930000,"model":"agentaus","choices":[{"index":0,"delta":{"role":"assistant","tool_calls":[{"index":0,"id":"call_abc123","type":"function","function":{"name":"get_current_weather","arguments":"{\"location\": \"Sydney, NSW\"}"}}]},"finish_reason":"tool_calls"}]}

data: [DONE]
Error mid-stream — if something fails after streaming has already started (so a normal HTTP error response is no longer possible), the error is sent as an SSE event instead of an HTTP status:
text
data: {"error": {"message": "..."}}

data: [DONE]
An error that occurs before the stream starts is returned as a normal HTTP error response instead — see Errors below.

Errors

Error responses use this envelope — check status and data, not HTTP status alone if your client library doesn't surface it directly:
json
{
  "status": 400,
  "message": "The request cannot be fulfilled",
  "data": { "messages": ["is required"] }
}
400
Bad Request
When it happensA request field is missing or invalid — e.g. messages omitted, temperature out of range, malformed tool_choice, a dataset_ids entry naming a dataset you can't access, or more than one agentaus_dataset_search entry. data holds details of the invalid field(s).
401
Unauthorized
When it happensMissing, invalid, or expired bearer token.
402
Payment Required
When it happensYour account has insufficient balance/credits for this request.
403
Forbidden
When it happensYour account isn't a member of the requested tenant, or lacks permission to use its Agentaus API.
429
Too Many Requests
When it happensYou're sending requests faster than your account's rate limit allows.
500
Internal Server Error
When it happensUnexpected server error.
503
Service Unavailable
When it happensA backing service is temporarily unavailable — retry.