Skip to content
Appmake
Kalle API docs

Messages endpoint

One endpoint does it all: answers, conversations, reasoning, tool calls and files. You send the conversation so far, and Kalle sends back the next message.

POST/v1/messages

A conversation

The API keeps no memory between requests. Send the whole conversation each time, oldest message first, with roles that alternate between user and assistant. Use system for instructions that apply to the whole conversation.

curl https://api.kalle.build/v1/messages \
  -H "Authorization: Bearer $KALLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kalle-turbo-max",
    "max_tokens": 1024,
    "system": "You answer questions for Nordlys Coffee. Keep every answer to two sentences.",
    "messages": [
      { "role": "user", "content": "Do you ship to Norway?" },
      {
        "role": "assistant",
        "content": "Yes, we ship to Norway from our warehouse in Aarhus."
      },
      { "role": "user", "content": "How long does it take?" }
    ]
  }'

Request body

FieldTypeRequiredDescription
modelstringYeskalle-turbo, kalle-design, kalle-turbo-max, kalle-turbo-ultra or auto. See Models.
messagesarrayYesThe conversation so far. The first message has the role user.
max_tokensintegerYesThe most output tokens Kalle may write. The answer stops when it gets there.
systemstringNoInstructions for the whole conversation: tone, rules, background.
effortstringNoauto, low, medium, high, extra or max. Defaults to auto.
streambooleanNoSend the answer as server-sent events. See Streaming.
toolsarrayNoFunctions Kalle may call. See Tool use.
tool_choicestring or objectNoauto, none, any, or { "type": "tool", "name": "..." } to require one tool.
stop_sequencesarrayNoStrings that end the answer as soon as Kalle writes one of them.
metadata.user_idstringNoYour own ID for the person behind the request. Never send names or email addresses.

Message content

content is either a string or a list of blocks. A string is the same as one text block. Use blocks to mix text with files and images, or to send tool results.

JSON
{
  "role": "user",
  "content": [
    { "type": "text", "text": "Which of these two layouts is easier to scan?" },
    { "type": "image", "source": { "type": "url", "url": "https://example.com/a.png" } }
  ]
}

Response

JSON
{
  "id": "msg_01J8Z5",
  "type": "message",
  "role": "assistant",
  "model": "kalle-turbo-max",
  "content": [
    { "type": "text", "text": "Orders to Norway usually arrive in three to five working days." }
  ],
  "stop_reason": "end_turn",
  "usage": { "input_tokens": 58, "output_tokens": 14, "reasoning_tokens": 0 }
}
FieldDescription
idA unique ID for this message. Include it when you contact support.
modelThe model that answered. With auto, this is the model Kalle picked.
contentThe answer as a list of blocks: text, and tool_use when Kalle calls a tool.
stop_reasonWhy Kalle stopped writing. See below.
usageTokens you pay for: input_tokens, output_tokens and the reasoning_tokens included in the output.

Stop reasons

ValueMeaning
end_turnKalle finished the answer.
max_tokensThe answer reached max_tokens. Raise the limit or ask Kalle to continue.
stop_sequenceKalle wrote one of your stop_sequences.
tool_useKalle wants to call a tool. Run it and send the result back.

Tips for good answers

  • Put stable instructions in system and the task itself in the last user message.
  • Show Kalle an example of the output you want. One good example beats a paragraph of rules.
  • Ask for JSON in a fixed shape when your code will read the answer, and check it before you use it.
  • Keep conversations short. Every request pays for the whole history as input tokens, so summarise long threads.