Chat completions.
Endpoint chat yang sepenuhnya kompatibel dengan OpenAI. Streaming, vision, tool calling, batching, dan anotasi respons Anoman semuanya dalam satu route.
Contoh cepat
Buat permintaan pertama Anda
from openai import OpenAI
client = OpenAI(base_url="https://api.anoman.io/v1", api_key="anm-sk-...")
response = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of Indonesia?"},
],
temperature=0.7,
max_tokens=200,
)
print(response.choices[0].message.content)Bentuk permintaan identik dengan /v1/chat/completions milik OpenAI. Satu-satunya perbedaan adalah base URL.
Body permintaan
Parameter
| Field | Tipe | Wajib? | Deskripsi |
|---|---|---|---|
| model | string | ✓ | Slug model dari katalog kami. Lihat GET /v1/models. |
| messages | array | ✓ | Riwayat percakapan. Setiap item memiliki role (system / user / assistant / tool) dan content (string atau array untuk vision). |
| max_tokens | integer | — | Batas token completion. Default = anggaran konteks model. |
| temperature | number | — | Temperature sampling (0–2). Default 1.0. Setel 0 untuk output yang mendekati deterministik. |
| top_p | number | — | Nucleus sampling (0–1). Gunakan dengan atau sebagai pengganti temperature. |
| stream | boolean | — | Streaming token via SSE. Lihat panduan streaming. |
| tools | array | — | Definisi function yang dapat dipanggil model. Bentuknya sama seperti OpenAI. |
| tool_choice | string / object | — | "auto" (default), "none", atau function tertentu. |
| response_format | object | — | {"type": "json_object"} untuk mode JSON. |
| seed | integer | — | Seed sampling deterministik. Tidak semua provider upstream menghormatinya. |
| stop | string / array | — | Hingga 4 stop sequence. |
| presence_penalty | number | — | −2 hingga 2. Mendorong topik baru. |
| frequency_penalty | number | — | −2 hingga 2. Mengurangi pengulangan. |
| user | string | — | Identifier end-user buram — muncul di traces untuk atribusi per-pengguna. |
| metadata | object | — | Tag key/value bebas (maks 16 key) yang dilampirkan ke trace. |
Header permintaan Anoman
Header opsional
| Header | Nilai | Efek |
|---|---|---|
| x-anoman-realtime | 1 / true | Paksa realtime meski key pelanggan lebih memilih batch. |
| x-anoman-prefer-batch | 1 / true | Ikutkan permintaan ini ke routing batch (lebih murah, SLA lebih panjang). |
| x-anoman-no-cache | 1 / true | Lewati cache semantik untuk permintaan ini (tetap ditagih biaya penuh). |
| anoman-session-id | string | Kelompokkan permintaan ke dalam sesi agen — muncul di tampilan Sessions dashboard. |
| anoman-agent-id | string | Identifier untuk agen yang melakukan panggilan (mis. support-bot-v2). |
Respons 200
Body respons
Identik dengan bentuk respons OpenAI, ditambah ekstensi _anoman dengan hasil guardrail, keputusan routing, status cache, dan penghitungan biaya kami.
{
"id": "chatcmpl-9k4LpQ8mZx7TbF2Vn",
"object": "chat.completion",
"created": 1740000123,
"model": "claude-sonnet-4-6",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The capital of Indonesia is Jakarta."
},
"finish_reason": "stop",
"logprobs": null
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 9,
"total_tokens": 33,
"prompt_tokens_details": {
"cached_tokens": 0
}
},
"_anoman": {
"guardrails": {
"injection": { "status": "pass", "score": 0.02 },
"pii": { "status": "pass" },
"content": { "status": "pass" },
"policy": { "status": "pass" },
"response_content": { "status": "pass" }
},
"routing": {
"mode": "realtime",
"region": "id",
"provider_type": "cloud_direct",
"provider_region": "ID"
},
"cache": {
"hit": false,
"type": "none"
},
"weighted_tokens": 1240,
"cost_usd": "0.000041",
"burst": { "active": false },
"billing": null
}
}Ingin memakai SDK OpenAI ketat yang menolak field tak dikenal? Setel header permintaan x-anoman-strip-extension: 1 dan blok _anoman dihapus dari body (data tetap sampai ke header + traces).
Header respons
Yang dibawa setiap 200
| Header | Contoh | Deskripsi |
|---|---|---|
| x-anoman-region | ID | Region yang memproses permintaan. |
| x-anoman-cache | none / provider / semantic | Tipe cache hit. |
| x-anoman-guardrail-injection | pass score=0.02 | Hasil pemindaian prompt injection. |
| x-anoman-guardrail-pii | pass redacted 2 entities | Hasil detektor PII. |
| x-anoman-rate-limit-rpm | 120 | Batas burst-guard RPM untuk tier Anda. |
| x-anoman-rate-remaining-rpm | 86 | Sisa permintaan pada menit ini. |
| x-anoman-burst-active | true / (absent) | Apakah kredit burst sedang menggandakan limit Anda. |
Lihat rate limits untuk daftar lengkap header rate.
Vision
Input gambar
Bungkus konten user sebagai array dengan entri type: text dan type: image_url. URL bisa publik atau data URL yang dienkode base64. Hanya model berkemampuan vision yang menerima input gambar — lihat badge residency + /models filter Modality untuk menemukannya.
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "What's in this chart?"},
{
"type": "image_url",
"image_url": {
"url": "https://example.com/chart.png",
# Or pass a data URL:
# "url": "data:image/png;base64,iVBORw0..."
},
},
],
},
],
)Tool calling
Function / tools
Berikan definisi tool dan model dapat memancarkan pesan tool_calls alih-alih teks bebas. Penerapan kebijakan Anoman dapat menolak nama tool tertentu per API key — lihat halaman policies di dashboard.
response = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "What's the weather in Jakarta?"}],
tools=[
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"},
"units": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["city"],
},
},
},
],
tool_choice="auto", # or {"type": "function", "function": {"name": "get_weather"}}
)
# The model decides whether to call the tool. If so:
tool_call = response.choices[0].message.tool_calls[0]
print(tool_call.function.name, tool_call.function.arguments)
# get_weather {"city": "Jakarta", "units": "celsius"}Routing batch
Ikut batch (lebih murah, SLA lebih panjang)
Setel x-anoman-prefer-batch: true dan endpoint yang sama mengembalikan 202 dengan poll_url. Batch job berbiaya ~50% lebih murah untuk beban non-interaktif (analisis data, ekstraksi semalam, eval run).
# Same endpoint — opt in via header. 202 means queued; poll the
# returned poll_url to retrieve when complete.
curl https://api.anoman.io/v1/chat/completions \
-H "Authorization: Bearer anm-sk-..." \
-H "Content-Type: application/json" \
-H "x-anoman-prefer-batch: true" \
-d '{
"model": "deepseek-v3",
"messages": [{"role": "user", "content": "Summarize this 50-page doc..."}]
}'Siklus hidup batch lengkap di referensi endpoint /v1/batch.
Streaming
Setel stream:true
stream = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "Tell me a short story."}],
stream=True,
)
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="", flush=True)Format wire lengkap + penanganan error di tengah stream ada di panduan streaming.
Error
Kemungkinan respons non-200
- 400 —
model_not_found,context_length_exceeded,vision_not_supported - 401/403 — kegagalan auth (lihat authentication) atau blokir guardrail (
prompt_injection,tool_denied,content_violation) - 402 —
budget_exceeded - 429 — batas rate atau inflight cap (lihat rate limits)
- 503/504 — masalah provider (dapat dicoba ulang)
Referensi lengkap di /docs/errors.
Coba dari playground.
Bandingkan 3 panel dengan output streaming langsung.