Chat
POST /v1/chat — send messages and receive assistant text through the assigned route.
POST /v1/chat is the primary text endpoint for multi-turn conversations.
Request
curl https://ai.latentkit.com/v1/chat \
-H "Authorization: Bearer $LATENTKIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "system", "content": "You are a concise assistant." },
{ "role": "user", "content": "Explain LatentKit in one sentence." }
],
"response_profile": "balanced",
"max_tokens": 200,
"temperature": 0.2
}'Common fields
| Field | Description |
|---|---|
messages | OpenAI-style role/content array (required) |
max_tokens | Output token limit (default 1000) |
temperature | Sampling temperature, 0.0–2.0 (default 0.7) |
response_profile | fast, balanced, or thinking when route allows overrides |
purpose | Tenant-declared routing label that selects which published route handles the request. Optional; defaults to unset, which uses the app's assigned route. An unknown or unconfigured purpose falls back to that same default instead of failing — see Purposes. Also accepted as the X-LK-Purpose header. |
seed | Reproducibility seed when the selected provider supports it — see Determinism |
stream | Set true for SSE streaming — see Streaming |
tools / tool_choice / parallel_tool_calls | Tool calling — see Tool calling |
response_format | Structured output, e.g. {"type": "json_object"} when the route model supports JSON mode |
stop | Stop sequence string or array |
top_p / top_k | Nucleus / top-k sampling when supported |
presence_penalty / frequency_penalty | Repetition controls when supported |
n | Number of completions when supported |
modalities | Output modalities, e.g. ["text", "audio"] for audio output |
metadata / user | Pass-through request annotations |
Provider-specific sampling fields are forwarded when the winning provider supports them and dropped otherwise, so one request body works across the whole route.
Multimodal messages
Message content can be an array of OpenAI-style content parts. Image parts automatically add the vision capability requirement, so only vision-capable route models are eligible:
{
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "What is in this image?" },
{ "type": "image_url", "image_url": { "url": "https://example.com/photo.jpg" } }
]
}
]
}For a simpler single-image API, see Vision.
Route rules
Do not send model or provider. Tool-heavy, JSON-mode, vision, audio, and video workloads may require credits or BYOK even when plain chat is within a Free managed allowance.
Response
{
"id": "req_abc123",
"provider": "anthropic",
"model": "claude-sonnet-4-6",
"policy_version_id": "pol_v_xyz789",
"content": "LatentKit routes your AI requests to the right provider automatically.",
"tool_calls": [],
"usage": { "input_tokens": 28, "output_tokens": 14, "total_tokens": 42 },
"cost_usd": 0.000294,
"lk_requested_purpose": null,
"lk_applied_purpose": null,
"lk_purpose_source": "default_no_purpose",
"determinism": { "seed_requested": null, "seed_honored": false, "provider_supports_seed": true }
}Successful chat responses always include id, provider, model, policy_version_id, usage, determinism, and the lk_*_purpose fields at the top level. See Response contract for the full shape.
SDK
const response = await client.chat.create({
messages: [{ role: 'user', content: 'Hello' }],
response_profile: 'balanced',
});Add purpose to route the request through a different published route — purpose picks
the route, response_profile picks how much effort it spends. Read the labels your
workspace configured from /v1/me rather than
hardcoding one:
const result = await client.chat.create({
messages: [{ role: 'user', content: 'Extract the invoice total as JSON.' }],
purpose: 'extraction',
response_profile: 'deep',
});
// null means the app's default route ran, not the extraction route.
if (result.lk_applied_purpose !== 'extraction') {
console.warn('purpose degraded:', result.lk_purpose_source);
}Errors
Errors return a structured envelope with error.code and error.category. Tool-required requests can return TOOL_CALL_NOT_PRODUCED when a model returns text instead of a tool call. See Error reference.