DokumentasiReferensi API

Chat completions

Rute chat: parameter, response, dan penalaran.

Ringkasan

Rute utama NusaRouter. Bentuk request dan responsenya mengikuti SDK OpenAI.

POST/v1/chat/completionsbutuh API key

Ini rute chat bentuk OpenAI. NusaRouter juga punya permukaan Anthropic yang terpisah — Format Anthropic — dengan base URL dan bentuk pesan yang berbeda. Jangan mencampur keduanya: di halaman ini yang berlaku hanya bentuk OpenAI.

Body request

FieldTipeWajibArtinya
modelstringWajibId model, persis seperti yang ada di katalog.
messagesarrayWajibMinimal satu pesan. Bentuknya {role, content, name?, tool_call_id?, tool_calls?}.
streambooleanOpsionalDefault false. Lihat Streaming.
max_tokensintegerOpsionalBatas token keluaran. Maksimum 1.000.000.
max_completion_tokensintegerOpsionalDiterima bersama max_tokens.
temperaturenumberOpsional0 sampai 2.
top_pnumberOpsional0 sampai 1.
stopstring | string[]OpsionalSatu atau beberapa sekuens penghenti.
nintegerOpsionalHanya 1. Nilai lain ditolak 422.
toolsarrayOpsionalFungsi yang boleh dipanggil model. Lihat Pemanggilan tool.
tool_choicestring | objectOpsional"auto", "required", atau memaksa satu fungsi. Diteruskan apa adanya, dan seberapa tegas ia ditegakkan bergantung modelnya. "none" belum dihormati, modelnya masih bisa memanggil tool. Lihat Pemanggilan tool.
parallel_tool_callsbooleanOpsionalMengizinkan beberapa panggilan tool dalam satu balasan.

Permukaan Anthropic (POST /v1/messages) memakai nama field Anthropic, bukan field di tabel ini. Lihat Format Anthropic.

role menerima system, developer, user, assistant, atau tool. content berupa string biasa, array berisi bagian bertipe, atau null kalau pesannya hanya membawa tool_calls.

Field tambahan

Field di luar daftar di atas diteruskan ke model, tidak dibuang.

Sebagian field yang umum dipakai sudah kami kenali dan teruskan apa adanya: response_format, seed, presence_penalty, frequency_penalty, logit_bias, logprobs, top_logprobs, user, store, metadata, service_tier, reasoning_effort, modalities, audio, prediction, web_search_options, stream_options, dan pasangan lama functions serta function_call.

Field yang bahkan tidak ada di daftar itu pun tetap diteruskan. Jadi opsi spesifik yang didukung model di balik layar tetap bisa kamu kirim.

Response

200 application/json
{
  "id": "chatcmpl-d070b226-…",
  "object": "chat.completion",
  "created": 1758531600,
  "model": "deepseek-flash-v4.1",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Halo! Ada yang bisa saya bantu?"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 9,
    "completion_tokens": 11,
    "total_tokens": 20,
    "cached_tokens": 0,
    "reasoning_tokens": 0
  }
}

model di response berisi id yang kamu minta, bukan id internal. NusaRouter tidak pernah membuka rute maupun identitas di balik layar.

Blok usage berisi prompt_tokens, completion_tokens, total_tokens, cached_tokens, dan reasoning_tokens. Kalau model tidak melaporkan pemakaian, blok ini tidak ada di response, bukan berisi nol. Nol berarti “tidak ada yang terpakai”; tidak adanya blok berarti “tidak ada yang dilaporkan”, dan keduanya berbeda.

finish_reason diteruskan apa adanya, jadi jawaban yang terpotong karena batas token (length) tetap bisa dibedakan dari jawaban yang selesai (stop).

Kalau model meminta menjalankan fungsi, message-nya berisi tool_calls, content-nya null, dan finish_reason-nya "tool_calls". Bentuk lengkapnya, beserta cara membalasnya, ada di Pemanggilan tool.

Beberapa field lain ikut muncul kalau modelnya mengirim: refusal saat model menolak menjawab, system_fingerprint, dan service_tier. Field yang tidak dikirim model tidak muncul sama sekali, bukan muncul berisi null. logprobs masuk ke situ: kamu boleh memintanya, tapi NusaRouter tidak pernah mengirimkannya pada model yang aktif sekarang.

Model penalaran

Model yang bernalar mengirim dua hal: proses berpikirnya di reasoning_content, dan jawabannya di content.

Ada lima aturan yang berlaku, dan semuanya demi kamu:

  1. Kalau model mengirim penalarannya, isinya diteruskan apa adanya di reasoning_content, tidak kami rangkum dan tidak kami buang. Kamu juga boleh mengirimkannya balik di pesan assistant, dan itu diteruskan utuh ke model.
  2. Yang perlu kamu tahu: pada jawaban biasa, reasoning_content sering tidak ada sama sekali. Bukan hilang di sisi kami, tapi memang tidak dikirim modelnya begitu jawabannya sudah jadi. Jadi jangan mengandalkan field ini selalu ada. Yang bisa kamu pegang: kalau ada, isinya utuh.
  3. Kalau model menghabiskan seluruh anggaran tokennya untuk bernalar dan tidak sempat menulis content sama sekali, penalarannya juga dikirim sebagai content, supaya kamu tidak menerima jawaban kosong. Pada streaming, isi itu ditulis sebelum frame yang membawa finish_reason, karena frame itulah yang jadi tempat klien berhenti membaca.
  4. Pengecualiannya saat model memanggil tool: penalarannya tidak disalin ke content, dan content-nya tetap null. Di situ yang kamu baca memang tool_calls, bukan jawaban, jadi menyalin penalaran ke content justru akan mencampur proses berpikir model ke dalam jawaban. Lihat Pemanggilan tool.
  5. Kalau tidak ada content maupun reasoning_content, request itu dianggap gagal. Biayanya ikut aturan kegagalan: token yang sudah diproses tetap ditagih, dan penahananmu dilepas penuh kalau tidak ada pemakaian yang tercatat. Lihat Urutan dan biaya.

Urutan dan biaya

Setiap request menempuh urutan yang sama:

urutan
batas laju per menit  ->  batas tingkat akses  ->  penahanan saldo  ->  model

Biaya ditahan sebelum request dikirim ke model, lalu diselesaikan dengan pemakaian sebenarnya dan sisanya dikembalikan. Penahanan itu sebuah estimasi, bukan harga tetap: kalau pemakaian ternyata lebih besar, tagihan menyesuaikan naik sampai maksimum 3× estimasi, dan tidak pernah melebihi saldomu.

Untuk request yang gagal, yang menentukan adalah apakah modelnya sempat bekerja, dan NusaRouter menagihkan hanya pemakaian yang tercatat. Kalau ada pemakaian yang tercatat, berarti tokennya benar-benar diproses, dan itu yang kamu bayar. Kalau tidak ada pemakaian yang tercatat sama sekali, seluruh penahananmu dilepas dan kamu tidak membayar apa pun.

Tarifnya diambil saat request dimulai, jadi perubahan harga di tengah request tidak bisa mengubah biaya request yang sedang jalan.

Troubleshooting

GejalaPenyebabSolusi
422Body gagal validasi: model kosong, messages kosong, atau content bukan string.periksa pesan errornya: field yang bermasalah disebutkan namanya
404 model_not_foundId model salah, atau path-nya tidak cocok dengan rute mana pun.ambil id dari katalog publik atau GET /v1/models
Jawaban kosongModel tidak mengirim content maupun reasoning_content, jadi request itu dianggap gagal dengan 502 empty_completion. Kalau penalarannya ada, penalaran itu yang dikirim sebagai content, bukan jawaban kosong.cek pesan errornya: kalau menyebut biaya, token yang sudah diproses tetap kamu bayar. Naikkan max_tokens kalau modelnya kehabisan anggaran
Parameter yang dikirim tidak berpengaruhField diteruskan apa adanya, dan model di baliknya mungkin tidak mendukungnya.uji lewat playground sebelum memakainya di produksi
Putaran kedua loop tool gagal 422Pesan assistant dikirim ulang dalam bentuk yang sudah diubah: tool_calls-nya dibuang, atau content: null-nya diganti jadi string kosong.kirim pesan assistant itu apa adanya, lalu tambahkan satu pesan tool dengan tool_call_id yang cocok. Lihat Pemanggilan tool
502 setelah mengirim toolsSkema parameters tidak valid, jadi modelnya yang menolak. Skema tidak diperiksa di sisi kami.perbaiki JSON Schema-nya, lalu uji lagi