Mansa Platform Docs

Chat

Create an assistant response from a message and optional conversation history.

POST/v1/chat

Request example

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 the capital of Ghana?",
  "tools": []
}'

Output

{
  "context": "ok",
  "data": {
    "id": "e2e5c130-69c7-46c0-8608-42277dd5db84",
    "message": "The capital of Ghana is **Accra**. It is the largest city in the country and serves as the political, economic, and cultural center of Ghana, located along the Atlantic coast in the southern part of the country."
  },
  "meta": {
    "usage": {
      "promptTokens": 8,
      "completionTokens": 103,
      "totalTokens": 111
    },
    "finishReason": "stop",
    "model": "mansa-ai",
    "latencyMs": 2785
  }
}

Send a message and read the assistant reply from data.message. Include history when the next turn should use earlier conversation.

Request fields

FieldTypeDefaultDescription
messagestringRequiredLatest user message, up to 8,000 characters
historyarray[]Up to 50 earlier user or assistant turns, up to 48,000 characters total, each turn up to 4,000 characters
systemstringOmittedInstructions for your application's assistant behavior, up to 8,000 characters
temperaturenumber0.7Sampling temperature from 0 to 2
max_tokensinteger4096Maximum response length, from 64 to 8,192 tokens
response_languagestringsourcesource follows the latest message; english requests English
toolsarray or autoOmittedEnable web tools, both with auto, or neither with []
streambooleanfalseReturn server-sent events when true

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:

  1. Read the full thread from your database.
  2. Build the API payload from a recent window (see below).
  3. 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:

  1. Take the most recent turns that fit within 50 history entries and 48,000 total history characters.
  2. 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.").
  3. 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

What you sendWhat happens
history: []The model treats message as a fresh turn.
Non-empty historyThe model uses those turns to resolve pronouns and continue the thread.

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

StatusTypical contextUpdate your stored history?
400invalid_requestNo — fix the request body
402insufficient_creditNo
429rate_limitedNo — backoff and retry
502service_unavailable, response_incomplete, translation_failedNo — retry where appropriate
503service_unavailableNo — reduce concurrency and retry
200 (JSON) or completed streamokYes — append user and assistant turns

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.