Send a message and read the assistant reply from data.message. Include history when the next turn should use earlier conversation.
Request fields
Conversation history
The API is stateless. Mansa does not store your threads. Send earlier turns in history and keep the latest user text in message.
curl --fail-with-body "$MANSA_API_BASE_URL/v1/chat" \
-H "Authorization: Bearer $MANSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "What is its official language?",
"history": [
{
"role": "user",
"content": "What is the capital of Ghana?"
},
{
"role": "assistant",
"content": "The capital of Ghana is Accra."
}
],
"tools": []
}'Output
{
"context": "ok",
"data": {
"id": "d77e9719-5792-482c-af24-238c1a283b57",
"message": "The official language of Ghana is English."
},
"meta": {
"usage": {
"promptTokens": 24,
"completionTokens": 9,
"totalTokens": 33
},
"finishReason": "stop",
"model": "mansa-ai",
"latencyMs": 1966
}
}Store the full thread in your database
Persist every user and assistant turn in your own database, keyed by a thread or session id. The history field is only the subset you send on each request — not your source of truth.
On each turn:
- Read the full thread from your database.
- Build the API payload from a recent window (see below).
- After a successful response, append the new user message and assistant reply to your database.
Do not append turns to your database or to the next request's history when a request fails. See Errors that affect history.
Long conversations: recent window and summary
When a thread grows beyond the API limits, keep the complete transcript in your database and send only what fits:
- Take the most recent turns that fit within 50 history entries and 48,000 total history characters.
- For older context the model still needs, add a short summary in
system(for example, "Earlier in this thread the user asked about X; the assistant explained Y."). - Refresh or replace the summary when the user switches topic or when facts in the summary may be stale.
Summary text in system bills as input tokens. See Pricing.
curl --fail-with-body "$MANSA_API_BASE_URL/v1/chat" \
-H "Authorization: Bearer $MANSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "What did we decide about the venue?",
"system": "Earlier in this thread: the user planned a team offsite in Accra and asked about venues near the airport.",
"history": [
{
"role": "user",
"content": "Find venues near Kotoka International Airport."
},
{
"role": "assistant",
"content": "Three options near the airport are Labadi Beach Hotel, Airport View Hotel, and Accra Marriott Hotel."
}
],
"tools": []
}'Output
{
"context": "ok",
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "You chose **Accra Marriott Hotel** for the offsite because it is closest to the airport and has meeting rooms on site."
},
"meta": {
"usage": {
"promptTokens": 58,
"completionTokens": 28,
"totalTokens": 86
},
"finishReason": "stop",
"model": "mansa-ai",
"latencyMs": 1420
}
}Manage context and avoid stale replies
If the user starts a new topic but you still send old turns, replies may stay anchored on the old subject. Clear history (or start a new thread id) when the topic changes.
For a single chat window, trim history to the active topic only. Use one in-flight request per thread unless you tag each response with a request id and ignore late answers from older requests.
# Store turns in your database between requests.
# Send only the recent window in history on each call.
curl --fail-with-body "$MANSA_API_BASE_URL/v1/chat" \
-H "Authorization: Bearer $MANSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "How many regions has he visited?",
"history": [
{
"role": "user",
"content": "Did President Mahama plan a Resetting Ghana tour?"
},
{
"role": "assistant",
"content": "Yes. Reports describe a Resetting Ghana tour with regional stops."
}
],
"response_language": "english",
"tools": []
}'Output
{
"context": "ok",
"data": {
"id": "f4e3d2c1-b0a9-8765-4321-fedcba987654",
"message": "President Mahama's Resetting Ghana tour included visits to several regions."
},
"meta": {
"usage": {
"promptTokens": 42,
"completionTokens": 18,
"totalTokens": 60
},
"finishReason": "stop",
"model": "mansa-ai",
"latencyMs": 980
}
}Web tools on follow-ups
Short follow-ups like "what about its economy?" work best when history carries the subject. For live web sources on a pronoun follow-up, rewrite message into a self-contained question instead of relying on search alone.
Replace data.sources on every successful response. Do not carry forward sources from an earlier turn.
Errors that affect history
Never leave a user turn in history without a matching assistant reply. Orphan user turns can misalign later answers.
For streaming, treat partial chunks as display-only until the stream completes with data: [DONE] and no terminal error event. See Errors.
System instructions
Use system when you need a stable role or style for that request. A concise summary of older thread context also belongs in system, not in history.
curl --fail-with-body "$MANSA_API_BASE_URL/v1/chat" \
-H "Authorization: Bearer $MANSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "Name one dish to try in Accra.",
"system": "You are a concise travel assistant. Reply in one short sentence.",
"tools": []
}'Output
{
"context": "ok",
"data": {
"id": "72b3a552-6055-476e-be5b-e13813afe455",
"message": "Try jollof rice with fried plantains and grilled tilapia for a classic Accra street-food experience."
},
"meta": {
"usage": {
"promptTokens": 24,
"completionTokens": 65,
"totalTokens": 89
},
"finishReason": "stop",
"model": "mansa-ai",
"latencyMs": 811
}
}Multilingual responses
Chat accepts supported languages in the same request. With response_language: "source", the reply follows the latest message. Set english when you need English output.
Supported languages include English, Swahili, Hausa, Yoruba, French, Arabic, Portuguese, Twi, Igbo, and Zulu. Coverage can vary — test the languages your application needs.
curl --fail-with-body "$MANSA_API_BASE_URL/v1/chat" \
-H "Authorization: Bearer $MANSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "Habari za asubuhi. Ni nini mji mkuu wa Kenya?",
"response_language": "source",
"tools": []
}'Output
{
"context": "ok",
"data": {
"id": "bd58f3c2-4e89-486e-a830-58fd89f7db94",
"message": "Habari za asubuhi! Mji mkuu wa Kenya ni **Nairobi**. Nairobi pia ndio mji mkubwa zaidi nchini Kenya, na unaojulikana kama kitovu cha biashara, utawala, na utamaduni."
},
"meta": {
"usage": {
"promptTokens": 12,
"completionTokens": 461,
"totalTokens": 473
},
"finishReason": "stop",
"model": "mansa-ai",
"latencyMs": 14150
}
}Web tools
Set tools to [{"type":"web_search"}], [{"type":"web_fetch"}], or auto. Use [] when the reply must not access the web. Enabling a tool does not guarantee it will be used.
Streaming
Set stream to true and read text/event-stream. Append content from stream_chunk events until data: [DONE].
curl --no-buffer --fail-with-body "$MANSA_API_BASE_URL/v1/chat" \
-H "Authorization: Bearer $MANSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "Say hello in one short sentence.",
"tools": [],
"stream": true
}'Output
data: {"context":"stream_chunk","id":"7ee9e70f-b3ae-4802-bc1e-0c2ef7c1e497","content":"Hello there!"}
data: {"context":"stream_chunk","id":"7ee9e70f-b3ae-4802-bc1e-0c2ef7c1e497","meta":{"usage":{"promptTokens":8,"completionTokens":62,"totalTokens":70},"finishReason":"stop","model":"mansa-ai","latencyMs":606}}
data: [DONE]Response
Read the reply from data.message. When web sources are available, data.sources contains their URLs. A finishReason of length means the response reached max_tokens.
Billing
Chat is billed by input and output tokens. Input includes message, history, and caller system text. max_tokens is a response limit, not a flat charge. Longer history and summaries increase input cost. See Pricing.