Lewati ke konten
kenari.

Messages

Buat pesan dengan format Anthropic Messages, dan perkirakan berapa token input yang dipakai sebuah request. Endpoint ini kompatibel dengan Anthropic API, jadi SDK resmi Anthropic dan Claude Code langsung bisa dipakai setelah base URL diganti.

POST /v1/messages

POST /v1/messages/count_tokens

Pakai https://kenari.id sebagai base URL, tanpa /v1. SDK Anthropic menambahkan /v1/messages sendiri, dan base URL https://kenari.id/v1 menghasilkan /v1/v1/messages yang mengembalikan 405. Untuk pengaturan Claude Code, lihat Claude Code.

Autentikasi dengan x-api-key: kn-... atau Authorization: Bearer kn-.... Lihat Autentikasi & API key.

FieldTipeWajibKeterangan
modelstringYaId katalog, id :free, nama rute, atau id byok/. Nilainya sama dengan di Chat completions.
messagesarrayYaPercakapan. Lihat Array messages.
max_tokensintegerTidakBatas atas token yang dihasilkan. Di sini opsional, berbeda dengan Anthropic API. Bawaan 65.536.
systemstring atau arrayTidakSystem prompt, berupa string atau array blok {"type": "text", "text": "..."}. Blok teks digabung dengan satu baris kosong, dan jenis blok lain diabaikan.
streambooleanTidakSetel true untuk menerima Server-Sent Events. Lihat Streaming.
temperaturenumberTidakTemperatur sampling.
top_pnumberTidakNucleus sampling.
top_kintegerTidakAmbil sampel dari K token teratas.
stop_sequencesarrayTidakString yang menghentikan generasi.
toolsarrayTidakFunction tool dengan name, description, dan input_schema, serta server tools kenari seperti {"type": "kenari:web_search"}. Lihat Function calling dan Server tools.
tool_choiceobjectTidak{"type": "auto"}, {"type": "any"}, {"type": "none"}, atau {"type": "tool", "name": "..."}.
thinkingobjectTidak{"type": "enabled", "budget_tokens": 4096} atau {"type": "disabled"}. Lihat Penalaran.
output_configobjectTidak{"effort": "high"} menyetel tingkat penalaran tanpa anggaran token. Lihat Penalaran.
metadataobjectTidakDiterima.

kenari tidak menafsirkan field lain. Field itu diteruskan apa adanya ke provider bila model dilayani dalam format Anthropic, dan dibuang bila tidak, jadi jangan bergantung padanya.

Setiap pesan punya field role dan content. role adalah user atau assistant. Pesan system juga diterima di dalam array, seperti yang dikirim Claude Code versi terbaru. content berupa string atau array blok.

BlokKegunaan
textTeks biasa.
imageGambar dari sumber base64 atau url. Lihat Gambar & berkas sebagai input.
documentPDF dari sumber base64 dibaca di model apa pun, sama seperti part file di chat, dan ditagih sebagai token input. Sumber url hanya sampai ke model yang dilayani lewat API gaya Anthropic dan dibuang tanpa error untuk model lain. Sumber text adalah teks biasa. Lihat Baca dokumen.
tool_usePanggilan fungsi yang dibuat model sebelumnya.
tool_resultHasil sebuah panggilan. content berupa string atau array blok text dan image. Setel is_error untuk melaporkan kegagalan.
thinking, redacted_thinkingPenalaran sebelumnya, dikirim kembali tanpa diubah.

Jenis blok yang tidak dikenal diabaikan. Blok dengan tipe yang dikenali tetapi struktur yang tidak valid mengembalikan HTTP 400.

Kirim penanda cache_control seperti yang kamu lakukan ke Anthropic. kenari mempertahankannya bila model dilayani dalam format Anthropic. kenari juga menambahkan titik cache sendiri saat menyusun ulang request, jadi cache tidak bergantung pada penandamu. Lihat Prompt caching.

Response berupa objek message Anthropic.

{
"id": "4f1c9a2e7b3d5a60",
"type": "message",
"role": "assistant",
"model": "step-3-7-flash:free",
"content": [
{ "type": "text", "text": "Halo! Ada yang bisa dibantu?" }
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": { "input_tokens": 9, "output_tokens": 12 }
}
FieldKeterangan
contentArray blok: text, tool_use, dan thinking bila model bernalar. Lihat Penalaran.
stop_reasonend_turn, max_tokens, stop_sequence, tool_use, atau refusal.
stop_sequenceSelalu null. Bila sebuah stop sequence mengakhiri pesan, stop_reason bernilai stop_sequence.
usage.input_tokensToken input yang tidak dilayani dari cache dan tidak ditulis ke cache.
usage.output_tokensToken output. Token penalaran ditagih sebagai output.
usage.cache_read_input_tokensToken input yang dibaca dari cache. Ada bila provider melaporkannya.
usage.cache_creation_input_tokensToken input yang ditulis ke cache. Ada bila provider melaporkannya.
sourcesAda bila server tool kenari mencari di web. Berisi daftar {url, title} untuk tiap sumber.

POST /v1/messages/count_tokens menerima body yang sama dengan /v1/messages dan mengembalikan perkiraan token input.

{ "input_tokens": 41 }

Angkanya diperkirakan dari ukuran request, bukan dihitung dengan tokenizer, jadi anggap sebagai pedoman kasar untuk menyesuaikan jendela konteks. Pemanggilan ini butuh key yang valid, tetapi tidak memeriksa model, tidak menjalankannya, dan tidak dikenai biaya. Body yang tidak bisa diurai mengembalikan 400.

Terminal window
curl https://kenari.id/v1/messages/count_tokens \
-H "x-api-key: $KENARI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "step-3-7-flash:free",
"messages": [{ "role": "user", "content": "Halo!" }]
}'
Terminal window
curl https://kenari.id/v1/messages \
-H "x-api-key: $KENARI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "step-3-7-flash:free",
"max_tokens": 512,
"system": "Kamu menjawab dengan singkat.",
"messages": [{ "role": "user", "content": "Halo!" }]
}'
import os
import anthropic
client = anthropic.Anthropic(
base_url="https://kenari.id",
api_key=os.environ["KENARI_API_KEY"],
)
message = client.messages.create(
model="step-3-7-flash:free",
max_tokens=512,
system="Kamu menjawab dengan singkat.",
messages=[{"role": "user", "content": "Halo!"}],
)
print("".join(block.text for block in message.content if block.type == "text"))
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://kenari.id",
apiKey: process.env.KENARI_API_KEY,
});
const message = await client.messages.create({
model: "step-3-7-flash:free",
max_tokens: 512,
system: "Kamu menjawab dengan singkat.",
messages: [{ role: "user", content: "Halo!" }],
});
for (const block of message.content) {
if (block.type === "text") console.log(block.text);
}

Setiap pesan ditagih per token sesuai harga Input, Output, Cache read, dan Cache write model tersebut. Model :free tidak dikenai biaya. count_tokens gratis. Lihat Cara penagihan.

Error memakai envelope Anthropic: objek dengan "type": "error" dan objek error yang berisi type dan message. Di sini hanya error yang khusus untuk endpoint ini. Sisanya ada di Error.

Statuserror.typeKapan
400invalid_request_errorBody bukan JSON yang valid atau tidak memuat model atau messages. Role, tipe tool_choice, atau blok bertipe dikenali memiliki struktur yang tidak valid. Id byok/ tidak berformat benar. Model bukan model chat, seperti model gambar atau suara. Request lebih panjang dari jendela konteks model.
400not_found_errormodel tidak ada di katalog dan bukan salah satu rutemu, atau kamu belum menyimpan key untuk provider di id byok/.
403permission_errorModel hanya untuk akun dengan langganan aktif. Id byok/ menyebut provider yang key-nya tidak bisa melayani saat ini. API key punya batas pengeluaran yang tidak bisa dipakai untuk request BYOK.
405tidak adaBase URL berakhir dengan /v1, sehingga SDK memanggil /v1/v1/messages. Pakai https://kenari.id.