Lewati ke konten
kenari.

Baca dokumen

Lampirkan PDF ke request chat biasa, di model apa pun. kenari membaca dokumennya sebelum request dirutekan dan memberi model isinya: teks dari setiap halaman yang punya lapisan teks, dan gambar dari setiap halaman yang tidak punya, misalnya hasil pindaian atau halaman yang hanya berisi gambar. Urutan halaman tetap terjaga. Tidak perlu plugin.

Tidak ada biaya tambahan. Yang diterima model ditagih sebagai token input biasa, mengikuti sumber dana request tersebut, sehingga paket langganan yang mencakup model itu juga mencakup dokumennya.

Untuk dokumen yang butuh OCR sungguhan, misalnya tulisan tangan atau pindaian yang buruk, sebut engine ocr. Pembacaan itu ditagih per halaman dari saldo dan tidak pernah termasuk paket. POST /v1/ocr melakukan pembacaan yang sama tanpa model.

Tambahkan content part bertipe file ke pesan user. file_data adalah data URL dengan format data:<type>;base64,<contents>, yaitu tipe media lalu isi berkas dalam base64. Data URL harus menyebut tipe media. Data URL tanpa tipe, misalnya data:;base64,..., ditolak. URL http biasa tidak diambil, jadi kirim isi berkasnya sendiri. Satu request boleh membawa beberapa dokumen.

Shell menyusun body request, karena curl tidak bisa membaca berkas ke dalam JSON sendiri. Cara ini butuh jq. Ganti invoice.pdf dengan berkasmu sendiri.

Terminal window
{ printf 'data:application/pdf;base64,'; base64 < invoice.pdf | tr -d '\n'; } > invoice.dataurl
jq -n --rawfile data invoice.dataurl '{
model: "step-3-7-flash:free",
messages: [{
role: "user",
content: [
{type: "text", text: "Berapa total di invoice ini?"},
{type: "file", file: {filename: "invoice.pdf", file_data: $data}}
]
}]
}' | curl https://kenari.id/v1/chat/completions \
-H "Authorization: Bearer $KENARI_API_KEY" \
-H "Content-Type: application/json" \
-d @-

Model di contoh ini gratis, jadi contoh ini bisa dijalankan tanpa saldo. Di POST /v1/messages, blok document dengan sumber PDF base64 dibaca dengan cara yang sama. Request Responses tidak menerima dokumen. Lihat Gambar & berkas sebagai input.

  • application/pdf: halaman yang punya lapisan teks dikirim sebagai teks, halaman tanpa lapisan teks dikirim sebagai gambar.
  • text/plain, text/markdown, text/csv, text/html, dan application/json: dikirim sebagai teks.
  • Gambar seperti image/png, image/jpeg, dan image/webp: dikirim sebagai gambar.

Tipe lain ditolak dengan 400 sebelum ada yang ditagih.

  • Sekitar 15 MB per dokumen dan 100 halaman per PDF.
  • Paling banyak 20 halaman tanpa lapisan teks per request. Masing-masing dikirim sebagai gambar, kira-kira 1.000 sampai 1.500 token input. Pindaian yang lebih panjang ditolak dengan 400: pecah dokumennya, atau pakai engine ocr.
  • Dokumen yang membuat request terlalu panjang untuk konteks model ditolak dengan 400 dan tanpa biaya. Pesannya menyebut perkiraan jumlah token dan ukuran konteks model, jadi kamu bisa memilih model yang lebih besar atau mengirim lebih sedikit halaman.
  • PDF yang rusak atau dikunci dengan kata sandi ditolak dengan 400.

Plugin file-parser bersifat opsional. Sebut engine hanya kalau kamu ingin perilaku selain bawaan.

"plugins": [{"id": "file-parser", "pdf": {"engine": "ocr"}}]
engineYang terjadiBiaya
tidak ada atau autoHalaman berteks sebagai teks, halaman lain sebagai gambar. Boleh beberapa dokumen per requestToken input model saja
pdf-text (alias cloudflare-ai)Lapisan teks saja. PDF dengan halaman tanpa teks ditolakToken input model saja
nativeBerkas dikirim apa adanya ke model yang membaca berkas sendiriToken input model saja
ocr (alias mistral-ocr)OCR berbayar, lalu teksnya diberikan ke model. Satu dokumen per requestPer halaman dari saldo, ditambah token model

Dengan native, model yang tidak membaca jenis berkas itu sendiri menolak request dengan 400 tanpa biaya, dan gambar harus dikirim sebagai part image_url. Nama engine lain ditolak dengan 400.

Bagian dari sini sampai Key dengan batasan menjelaskan engine ocr.

Dengan engine ocr, response membawa teks hasil bacaan di samping jawaban model, di message.annotations. Request-nya sama seperti di atas, ditambah "plugins": [{"id": "file-parser", "pdf": {"engine": "ocr"}}].

{
"choices": [{
"message": {
"role": "assistant",
"content": "Totalnya Rp 417.000.",
"annotations": [{
"type": "file",
"file": {
"hash": "sha256:a3b6919a...",
"name": "invoice.pdf",
"content": [{"type": "text", "text": "# INVOICE\n..."}],
"confidence": 0.9892,
"low_confidence": false,
"reuse_id": "ocr_8f286cec-075b-4083-a462-fc89170feb4f"
}
}]
}
}]
}

content berisi teks hasil bacaan, hash mengidentifikasinya, dan reuse_id ada kalau hasil bacaan tersimpan untuk dipakai ulang. Anotasi hanya ditambahkan ke response tanpa streaming. Dengan stream: true, dokumen tetap dibaca dan ditagih, tetapi teks dan reuse_id tidak dikembalikan. Pakai request tanpa streaming kalau kamu butuh keduanya.

confidence adalah rata-rata skor per halaman dari mesin pembaca. Nilainya null kalau mesin tidak memberi skor. low_confidence bernilai true kalau skor di bawah ambang kenari, dan skor yang hilang tidak selalu menyalakannya. Anggap ini sebagai peringatan, bukan jaminan. Dokumen yang terbaca benar dan yang terbaca salah punya rentang skor yang tumpang tindih, dan mesin cenderung mengisi bagian yang tidak terbaca dengan nilai yang tampak masuk akal, bukan mengosongkannya. Minta orang memeriksa setiap angka yang kamu ambil dari hasil pindaian, apa pun nilai low_confidence.

Pakai ulang hasil OCR tanpa biaya halaman lagi

Section titled “Pakai ulang hasil OCR tanpa biaya halaman lagi”

Kirim kembali reuse_id di plugin pada giliran berikutnya, tanpa content part file:

{
"model": "step-3-7-flash:free",
"messages": [{"role": "user", "content": "Siapa penjualnya?"}],
"plugins": [{"id": "file-parser", "pdf": {"engine": "ocr", "reuse_id": "ocr_8f286cec-075b-4083-a462-fc89170feb4f"}}]
}

Ganti dengan reuse_id yang dikembalikan response-mu sendiri.

Giliran itu tidak membaca dokumen lagi dan tidak menambah biaya halaman. Satu request membawa file atau reuse_id, tidak pernah keduanya. reuse_id hanya berlaku untuk akun yang menerimanya, dan berlaku di kedua endpoint: reuse_id dari giliran chat bisa dipakai di /v1/ocr, dan sebaliknya. Kalau model chat gagal setelah dokumen dibaca, biaya halaman tetap berlaku. Mengirim dokumen yang sama lagi di akun yang sama tidak ditagih dua kali, selama pembacaan pertama tersimpan, yaitu kalau response-nya membawa reuse_id.

Pembacaan bawaan, pdf-text, dan native tidak punya biaya sendiri. Teks dan gambar halaman dari dokumen adalah token input model, ditagih seperti input lain, dan paket yang mencakup model itu mencakupnya juga.

Engine ocr menagih per halaman yang dibaca, dari saldo, dan gambar dihitung satu halaman. Paket tidak pernah mencakupnya, bahkan kalau paketmu mencakup model yang menjawab. Kalau saldo tidak cukup untuk dokumennya, kenari menolak request dengan 402 dan insufficient_balance sebelum membaca apa pun, dan tidak ada yang ditagih. Satu request OCR membuat dua baris di pemakaian, satu untuk pembacaan dan satu untuk jawaban model. Lihat Cara penagihan untuk saldo dan dimensi harga, dan Error untuk errornya.

Bagian ini berlaku untuk engine ocr dan /v1/ocr. Key yang dibatasi ke model tertentu hanya bisa memakai OCR kalau kamu mencentang Pembacaan dokumen di bawah Kemampuan berbayar saat membuatnya. Pembacaan bawaan hanya memakai token model, jadi key yang boleh memakai sebuah model juga boleh melampirkan dokumen ke model itu. API key dibagikan hanya bisa memakai ulang hasil bacaan yang dibuat oleh key yang sama, jadi pemegang key dibagikan tidak bisa membaca ulang dokumen dari key lain milikmu. Lihat Autentikasi & API key untuk batasan dan pembagian key.

POST /v1/ocr mengembalikan teks hasil bacaan beserta metadatanya, tanpa model yang menghasilkan jawaban, jadi kamu hanya membayar biaya per halaman tanpa biaya token. Lihat OCR untuk request dan response-nya.