Tool calling and JSON
POST
/v1/chat/completionstools, tool_choice, and response_format are passed through to the provider as-is. When the model calls a tool, finish_reason becomes tool_calls and message.tool_calls is returned in OpenAI shape. response_format: {"type":"json_object"} is passed through too.
Request
curl https://api-dev.satulink.ai/v1/chat/completions \
-H "Authorization: Bearer $SATULINK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v-4.1-flash",
"messages": [{ "role": "user", "content": "Bagaimana cuaca di Jakarta?" }],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Ambil cuaca terkini untuk satu kota",
"parameters": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
}],
"tool_choice": "auto"
}'// client dibuat seperti di bagian SDK
const completion = await client.chat.completions.create({
model: "deepseek-v-4.1-flash",
messages: [{ role: "user", content: "Bagaimana cuaca di Jakarta?" }],
tools: [
{
type: "function",
function: {
name: "get_weather",
description: "Ambil cuaca terkini untuk satu kota",
parameters: {
type: "object",
properties: { city: { type: "string" } },
required: ["city"],
},
},
},
],
tool_choice: "auto",
});
const message = completion.choices[0].message;
if (message.tool_calls) {
console.log(message.tool_calls[0].function);
}# client dibuat seperti di bagian SDK
completion = client.chat.completions.create(
model="deepseek-v-4.1-flash",
messages=[{"role": "user", "content": "Bagaimana cuaca di Jakarta?"}],
tools=[
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Ambil cuaca terkini untuk satu kota",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}
],
tool_choice="auto",
)
message = completion.choices[0].message
if message.tool_calls:
print(message.tool_calls[0].function)Still haven't found the answer? Try it directly in Playground or view the list of active models.

