System One
Ajukan pertanyaan bertipe tentang sebuah teks, data, gambar, audio, atau video, dan terima satu jawaban bertipe untuk setiap pertanyaan. Model Clairic justru mengekstrak nilai: kamu menyebutkan field bertipe dan menerima satu nilai bertipe untuk setiap field. Model System One adalah model keputusan dan ekstraksi, bukan model chat. Karena request-nya bukan request chat, ini adalah kontrak kenari sendiri dan tidak ada method SDK OpenAI atau Anthropic yang memetakannya.
POST /v1/systemone
Endpoint ini hanya melayani model System One. Kalau dipanggil dengan model chat, hasilnya 400. Kalau endpoint chat dipanggil dengan id System One, hasilnya 400 yang mengarah ke sini. Lihat model System One yang sedang tersedia lewat panggilan publik yang tidak butuh key:
curl "https://kenari.id/v1/models?modality=systemone"GET /v1/models tanpa parameter tidak menampilkan model embedding, rerank, moderasi, atau System One. Endpoint ini menampilkan model chat, gambar, suara, transkripsi, dan video. Contoh di bawah memakai model gratis. Ganti dengan id yang dikembalikan panggilan di atas, selama modelnya menerima apa yang kamu kirim. Tidak ada streaming.
Request
Section titled “Request”| Field | Tipe | Wajib | Keterangan |
|---|---|---|---|
model | string | ya | Id model System One. |
state | string, object, atau array | ya | Teks atau data yang dinilai. Request fields boleh tanpa state bila mengirim gambar. |
questions | object | ya, atau fields | Satu atau lebih pertanyaan. Setiap key adalah id pertanyaan pilihanmu, dan jawabannya kembali dengan key yang sama. Maksimum 128 pertanyaan. |
fields | object | ya, atau questions | Hanya Clairic. Field bertipe yang diekstrak, sebagai pengganti questions. Kirim questions atau fields, tidak keduanya. Lihat Ekstrak field. |
reference_date | string | tidak | Hanya Clairic. Tanggal ISO, misalnya 2026-10-25, sebagai patokan untuk tanggal yang ditulis tanpa tahun. |
options | object | tidak | Hanya Clairic. include_quantiles menambahkan 99 persentil ke estimate. return_state_text mengembalikan teks yang menjadi acuan posisi span di jawaban, sebagai state_text. Keduanya boolean. |
assets | object | tidak | Gambar, masing-masing dengan nama referensi pilihanmu. Lihat Gambar. |
images | array | tidak | Gambar berurutan, untuk model yang menerima bentuk ini. Kirim ini atau assets, tidak keduanya. |
audio | array | tidak | Klip audio, untuk model yang membaca audio. Lihat Audio dan video. |
videos | array | tidak | Video, untuk model yang membaca video. Lihat Audio dan video. |
Body request maksimum 512 KiB, tanpa menghitung data gambar, audio, dan video. Seluruh body, termasuk data itu, maksimum 32 MiB, dan body yang lebih besar ditolak dengan 413. Base64 menambah sekitar sepertiga ukuran berkas. Setiap pertanyaan adalah objek:
| Field | Tipe | Wajib | Keterangan |
|---|---|---|---|
type | string | ya | noul, choice, score, atau box. |
instructions | string, object, atau array | ya | Isi pertanyaan. |
criteria | object atau array | tidak | Untuk noul, deskripsi benar dan salah. Untuk choice, peta pilihan. Untuk score, rubrik berurutan. box tidak memakainya. |
Response
Section titled “Response”Response hanya berisi model, answers, dan usage, ditambah truncated pada panggilan Clairic dan state_text bila kamu memintanya. model adalah id versi yang menjawab, dan kembali ke id yang kamu minta kalau id versinya tidak tersedia. answers berisi satu entri per id pertanyaan, atau satu per nama field untuk panggilan fields. usage melaporkan input_tokens dan output_tokens. Response Clairic ditunjukkan di Ekstrak field.
{ "model": "clef:free", "answers": { "q": { "type": "noul", "noul": 0.993 } }, "usage": { "input_tokens": 47, "output_tokens": 0 }}Gambar
Section titled “Gambar”Sebagian model System One juga bisa membaca gambar. Model tersebut mencantumkan image di modalities.input pada daftar ?modality=systemone. Mengirim gambar atau pertanyaan box ke model lain menghasilkan 400.
Taruh setiap gambar di assets dengan nama referensi pilihanmu. Lalu tulis nama itu di tempat gambar dimaksud: di state, di instructions atau criteria sebuah pertanyaan, atau di instructions sebuah field. Nama itu boleh berupa seluruh string atau berada di dalam teks. Key objek dan type pertanyaan tidak pernah dibaca sebagai referensi.
| Field | Tipe | Wajib | Keterangan |
|---|---|---|---|
type | string | tidak | image. |
format | string | ya | png, jpg, atau jpeg. Harus sesuai dengan isi file gambarnya. |
data_base64 | string | ya | File gambar dalam base64 standar, tanpa awalan data:. |
Field di bawah ini dikirim di request bersama model, dengan id dari daftar tersebut:
{ "assets": { "struk": { "type": "image", "format": "png", "data_base64": "iVBORw0KGgo..." } }, "state": "struk", "questions": { "rinci": { "type": "noul", "instructions": "Apakah struk mencantumkan harga setiap barang?" }, "total": { "type": "box", "instructions": "Jumlah total di struk" } }}Satu request membawa maksimum 16 gambar, masing-masing maksimum 16 MiB. Nama referensi panjangnya 1 sampai 1.024 byte, dan semua nama digabung maksimum 65.536 byte. Setiap model juga punya batasnya sendiri untuk jumlah gambar yang dibaca, ukuran, dimensi piksel, dan jenis file. Request di luar batas itu menghasilkan 400 dengan pesan yang menyebut batasnya.
Sebagian model juga menerima array images sebagai ganti assets. Setiap item berupa URL data:image/png;base64,..., dengan image/png, image/jpeg, atau image/webp, atau objek dengan content_type dan base64. Model membaca gambar sesuai urutan array. Kirim assets atau images, tidak keduanya. Model yang hanya membaca assets menghasilkan 400 untuk images.
Pertanyaan box
Section titled “Pertanyaan box”Pertanyaan box menanyakan letak sesuatu di dalam gambar. Pertanyaan ini tidak memakai criteria, dan request-nya butuh minimal satu gambar. Jawabannya memberi setiap sisi kotak sebagai pecahan dari tinggi atau lebar gambar, dari 0 sampai 1, ditambah tingkat keyakinan. Tidak semua model gambar menjawab pertanyaan box.
{ "type": "box", "box": { "top": 0.62, "bottom": 0.7, "left": 0.55, "right": 0.9 }, "confidence": 0.93 }Audio dan video
Section titled “Audio dan video”Clef Omni membaca audio dan video, selain teks dan gambar. Model yang membacanya mencantumkan audio atau video di modalities.input pada daftar ?modality=systemone. Mengirim audio atau video ke model lain menghasilkan 400.
Kirim audio di audio dan video di videos, bersama model, state, dan questions. state tetap wajib, jadi tambahkan satu baris teks singkat tentang apa yang kamu kirim. Setiap item berupa URL data: dengan isi base64, atau objek dengan content_type dan base64. kenari tidak mengambil isi dari URL, jadi item berupa URL biasa menghasilkan 400.
| Field | Batas | Tipe |
|---|---|---|
audio | Maksimum 4 klip, masing-masing 8 MiB | audio/wav (juga audio/x-wav dan audio/wave) atau audio/mpeg (juga audio/mp3) |
videos | Maksimum 2 video, masing-masing 16 MiB | video/mp4 atau video/webm |
Audio dan video digabung maksimum 16 MiB per request. Ukuran dihitung dari berkasnya, bukan dari teks base64-nya. Berkas harus sesuai dengan tipenya, yaitu WAV atau MP3 untuk audio dan MP4 atau WebM untuk video, kalau tidak request menghasilkan 400.
curl https://kenari.id/v1/systemone \ -H "Authorization: Bearer $KENARI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "clef-omni:free", "state": "Pesan suara dan video singkat dari depan pintu.", "audio": ["data:audio/wav;base64,UklGRiQAAABXQVZF..."], "videos": [{ "content_type": "video/mp4", "base64": "AAAAIGZ0eXBpc29t..." }], "questions": { "delivered": { "type": "noul", "instructions": "Apakah ada paket yang ditinggalkan di depan pintu?" } } }'Base64 di contoh ini dipotong, jadi kirim berkas yang utuh. Bentuk response-nya sama seperti panggilan dengan pertanyaan biasa.
Ekstrak field
Section titled “Ekstrak field”Clairic membaca teks, dan gambar kalau kamu mengirimnya, lalu mengekstrak satu nilai bertipe untuk setiap field. Kirim fields sebagai pengganti questions, dan kirim salah satunya saja. Setiap key di fields adalah nama field pilihanmu, dan jawabannya kembali dengan nama yang sama. state adalah teks yang dibaca. Object atau array dikirim sebagai teks JSON-nya. state boleh tidak ada hanya bila request mengirim gambar, kalau tidak isinya tidak boleh kosong.
Setiap field adalah objek dengan type dan instructions opsional berupa string yang menjelaskan isi field:
| Tipe | Hasil |
|---|---|
text | Potongan state, disalin apa adanya. |
number | Angka yang dibaca atau dihitung dari state. |
date, time, datetime | Tanggal kalender, jam, atau keduanya, dalam bentuk ISO. |
duration | Lama waktu. |
list | Setiap teks, angka, atau tanggal yang cocok, sesuai urutan kemunculannya. |
estimate | Perkiraan angka atau tanggal di antara min dan max yang kamu tentukan. |
forecast | Satu perkiraan untuk setiap langkah ke depan dari sebuah deret data. |
Nama field terdiri dari 1 sampai 64 karakter: A sampai Z, a sampai z, 0 sampai 9, garis bawah, titik, atau tanda hubung. Nama harus diawali huruf atau garis bawah. Satu request memuat 1 sampai 64 field. kenari meneruskan setiap field apa adanya, jadi field juga menerima pengaturan sesuai tipenya, misalnya unit, integer, dan decimals untuk angka, items untuk list, min, max, step, scale, dan null_threshold untuk estimate atau forecast, serta horizon dan interval untuk forecast.
curl https://kenari.id/v1/systemone \ -H "Authorization: Bearer $KENARI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "clairic:free", "state": "Invoice INV-2291, terbit 3 Maret 2026. Total tagihan: Rp 4.250.000.", "fields": { "invoice_number": { "type": "text", "instructions": "Nomor invoice" }, "total": { "type": "number", "instructions": "Total tagihan dalam rupiah" } } }'Response tetap berisi model, answers, dan usage, dengan satu jawaban per nama field. Response menambahkan truncated, yang bernilai true kalau state dipotong agar muat di model, dan state_text kalau kamu menyetel options.return_state_text ke true.
{ "model": "clairic:free", "answers": { "invoice_number": { "type": "text", "value": "INV-2291", "guess": "INV-2291", "confidence": 0.999984, "p_null": 0.000011, "span": [8, 16] }, "total": { "type": "number", "value": 4250000, "guess": 4250000, "confidence": 0.999995, "p_null": 0.000008 } }, "truncated": false, "usage": { "input_tokens": 72, "output_tokens": 0 }}| Key | Arti |
|---|---|
type | Tipe field. |
value | Jawabannya, atau null kalau input tidak menentukannya. |
guess | Kandidat terbaik. Tetap ada di jawaban saat value bernilai null. |
confidence | Seberapa yakin model terhadap jawabannya. |
p_null | Probabilitas bahwa input tidak menentukan nilainya. |
span | Untuk field text, posisi awal dan akhir guess di dalam teks yang dibaca. state_text mengembalikan teks itu. |
Field list menambahkan spans, dan field estimate menambahkan median, p10, dan p90. Setiap nilai pasti valid untuk tipenya, tetapi belum tentu benar, jadi pakai confidence dan p_null untuk menentukan jawaban mana yang perlu dicek manual.
Contoh
Section titled “Contoh”curl https://kenari.id/v1/systemone \ -H "Authorization: Bearer $KENARI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "clef:free", "state": "kucing duduk di atas karpet", "questions": { "q": { "type": "noul", "instructions": "Apakah ini kalimat tentang hewan?" } } }'Python
Section titled “Python”Endpoint ini tidak punya method SDK, jadi pakai requests.
import osimport requests
resp = requests.post( "https://kenari.id/v1/systemone", headers={"Authorization": f"Bearer {os.environ['KENARI_API_KEY']}"}, json={ "model": "clef:free", "state": "kucing duduk di atas karpet", "questions": { "q": { "type": "noul", "instructions": "Apakah ini kalimat tentang hewan?", } }, },)print(resp.json()["answers"])JavaScript
Section titled “JavaScript”const resp = await fetch("https://kenari.id/v1/systemone", { method: "POST", headers: { Authorization: `Bearer ${process.env.KENARI_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ model: "clef:free", state: "kucing duduk di atas karpet", questions: { q: { type: "noul", instructions: "Apakah ini kalimat tentang hewan?", }, }, }),});const { answers } = await resp.json();Penagihan
Section titled “Penagihan”System One ditagih per token input. Token output dilaporkan dan tidak ditagih. Gambar, audio, dan video dihitung sebagai token input. Saldo yang ditahan untuk sebuah request menghitung token setiap gambar dari ukuran pikselnya, satu kali untuk setiap tempat nama referensinya muncul. Untuk setiap klip audio dan setiap video, saldo yang ditahan menghitung angka tetap untuk kemungkinan terburuk, karena kenari tidak membaca durasi klip. Model gratis seperti clef:free menagih Rp 0. Lihat Cara penagihan untuk cara estimasi, penahanan saldo, dan dimensi harga.
| Status | Kode | Kapan |
|---|---|---|
| 400 | bad_request | model tidak dikenal atau bukan model System One, state tidak ada atau bukan string, object, atau array, questions dan fields dikirim bersamaan atau keduanya tidak ada, questions kosong atau lebih dari 128 entri, sebuah pertanyaan punya type yang tidak dikenal atau tanpa instructions, atau body melewati 512 KiB tanpa data gambar, audio, dan video. |
| 400 | bad_request | Model tidak membaca gambar, sebuah gambar bukan base64 yang valid atau tidak sesuai dengan format-nya, pertanyaan box punya criteria atau request-nya tanpa gambar, atau request melewati batas gambar model. |
| 400 | bad_request | Model tidak membaca audio atau video, item audio atau videos berupa URL atau bukan base64 yang valid, tipenya bukan yang diterima atau tidak sesuai dengan berkasnya, atau request melewati batas klip. |
| 400 | bad_request | fields dikirim ke model selain Clairic, atau questions dikirim ke Clairic. Nama atau type field tidak valid, fields berisi lebih dari 64 entri, reference_date bukan string, sebuah opsi bukan true atau false, atau state kosong dan tidak ada gambar yang dikirim. |
| 400 | model_not_found | Modelnya terdaftar tetapi saat ini tidak ada provider yang melayaninya. Coba lagi nanti. |
| 413 | tidak ada | Body request di atas 32 MiB. Response-nya teks biasa. |
Kode bersama, seperti all_providers_failed, ada di Error.