Lewati ke konten
kenari.

Pencarian web & X

Cari di web, ambil sebuah halaman, atau cari postingan terbaru di X lewat panggilan HTTP biasa, tanpa perlu memilih atau memanggil model chat. Ini adalah operasi yang sama dengan yang diberikan Server tools kepada model, dan yang sama dengan yang dibuka Server MCP untuk agen. Ketiga endpoint butuh API key.

POST /v1/web/search mengembalikan hasil pencarian yang diurutkan berdasarkan relevansi untuk sebuah query.

FieldTipeWajibDeskripsi
querystringyaQuery pencarian. Tidak boleh kosong.
max_resultsintegertidakJumlah hasil yang dikembalikan. Defaultnya 5. Nilai di luar 1 sampai 10 dipindah ke batas terdekat, bukan ditolak. Nilai negatif atau di atas 255 gagal diurai dengan 422 teks biasa.

Response berisi array results. Setiap hasil punya title, url, dan cuplikan content. id mengidentifikasi request dan cost_micro_idr adalah biaya yang ditagih dalam mikro-Rupiah (Rupiah kali 1.000.000). Nilainya 0 kalau jatah paket menanggung panggilan itu.

{
"results": [
{
"title": "Mengumumkan Rust 1.87.0",
"url": "https://blog.rust-lang.org/2025/05/15/Rust-1.87.0.html",
"content": "Tim Rust dengan senang hati mengumumkan versi baru Rust..."
}
],
"id": "req_2c9d0a7e-5f5e-4b6a",
"cost_micro_idr": 0
}
Terminal window
curl https://kenari.id/v1/web/search \
-H "Authorization: Bearer $KENARI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "versi stabil Rust terbaru", "max_results": 5}'

POST /v1/web/fetch mengambil satu halaman dan mengembalikan teksnya.

FieldTipeWajibDeskripsi
urlstringyaHalaman yang diambil. Harus diawali http:// atau https:// dan menunjuk ke host publik. Alamat di jaringan privat ditolak.

Response berisi title halaman, content sebagai teks biasa, dan links, daftar URL yang ditemukan di halaman. id dan cost_micro_idr sama seperti di atas.

{
"title": "Mengumumkan Rust 1.87.0",
"content": "Tim Rust dengan senang hati mengumumkan versi baru Rust...",
"links": ["https://www.rust-lang.org/", "https://blog.rust-lang.org/"],
"id": "req_6b1f4c88-1d27-4e0b",
"cost_micro_idr": 0
}
Terminal window
curl https://kenari.id/v1/web/fetch \
-H "Authorization: Bearer $KENARI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://blog.rust-lang.org/2025/05/15/Rust-1.87.0.html"}'

POST /v1/x/search mencari postingan terbaru di X dan mengembalikan jawaban singkat beserta sumbernya.

FieldTipeWajibDeskripsi
querystringyaQuery pencarian. Tidak boleh kosong.
x_search_filterobjecttidakMempersempit pencarian. Field yang tidak dikenal ditolak.
x_search_filter.allowed_x_handlesarray of stringtidakCari hanya di akun-akun ini. Maksimal 20.
x_search_filter.excluded_x_handlesarray of stringtidakAbaikan akun-akun ini. Maksimal 20. Tidak bisa dipakai bersama allowed_x_handles.
x_search_filter.from_datestringtidakAwal rentang tanggal, YYYY-MM-DD.
x_search_filter.to_datestringtidakAkhir rentang tanggal, YYYY-MM-DD. Tidak boleh sebelum from_date.
x_search_filter.enable_image_understandingbooleantidakBaca gambar di dalam posting.
x_search_filter.enable_video_understandingbooleantidakBaca video di dalam posting.

Handle ditulis tanpa @ dan hanya berisi huruf, angka, dan garis bawah, maksimal 40 karakter.

Response berisi answer dan array citations berisi object {url, title} yang mengarah ke x.com. title bisa null. id dan cost_micro_idr sama seperti di atas.

{
"answer": "Kebanyakan orang membahas build yang lebih cepat di rilis baru...",
"citations": [
{"url": "https://x.com/rustlang/status/1234567890", "title": null}
],
"id": "req_9a40d1b3-7c52-4f1e",
"cost_micro_idr": 0
}
Terminal window
curl https://kenari.id/v1/x/search \
-H "Authorization: Bearer $KENARI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "tanggapan atas rilis Rust terbaru",
"x_search_filter": {"from_date": "2026-01-01"}
}'

Endpoint ini tidak punya method SDK, jadi panggil dengan requests atau fetch.

import os
import requests
response = requests.post(
"https://kenari.id/v1/web/search",
headers={"Authorization": f"Bearer {os.environ['KENARI_API_KEY']}"},
json={"query": "versi stabil Rust terbaru", "max_results": 3},
)
response.raise_for_status()
for hit in response.json()["results"]:
print(hit["title"], hit["url"])
const response = await fetch("https://kenari.id/v1/web/search", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.KENARI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ query: "versi stabil Rust terbaru", max_results: 3 }),
});
if (!response.ok) throw new Error(await response.text());
for (const hit of (await response.json()).results) {
console.log(hit.title, hit.url);
}

Setiap panggilan yang berhasil ditagih biaya tetap, terpisah dari token, dan biayanya dikembalikan di cost_micro_idr. Panggilan yang gagal tidak ditagih. Paket dapat menanggung pencarian web dan pengambilan halaman, sedangkan pencarian X ditagih dari saldo saja. Aturannya ada di Cara penagihan dan Langganan.

Key yang dibatasi ke model tertentu butuh Pencarian dan pengambilan halaman web yang dicentang di bawah Kemampuan berbayar untuk memanggil pencarian dan pengambilan halaman, dan Pencarian X yang dicentang untuk memanggil pencarian X. Lihat Autentikasi & API key.

StatusKodeKapan
400bad_requestquery atau url kosong. x_search_filter tidak valid, dan pesannya menyebut field-nya. url bukan alamat http atau https yang publik. Pencarian tidak menemukan apa pun, atau halaman tidak bisa diambil. Key dibatasi dan tidak diberi kemampuan itu. Fiturnya sedang dimatikan.
429plan_limit_reachedPencarian atau pengambilan halaman: jatah harian paket habis dan overflow PAYG mati atau saldomu tidak cukup untuk biayanya. Pencarian X: saldomu tidak cukup untuk biayanya.
429rate_limit_exceededAPI key dibagikan memanggil terlalu cepat. Tunggu lalu coba lagi.
503upstream_errorPencarian X gagal memberi jawaban yang bisa dipakai. Kamu tidak ditagih. Coba lagi.

Body yang bukan JSON valid, request tanpa Content-Type: application/json, serta query atau url 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. Hanya string kosong yang sampai ke bad_request. Lihat Error.

Saldo yang habis di endpoint ini mengembalikan 429, bukan 402. Lihat Error untuk kode lainnya.