The Chat API simplifies how businesses connect to various AI models across different providers. It acts as a single point of access, eliminating the need to manage multiple SDKs or APIs. This means you can interact with any supported LLM using just one SDK. In addition, the API centralizes the use of any Assistant in a single entry point.
Check the generic variables needed to use the API.
The general endpoint is as follows:
| Method |
Path |
| POST |
v1/chat/completions
(Open AI official Path)
or
/chat
or
/chat/completions
|
The v1/chat/completions, /chat/completions and /chat endpoints are supported and you can choose either endpoint. Both have the same interface (Request/Response) as the OpenAI Chat Completion API. These endpoints can be called using the OpenAI SDKs.
- Method: POST
- Path: $BASE_URL/v1/chat/completions
Headers:
- Content-Type: application/json
- Authorization: Bearer $GEAI_APITOKEN
- saia-conversation-id: $CONVERSATION_ID
The header saia-conversation-id is used differently depending on the Agentic Solution:
Agents
For Agents, the saia-conversation-id header is optional, but recommended.
In this case, the identifier is mainly used to group and optimize executions internally across requests. The Agent does not automatically recover the conversation history from this identifier alone. To preserve conversational context, you must always send the full message history in the messages array, following the OpenAI Chat Completions API pattern.
When provided, the saia-conversation-id value must be a UUID. Any UUID can be used, as long as it has not been used before.
The conversation remains valid until a new version of the Agent is published.
Flows
For Flows, the saia-conversation-id header is mandatory in every request in order to continue the same Flow execution instance. If it is not provided, the request will fail.
This identifier is used to maintain the execution state of the Flow between requests, allowing the conversation to continue from the exact step where the previous interaction ended. The value can be a UUID or any alphanumeric string. If you change this value, a new Flow conversation instance is created.
You must generate and persist the saia-conversation-id value in order to continue interacting with the same Flow instance.
Flow conversations expire after 10 minutes of inactivity and are automatically deleted.
- dsd
- parent-request-id (Optional When provided, the Chat API associates the generated Agent request with the specified parent request, enabling end-to-end request traceability and aggregated cost and execution time tracking across child requests)
- Accept-Language
For Flows, the Accept-Language header (e.g. 'es') is mandatory.
Request Body
The payload will vary depending on the selected Assistant. The general pattern is as follows:
{
"model": "string", // mandatory
"messages": [ ... ], // at least one message
"stream": boolean // optional
}
The model needs to specify an assistant_type and a specific_parameter whose format depends on that type. Its format is as follows:
"model": "saia:<assistant_type>:<specific_parameter>"
The following table describes the supported assistant_type and their corresponding specific_parameter.
| assistant_type |
Description |
specific_parameter |
Example |
| agent |
Identifies a Agent. |
agent_name1 or agent_id2 - the Agent’s name, or its Id.You may also supply the draft format <agent_name>:<version>:<revision>3 (use 0 if the version is unknown. The revision is optional and can be read in the JSON Tab of an Agent). |
1. "model": "saia:agent:InventoryChecker"
2. "model": "saia:agent:123e4567-e89b-12d3-a456-426614174000"
3. "model": "saia:agent:InventoryChecker:0:2" |
| flow |
Identifies a Flow. |
bot_id - the Bot id shown in OVERVIEW, located in the Flow Builder Side Navigation Menu.
|
"model": "saia:flow:7f9c4b28-5cde-42a1-ad23-8b7fe1f1b9e5" |
| assistant |
Identifies an Assistant API, Chat with Data Assistant and API Assistant. |
assistant_name – the name of an Assistant API, Chat with Data Assistant, or API Assistant. |
"model": "saia:assistant:DataQA" |
| search |
Identifies a RAG Assistant |
assistant_name – the name of the RAG Assistant. |
"model": "saia:search:ProductSearchRAG" |
The messages element defines the desired messages to be added. The minimal value needs to be the following, where the content details the user input.
{
"role": "string", /* user, system and may support others depending on the selected model */
"content": "string"
}
You can add additional parameters.
Note: File references must be defined using double curly braces: {{file:file_name}}. E.g.: "Summarize the following document: {{document_1}}".
Below are possible body samples.
{
"model": "saia:agent:JarvisTools",
"messages": [
{
"role": "user",
"content": "I need the price of the product to clean screens in the (here put the URL) site."
},
{
"role": "assistant",
"content": "Sure, I can look that up. Do you have the exact product name or should I search for all screen-cleaning products on the site?"
},
{
"role": "user",
"content": "Search all screen-cleaning products."
}
],
"stream": false
}
The expected result is to stream the translated content depending on the Prompt defined.
curl -X POST "$BASE_URL/v1/chat/completions" \
-H 'Authorization: Bearer $GEAI_APITOKEN' \
-H 'content-type: application/json' \
-H 'saia-conversation-id: $CONVERSATION_ID' \
-d '{
"model": "saia:agent:JarvisTools",
"messages": [
{
"role": "user",
"content": "I need the price of the product to clean screens in the (here put the URL) site."
},
{
"role": "assistant",
"content": "Sure, I can look that up. Do you have the exact product name or should I search for all screen-cleaning products on the site?"
},
{
"role": "user",
"content": "Search all screen-cleaning products."
}
],
"stream": false
}'
{
"model": "saia:assistant:translate-to-spanish", /* Using a Standard Assistant named 'translate-to-spanish' */
"messages": [
{
"role": "user",
"content": "Hi, welcome to Glob.AI OS!!"
}
],
"stream": true
}
The expected result is to stream the translated content depending on the Prompt defined.
curl -X POST "$BASE_URL/v1/chat/completions" \
-H 'Authorization: Bearer $GEAI_APITOKEN' \
-H 'content-type: application/json' \
-d '{
"model": "saia:assistant:translate-to-spanish",
"messages": [
{
"role": "user",
"content": "Hi, welcome to Glob.AI OS!!"
}
],
"stream": true
}'
{
"model": "saia:assistant:ChatWithData",
"messages": [
{
"role": "user",
"content": "How many covid deaths were there in Singapore 2022?"
}
]
}
curl -X POST "$BASE_URL/v1/chat/completions" \
-H 'Authorization: Bearer $GEAI_APITOKEN' \
-H 'content-type: application/json' \
-d '{
"model": "saia:assistant:ChatWithData",
"messages": [
{
"role": "user",
"content": "How many covid deaths were there in Singapore 2022?"
}
],
"stream": false
}'
If the request is processed successfully, the response is returned in JSON format, which includes two key components: the query, represented by key = “query”, and the result of the execution, accessible through key = “dataSet”.
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\"query\":{\"id\":\"db7c1e09-c059-4b96-9847-f174b1af6974\",\"name\":\"CovidDeathsInSingapore2022\",\"description\":\"Covid Deaths In Singapore2022\",\"expression\":\"Query CovidDeathsInSingapore2022 [OutputType='Table', Paging='False']\\r\\n{\\r\\n\\tSum(NewDeaths) [Name='Element01']\\r\\n\\t#filters\\r\\n\\t\\tCountryISO = 'SG'\\r\\n\\t\\tYear(Date) = 2022\\r\\n\\t#end\\r\\n}\",\"removeDuplicates\":false,\"outputType\":\"Table\",\"paging\":false},\"dataSet\":{\"id\":\"3dc46b4b-700a-42d2-8cd0-34669979c590\",\"pageNumber\":1,\"totalPages\":1,\"totalRows\":1,\"metadata\":[{\"name\":\"Element01\",\"type\":\"datum\",\"caption\":\"Sum of New Deaths\",\"dataType\":\"number\"}],\"data\":[{\"Element01\":\"386\"}]}}"
}
}
{
"model": "saia:assistant:test-openapi-weather-assistant",
"stream": false,
"messages": [
{
"role": "user",
"content": "weather in madrid"
}
]
}
curl -X POST "$BASE_URL/v1/chat/completions" \
-H 'Authorization: Bearer $GEAI_APITOKEN' \
-H 'content-type: application/json' \
-d '{
"model": "saia:assistant:test-openapi-weather-assistant",
"messages": [
{
"role": "user",
"content": "weather in madrid"
}
],
"stream": false
}'
{
"threadId": "uuid_as_string", /* conversation identifier (optional) */
"model": "saia:search:Default", /* Using the Default RAG Assistant */
"messages": [
{
"role": "user",
"content": "Summarize the features of Glob.AI OS"
}
],
"stream": true
}
The expected result is to query the Default RAG Assistant and stream a reply once the sources are obtained.
curl -X POST "$BASE_URL/v1/chat/completions" \
-H 'Authorization: Bearer $GEAI_APITOKEN' \
-H 'content-type: application/json' \
-d '{
"model": "saia:search:Default",
"messages": [
{
"role": "user",
"content": "Summarize the features of Glob.AI OS"
}
],
"stream": true
}'
More information: RAG samples with Chat API
{
"model": "saia:flow:87507723-3e3b-47f6-a1d0-aa53370c71d2", /* Where 87507723-3e3b-47f6-a1d0-aa53370c71d2 is the bot_id*/
"messages": [
{
"role": "user",
"content": "Question for flow"
}
]
}
curl -X POST "$BASE_URL/v1/chat/completions" \
-H 'Authorization: Bearer $GEAI_APITOKEN' \
-H 'content-type: application/json;charset=utf-8' \
-H 'Accept-Language: en' \
-H 'saia-conversation-id: $CONVERSATION_ID' \
-d '{
"model": "saia:flow:87507723-3e3b-47f6-a1d0-aa53370c71d2",
"messages": [
{
"role": "user",
"content": "Question for flow"
}
]
}'
In addition to interacting with Assistants, Agents, Flows, and RAG Assistants, the Chat API also allows Direct Chat with Large Language Models (LLMs).
This capability enables advanced configuration options that are not always exposed when using higher-level abstractions.
One of the main advantages of direct LLM interaction is the ability to use optional reasoning parameters, such as reasoning_effort, which provides fine-grained control over how much reasoning the model applies when generating a response.
The optional reasoning_effort parameter controls the depth of reasoning applied by supported models.
Supported values:
- "Low"
- "Medium"
- "High"
- "none" (supported starting from OpenAI GPT-5.1, to explicitly disable reasoning)
This parameter is supported by:
- OpenAI models starting from version 5
- Claude models starting from version 4.1
- Gemini models starting from version 2.0
- All corresponding reasoning-capable models from these providers
Note: When using reasoning_effort with OpenAI or Anthropic (Claude) models, the temperature must be set to 1.
cURL Sample
curl --location "$BASE_URL/v1/chat/completions" \
-H 'Authorization: Bearer $GEAI_APITOKEN'
-H 'content-type: application/json' \
-d '{
"model": "openai/gpt-5.1",
"messages": [
{
"role": "user",
"content": "Cuantas a tiene la palabra universidad, despues de traducirla a Frances"
}
],
"stream": false,
"temperature": 1,
"reasoning_effort": "low",
"max_tokens": 10000
}'
curl -X POST "$BASE_URL/v1/chat/completions" \
-H 'Authorization: Bearer $GEAI_APITOKEN' \
-H 'X-Saia-Cache-Enabled: false' \
-H 'content-type: application/json' \
-d '{
"model": "openai/gpt-4o",
"messages": [
{
"role": "system",
"content": "You are a professional Translator. Translate the user text to English. Just output one word. "
},
{
"role": "user",
"content": "Hola"
}
],
"stream": false
}'
Note that in the model parameter, you must specify the model in the format provider/nameModel.
from openai import OpenAI
api_key = "$(GEAI_APITOKEN)"
api_base = "https://api.saia.ai/v1/chat/completions"
openai = OpenAI(api_key=api_key, base_url=api_base)
completion = openai.chat.completions.create(model="gpt-4o-mini", messages=[{"role": "user", "content": "Hello world"}])
print(completion.choices[0].message.content)
const { Configuration, OpenAIApi } = require("openai");
const configuration = new Configuration({
apiKey: SAIA_APITOKEN,
basePath: "https://api.saia.ai/v1/chat/completions",
});
const openai = new OpenAIApi(configuration);
async function main() {
const chatCompletion = await openai.createChatCompletion({
model: "gpt-4o-mini",
messages: [{role: "user", content: "Hello world"}],
});
console.log(chatCompletion.data.choices[0].message);
}
main();
curl -X POST "$BASE_URL/v1/chat/completions" \
-H 'Authorization: Bearer $GEAI_APITOKEN' \
-H 'X-Saia-Cache-Enabled: false' \
-H 'content-type: application/json' \
-d '{
"model": "vertex_ai/gemini-1.5-pro-preview-0409",
"messages": [
{
"role": "system",
"content": "You are a professional Translator. Translate the user text to English. Just output one word. "
},
{
"role": "user",
"content": "Hola"
}
],
"stream": false
}'
First, you need to create an assistant with the variables, and then pass the variables when you use it.
curl --location 'https://api.saia.ai/v1/assistant'
-H 'content-type: application/json'
-H 'Authorization: Bearer $GEAI_APITOKEN'
-d '{
"type": "chat",
"name": "Test-variables",
"prompt": "You are a translator. Translate to {language}."
}'
curl --location 'https://api.saia.ai/v1/chat/completions'
-H 'Saia-Auth: $GEAI_APITOKEN'
-H 'X-Saia-Cache-Enabled: false'
-H 'content-type: application/json'
-d '{
"model": "saia:assistant:Test-variables",
"messages": [
{
"role": "user",
"content": "Hello"
}
],
"variables": [
{
"key": "language",
"value": "French"
}
],
"stream": false
}'