Build with the API
Chat completions with tools and images
POST /v1/chat/completions sends a conversation to a chat model and returns its reply. The same chat is available as POST /v1/messages, in the form Anthropic's clients send and read: use whichever your code already uses, with the same key, models and prices. Each example below is one call, shown for every client; the choice you make is remembered across the documentation.
curl https://sven.swedishembedded.com/v1/chat/completions \
-H "Authorization: Bearer $SVEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "MODEL_ID",
"messages": [
{"role": "system", "content": "You answer in one sentence."},
{"role": "user", "content": "Why is the sky blue?"}
],
"temperature": 0.2,
"max_tokens": 200
}'
Parameters#
| Parameter | Notes |
|---|---|
model | Required. A chat model's id from the model list. |
messages | Required, at least one. Each has a role (system or developer for instructions, user, assistant or tool) and content. |
temperature | 0 to 2. |
top_p | 0 to 1. |
max_tokens, max_completion_tokens | The most tokens to write. When both are sent, max_completion_tokens wins. When neither is, a default applies. |
stop | A string or a list of strings at which the model stops. |
tools, tool_choice | Functions the model may call. See below. |
response_format | The shape the reply must take: {"type": "json_object"} for any JSON object, or {"type": "json_schema", "json_schema": {"name", "strict", "schema"}} for JSON following your schema (at most 64 KB). Models that take it list response_format or structured_outputs in supported_parameters. |
stream, stream_options | Receive the reply as it is written. See Streaming. |
n | Only 1 is accepted. |
A parameter the model does not accept is refused with a 400 whose error.param names it. The model's supported_parameters in the model list says what it takes.
Tool calling#
Describe functions in tools and the model may answer with a call to one instead of text. You run the function and send its result back in a tool message that carries the call's tool_call_id. Only models whose capabilities include tools take them.
curl https://sven.swedishembedded.com/v1/chat/completions \
-H "Authorization: Bearer $SVEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "MODEL_ID",
"messages": [{"role": "user", "content": "What is the weather in Malmo?"}],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "The current weather in a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
}
],
"tool_choice": "auto"
}'
Images in a message#
A user message can carry images next to text, for a model whose input modalities include images. The content is a list of parts, and an image is base64 text, never a link: sven does not fetch addresses. BASE64_IMAGE below stands for the picture's base64 text; the Python and Node tabs of the first form show how to make it.
Send a picture at the size a model reads it: models scale an image down to about 1,568 px on its longest edge before they look at it, so anything larger costs upload time and is never seen. A screenshot or diagram reads best as PNG, a photo as JPEG. A conversation carries its images with every call; send again only the ones the next answer needs.
curl https://sven.swedishembedded.com/v1/chat/completions \
-H "Authorization: Bearer $SVEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "MODEL_ID",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "What is in this picture?"},
{
"type": "image_url",
"image_url": {"url": "data:image/png;base64,BASE64_IMAGE"}
}
]
}
]
}'
Images may be PNG, JPEG, GIF or WebP, up to 10 MiB each and 20 per request. A model that does not take images refuses the request and names itself.
The response#
The reply is a chat completion object: choices[0].message holds the text or the tool calls, finish_reason says why it ended (stop, length, tool_calls or content_filter), and usage has prompt_tokens, completion_tokens and total_tokens, which is what you are charged for. Every response carries an x-request-id header.
A conversation longer than the model can take is refused with a 400 on messages.
Using Anthropic's client#
An existing Anthropic client works against POST /v1/messages unchanged, with the same key. Its base URL is the API's address without /v1, because the client adds /v1/messages itself; the Anthropic tabs above show it. The models and prices are those of the chat completions route.
x-api-keycarries the key (a bearer token works too).anthropic-versionis required,2026-10-21or2023-06-01. Anthropic's clients send it for you. Any other version is refused with a400.- The
anthropic-betaheader is not supported and is refused with a400. modelandmax_tokensare required. You can also sendsystem,stop_sequences,tools,tool_choiceandstream, and under2023-06-01alsotemperature(0 to 1),top_pandtop_k. Under2026-10-21those three, and a text block of yours that carriescitations, are refused with a400, as that version removed them. Images are sent as base64 sources inside a message's content, never as links.- Extended thinking cannot be switched on: omit
thinkingor send{"type": "disabled"}. - Errors come back as an object with
type: "error"and anerrorholding atypeand amessage. The statuses match those of the rest of the API, with two differences: a model that is temporarily unavailable is529withoverloaded_error, and an account that cannot cover the call is402withbilling_error. See Errors.