OCR
Baca teks dari PDF atau gambar dokumen tanpa meminta model chat menghasilkan jawaban. Kamu hanya membayar biaya per halaman, tanpa biaya token. Kalau kamu ingin model menjawab pertanyaan tentang dokumen, lampirkan berkasnya ke request Chat Completions, seperti dijelaskan di Baca dokumen, yang dibaca kenari untuk model apa pun sebagai token input biasa. Endpoint ini adalah pembacaan berbayar yang sama dengan engine ocr di sana.
POST /v1/ocr
Request
Section titled “Request”Kirim body JSON dengan file atau reuse_id, tidak pernah keduanya.
| Field | Tipe | Wajib | Deskripsi |
|---|---|---|---|
file | object | salah satu dari file atau reuse_id | Dokumen yang dibaca. |
file.filename | string | ya, bila memakai file | Nama berkas. Dikembalikan sebagai name. |
file.file_data | string | ya, bila memakai file | Data URL base64: data:<type>;base64,<contents>, yaitu tipe media lalu isi berkas dalam base64. URL http biasa tidak diambil. |
reuse_id | string | salah satu dari file atau reuse_id | reuse_id dari pembacaan sebelumnya di akunmu. Menyajikan teks yang tersimpan tanpa biaya. |
engine | string | tidak | Hanya ocr yang diterima. Nilai lain ditolak. |
Tipe yang diterima adalah application/pdf, image/png, image/jpeg, image/webp, image/gif, dan image/tiff. Ada dua batas dan salah satunya bisa menolak lebih dulu: batas halaman per dokumen yang ditetapkan kenari, dan batas ukuran sekitar 15 MB. Dokumen yang melewati salah satu batas ditolak, tidak dibaca, dan tidak ditagih. Pesan penolakan menyebut batas halaman kalau itu yang terlampaui.
Response
Section titled “Response”Response berisi teks hasil bacaan dan biaya pembacaannya. pages adalah jumlah halaman yang benar-benar dibaca, dan biaya dihitung dari angka itu. cost_micro_idr adalah biaya dalam mikro-Rupiah (Rupiah kali 1.000.000), dan bernilai 0 kalau request hanya memakai ulang hasil bacaan yang tersimpan. content berisi teks hasil bacaan. confidence dan low_confidence artinya sama seperti di response chat dengan engine ocr: rata-rata skor per halaman, yang bernilai null kalau mesin tidak memberi skor, dan penanda peringatan, bukan jaminan. reuse_id memungkinkan kamu membaca dokumen yang sama lagi tanpa biaya, dari endpoint ini atau dari chat dengan engine ocr.
{ "id": "req_8f286cec-075b-4083", "pages": 3, "cost_micro_idr": 225000000, "name": "invoice.pdf", "hash": "sha256:a3b6919a...", "content": [{"type": "text", "text": "# INVOICE\n..."}], "confidence": 0.9892, "low_confidence": false, "reuse_id": "ocr_8f286cec-075b-4083-a462-fc89170feb4f"}reuse_id ada kalau hasil bacaan tersimpan. Mengirim dokumen yang sama lagi di akun yang sama mengembalikan hasil bacaan yang tersimpan dan tidak menagih apa pun, selama pembacaan pertama tersimpan dan membawa reuse_id. Anggap setiap angka dari hasil pindaian belum terverifikasi sampai ada orang yang memeriksanya.
Contoh
Section titled “Contoh”Ganti invoice.pdf dengan berkasmu sendiri. Setiap contoh mengubahnya menjadi base64 lebih dulu, dan contoh curl butuh jq.
{ printf 'data:application/pdf;base64,'; base64 < invoice.pdf | tr -d '\n'; } > invoice.dataurl
jq -n --rawfile data invoice.dataurl '{file: {filename: "invoice.pdf", file_data: $data}}' \ | curl https://kenari.id/v1/ocr \ -H "Authorization: Bearer $KENARI_API_KEY" \ -H "Content-Type: application/json" \ -d @-Untuk membaca lagi tanpa membayar, kirim reuse_id sebagai ganti berkas:
curl https://kenari.id/v1/ocr \ -H "Authorization: Bearer $KENARI_API_KEY" \ -H "Content-Type: application/json" \ -d '{"reuse_id": "ocr_8f286cec-075b-4083-a462-fc89170feb4f"}'Python
Section titled “Python”import base64import osimport requests
with open("invoice.pdf", "rb") as f: encoded = base64.b64encode(f.read()).decode()
response = requests.post( "https://kenari.id/v1/ocr", headers={"Authorization": f"Bearer {os.environ['KENARI_API_KEY']}"}, json={ "file": { "filename": "invoice.pdf", "file_data": f"data:application/pdf;base64,{encoded}", } },)response.raise_for_status()result = response.json()
print(result["pages"], result["cost_micro_idr"])print(result["content"][0]["text"])JavaScript
Section titled “JavaScript”import { readFile } from "node:fs/promises";
const encoded = (await readFile("invoice.pdf")).toString("base64");
const response = await fetch("https://kenari.id/v1/ocr", { method: "POST", headers: { Authorization: `Bearer ${process.env.KENARI_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ file: { filename: "invoice.pdf", file_data: `data:application/pdf;base64,${encoded}`, }, }),});if (!response.ok) throw new Error(await response.text());const result = await response.json();
console.log(result.pages, result.cost_micro_idr);console.log(result.content[0].text);Penagihan
Section titled “Penagihan”Pembacaan ditagih per halaman yang dibaca, dari saldo. Paket tidak mencakupnya. kenari memeriksa dulu apakah saldomu cukup untuk dokumen itu sebelum membaca apa pun. Kalau tidak cukup, request ditolak dengan 402 dan tidak ada yang ditagih, dan pembacaan yang gagal juga tidak ditagih. Pemakaian ulang gratis. Lihat Cara penagihan untuk saldo dan dimensi harga.
| Status | Kode | Kapan |
|---|---|---|
| 400 | bad_request | Body tidak berisi file maupun reuse_id, atau berisi keduanya. file_data bukan data URL base64, kosong, atau bukan base64 yang valid. Tipenya tidak diterima. Dokumen melebihi batas ukuran atau batas halaman. engine bukan ocr. reuse_id tidak dikenal di akunmu. |
| 400 | bad_request | Key dibatasi ke model tertentu dan tidak diberi Pembacaan dokumen, atau pembacaan dokumen sedang dimatikan. API key dibagikan mengirim reuse_id yang tidak dibuatnya sendiri. |
| 402 | insufficient_balance | Saldomu tidak cukup untuk dokumen itu. Pesannya menyebut bahwa pembacaan dokumen ditagih per halaman dari saldo dan tidak dicakup paket, serta menyarankan mengirim berkas ke model yang membaca berkas. Pesan itu juga menunjukkan saldo yang tersedia dan saldo maksimum yang dicadangkan untuk pembacaan dokumen ini. |
| 503 | upstream_error | Pembacaan gagal. Kamu tidak ditagih. Coba lagi. |
Body yang bukan JSON valid, request tanpa Content-Type: application/json, serta objek file dengan filename atau file_data yang hilang atau bertipe salah ditolak sebelum endpoint berjalan, dengan body teks biasa tanpa code: 400 untuk JSON yang tidak valid, 415 untuk content type yang hilang, dan 422 untuk field yang hilang atau bertipe salah. Lihat Error.
Key yang dibatasi ke model tertentu butuh Pembacaan dokumen yang dicentang di bawah Kemampuan berbayar. Lihat Autentikasi & API key. Lihat Error untuk kode lainnya.