anoman
POST · /v1/chat/completions

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

FieldTipeWajib?Deskripsi
modelstringSlug model dari katalog kami. Lihat GET /v1/models.
messagesarrayRiwayat percakapan. Setiap item memiliki role (system / user / assistant / tool) dan content (string atau array untuk vision).
max_tokensintegerBatas token completion. Default = anggaran konteks model.
temperaturenumberTemperature sampling (0–2). Default 1.0. Setel 0 untuk output yang mendekati deterministik.
top_pnumberNucleus sampling (0–1). Gunakan dengan atau sebagai pengganti temperature.
streambooleanStreaming token via SSE. Lihat panduan streaming.
toolsarrayDefinisi function yang dapat dipanggil model. Bentuknya sama seperti OpenAI.
tool_choicestring / object"auto" (default), "none", atau function tertentu.
response_formatobject{"type": "json_object"} untuk mode JSON.
seedintegerSeed sampling deterministik. Tidak semua provider upstream menghormatinya.
stopstring / arrayHingga 4 stop sequence.
presence_penaltynumber−2 hingga 2. Mendorong topik baru.
frequency_penaltynumber−2 hingga 2. Mengurangi pengulangan.
userstringIdentifier end-user buram — muncul di traces untuk atribusi per-pengguna.
metadataobjectTag key/value bebas (maks 16 key) yang dilampirkan ke trace.

Header permintaan Anoman

Header opsional

HeaderNilaiEfek
x-anoman-realtime1 / truePaksa realtime meski key pelanggan lebih memilih batch.
x-anoman-prefer-batch1 / trueIkutkan permintaan ini ke routing batch (lebih murah, SLA lebih panjang).
x-anoman-no-cache1 / trueLewati cache semantik untuk permintaan ini (tetap ditagih biaya penuh).
anoman-session-idstringKelompokkan permintaan ke dalam sesi agen — muncul di tampilan Sessions dashboard.
anoman-agent-idstringIdentifier 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

HeaderContohDeskripsi
x-anoman-regionIDRegion yang memproses permintaan.
x-anoman-cachenone / provider / semanticTipe cache hit.
x-anoman-guardrail-injectionpass score=0.02Hasil pemindaian prompt injection.
x-anoman-guardrail-piipass redacted 2 entitiesHasil detektor PII.
x-anoman-rate-limit-rpm120Batas burst-guard RPM untuk tier Anda.
x-anoman-rate-remaining-rpm86Sisa permintaan pada menit ini.
x-anoman-burst-activetrue / (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..."
                    },
                },
            ],
        },
    ],
)
Data URL. Maks 5 MB per gambar. PNG, JPEG, dan WebP diterima. GIF beranimasi diturunkan menjadi satu frame.

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

  • 400model_not_found, context_length_exceeded, vision_not_supported
  • 401/403 — kegagalan auth (lihat authentication) atau blokir guardrail (prompt_injection, tool_denied, content_violation)
  • 402budget_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.