Chat completions
POST
https://app.sulus.ai/api/v1/chat/completions
Send a chat-completions request to an agent
Authentication
Send a bearer token created on your dashboard's Developer page:
Authorization: Bearer <YOUR_API_KEY>
Request body
model
string
Optional
Nullable
Model id from GET /models. Omit for the default.
Validation:
sometimes|nullable|string|max:255Stored in
ai_chats.modelmessages
array
Required
Conversation turns. Must contain at least one user-role message.
Validation:
required|array|min:1messages.*.role
string
Required
Turn role.
Validation:
required|string|in:system,user,assistantStored in
ai_chat_messages.rolemessages.*.content
string
Required
Turn text, max 20,000 characters.
Validation:
required|string|max:20000Stored in
ai_chat_messages.contentagent
string
Optional
Nullable
Sulus extension: which agent answers. Defaults to your most recently active agent.
Validation:
sometimes|nullable|string|max:64Stored in
ai_projects.uidchat
string
Optional
Nullable
Sulus extension: continue this existing thread statefully.
Validation:
sometimes|nullable|string|max:64Stored in
ai_chats.uidstream
boolean
Optional
Default: false
Must be false or omitted — streaming is not supported.
Validation:
sometimes|booleanErrors
| Status | Meaning | Body |
|---|---|---|
400 |
invalid_request_error — streaming requested, or no user-role message | {"error":{"message":"Streaming is not supported yet. Set \"stream\": false.","type":"invalid_request_error","code":400}} |
404 |
invalid_request_error — agent or chat not found | |
402 |
insufficient_quota — prepaid token balance exhausted | |
500 |
api_error — the assistant could not generate a response | |
401 |
Missing or invalid bearer token | |
403 |
Feature ai_chat not enabled for the account | |
422 |
Validation failed | {"message":"…","errors":{"field":["…"]}} |
Notes
- Errors use the chat-completions envelope {"error":{"message","type","code"}} — not the plain {"message"} envelope.
- Stateless mode (no chat field) creates a fresh thread seeded with your messages; system-role turns are stored as user-visible preamble.
- Passing both agent and chat continues that thread under that agent; passing agent alone (no chat) starts a fresh stateless thread.
- model ids are account-specific; "sulus-chat-1" here is a placeholder — call GET /models for the real ids available to your account.
curl --request POST \
--url https://app.sulus.ai/api/v1/chat/completions \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data '{
"model": "sulus-chat-1",
"messages": [
{"role": "system", "content": "You are speaking with a returning customer."},
{"role": "user", "content": "What are your opening hours?"}
],
"agent": "a1b2c3d4-0000-4000-8000-000000000001",
"chat": "b2c3d4e5-0000-4000-8000-000000000002",
"stream": false
}'
import requests
url = "https://app.sulus.ai/api/v1/chat/completions"
headers = {"Authorization": "Bearer <YOUR_API_KEY>"}
payload = {
"model": "sulus-chat-1",
"messages": [
{"role": "system", "content": "You are speaking with a returning customer."},
{"role": "user", "content": "What are your opening hours?"}
],
"agent": "a1b2c3d4-0000-4000-8000-000000000001",
"chat": "b2c3d4e5-0000-4000-8000-000000000002",
"stream": false
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
url := "https://app.sulus.ai/api/v1/chat/completions"
payload := strings.NewReader(`{
"model": "sulus-chat-1",
"messages": [
{"role": "system", "content": "You are speaking with a returning customer."},
{"role": "user", "content": "What are your opening hours?"}
],
"agent": "a1b2c3d4-0000-4000-8000-000000000001",
"chat": "b2c3d4e5-0000-4000-8000-000000000002",
"stream": false
}`)
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <YOUR_API_KEY>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}
Response
200
{
"id": "chatcmpl-7f3a9c2e-1111-4222-8333-000000000010",
"object": "chat.completion",
"created": 1769800000,
"model": "sulus-chat-1",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "We're open Monday to Friday, 9am to 6pm Eastern, and Saturday 10am to 2pm."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 210,
"completion_tokens": 88,
"total_tokens": 298
},
"sulus": {
"agent": "a1b2c3d4-0000-4000-8000-000000000001",
"chat": "b2c3d4e5-0000-4000-8000-000000000002",
"tools_used": []
}
}
Response — POST
/chat/completions
200
{
"id": "chatcmpl-7f3a9c2e-1111-4222-8333-000000000010",
"object": "chat.completion",
"created": 1769800000,
"model": "sulus-chat-1",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "We're open Monday to Friday, 9am to 6pm Eastern, and Saturday 10am to 2pm."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 210,
"completion_tokens": 88,
"total_tokens": 298
},
"sulus": {
"agent": "a1b2c3d4-0000-4000-8000-000000000001",
"chat": "b2c3d4e5-0000-4000-8000-000000000002",
"tools_used": []
}
}