invalid_request adalah kode error HTTP 400 pada Se-Hari API. Request Anda sampai ke endpoint yang benar dengan kredensial yang benar, tapi isinya tidak sesuai bentuk yang diharapkan. Validasi terjadi sebelum apa pun dikerjakan, jadi tidak ada yang berubah di sisi kami dan tidak ada kredit yang terpotong.
#Bentuk responsnya
Semua error Se-Hari memakai amplop yang sama. Yang perlu dicabang di kode Anda adalah code, bukan message — teks pesan bisa kami perbaiki sewaktu-waktu, sedangkan code adalah kontrak publik yang hanya berubah lewat versi API baru.
{
"error": {
"code": "invalid_request",
"message": "Contoh pesan untuk invalid_request.",
"docs_url": "https://se-hari.com/docs/error/invalid-request",
"request_id": "req_a1b2c3d4e5f6",
"details": {
"field": "date",
"reason": "Tanggal tidak ada di kalender"
}
}
}#Kapan ini muncul
Kode ini muncul di hampir semua endpoint yang menerima body, dan hampir selalu pada percobaan pertama sebuah integrasi baru. Karena validasi berjalan sebelum satu baris data pun disentuh, request yang ditolak dengan kode ini benar-benar tidak meninggalkan jejak: tidak ada meeting setengah jadi, tidak ada pekerjaan yang tergantung di antrean, dan tidak ada kredit yang terpotong. Itu artinya aman diulang sebanyak apa pun setelah body-nya diperbaiki, dan tidak perlu Idempotency-Key khusus untuk memperbaikinya.
#Kenapa ini terjadi
- Field wajib tidak dikirim —
details.fieldmenyebutkan yang mana - Tipe data tidak cocok, misalnya angka dikirim sebagai string
- Nilai di luar rentang: judul lebih dari 200 karakter,
limitlebih dari 100 - Tanggal yang secara format benar tapi tidak ada di kalender, seperti
2026-02-30 - Field tambahan yang tidak dikenal — kami menolaknya alih-alih mengabaikannya, karena field yang salah ketik yang diabaikan diam-diam adalah bug yang sulit ditemukan
#Cara memperbaikinya
Baca details pada respons. Di sana disebutkan field mana dan kenapa ditolak. Kalau details menyebut field yang menurut Anda sudah dikirim, periksa ejaannya — API ini memakai snake_case konsisten (pricing_tier_id, bukan pricingTierId).
#Yang memicu error
curl -X POST "https://se-hari.com/api/v1/meetings" \
-H "Authorization: Bearer $SEHARI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Rapat", "date": "2026-02-30", "start_time": "09:00", "pricing_tier_id": "..."}'#Yang seharusnya
curl -X POST "https://se-hari.com/api/v1/meetings" \
-H "Authorization: Bearer $SEHARI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Rapat", "date": "2026-03-02", "start_time": "09:00", "pricing_tier_id": "..."}'#Aman diulang?
Percuma tanpa perubahan. Request yang sama akan ditolak dengan cara yang sama persis. Perbaiki body-nya dulu, lalu kirim ulang; tidak perlu Idempotency-Key baru karena tidak ada apa pun yang sempat dikerjakan pada percobaan pertama.
#Jangan tertukar dengan
Jangan tertukar dengan invalid_parameter, yang menyoroti query string alih-alih body, dan dengan malformed_json, yang berarti body-nya bahkan tidak berhasil di-parse sehingga tidak ada field yang bisa disebutkan. Kalau details Anda kosong, kemungkinan besar yang Anda terima adalah malformed_json. Dan kalau bentuk request-nya benar tapi isinya tidak masuk akal untuk dikerjakan — misalnya rekaman tanpa audio — kodenya adalah unprocessable_entity, bukan ini.
#Mencegahnya terulang
Cara paling murah mencegahnya adalah membangun body dari tipe data, bukan dari string. Bahasa apa pun yang Anda pakai punya cara menyusun objek lalu menyerialisasinya; menyusun JSON dengan penggabungan string akan menghasilkan kesalahan tanda kutip dan koma yang persis seperti ini, dan baru ketahuan di produksi. Kalau integrasi Anda punya banyak pemanggil, ambil skema dari openapi.json dan validasi di sisi Anda sendiri sebelum mengirim — spesifikasinya memang disediakan untuk itu.
#Menangani ini di kode
Cabangkan pada error.code, dan bedakan kegagalan yang layak diulang dari yang tidak. Mengulang kegagalan yang tidak akan pernah berhasil hanya menghabiskan kuota rate limit — dan menyembunyikan kegagalan yang sebenarnya butuh perhatian Anda.
const res = await fetch('https://se-hari.com/api/v1/me', {
headers: { Authorization: `Bearer ${process.env.SEHARI_API_KEY}` }
});
if (!res.ok) {
const { error } = await res.json();
if (error.code === 'invalid_request') {
// Baca `details` pada respons. Di sana disebutkan field mana dan kenapa ditolak. Kalau…
console.error(error.message, error.details);
}
// request_id adalah satu-satunya cara kami menemukan request ini di log.
console.error(`request_id: ${error.request_id}`);
}#Selanjutnya
- Semua kode error — daftar lengkap
- Autentikasi — scope dan siklus hidup API key
- Referensi API — error apa saja yang mungkin muncul di tiap endpoint