insufficient_scope adalah kode error HTTP 403 pada Se-Hari API. Key Anda valid dan dikenali, tapi tidak punya scope yang dibutuhkan endpoint ini. Perbedaan antara 401 dan 403 di sini bermakna: 401 berarti "siapa Anda", 403 berarti "Anda dikenal, tapi tidak untuk ini".
#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": "insufficient_scope",
"message": "Contoh pesan untuk insufficient_scope.",
"docs_url": "https://se-hari.com/docs/error/insufficient-scope",
"request_id": "req_a1b2c3d4e5f6",
"details": {
"required": [
"notulen:write"
],
"granted": [
"notulen:read"
]
}
}
}#Kapan ini muncul
Kode ini adalah bukti bahwa kredensial Anda baik-baik saja. Banyak orang menghabiskan waktu memeriksa ulang key ketika melihat 403, padahal 403 hanya bisa muncul setelah key berhasil dikenali — key yang salah akan berhenti di 401 jauh sebelum pemeriksaan scope dilakukan.
#Kenapa ini terjadi
- Key dibuat dengan scope minimal lalu dipakai untuk hal yang lebih luas
- Endpoint butuh scope tulis sementara key hanya punya scope baca
- Node trigger n8n dipakai dengan key tanpa
webhooks:write
#Cara memperbaikinya
Scope tidak bisa ditambahkan ke key yang sudah ada — ini disengaja, supaya key yang bocor tidak bisa menjadi lebih berbahaya dari waktu ke waktu. Buat key baru dengan scope yang sesuai, ganti di integrasi Anda, lalu cabut yang lama. details.required pada respons menyebutkan scope apa yang kurang.
#Yang memicu error
# Key hanya punya notulen:read
curl -X POST "https://se-hari.com/api/v1/notes" \
-H "Authorization: Bearer $SEHARI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"recording_id": "c0ffee00-1111-2222-3333-444455556666"}'#Yang seharusnya
# Lihat scope yang melekat pada key ini
curl "https://se-hari.com/api/v1/me" \
-H "Authorization: Bearer $SEHARI_API_KEY" | jq '.api_key.scopes'#Aman diulang?
Percuma tanpa perubahan. Scope tidak berubah dengan sendirinya. Buat key baru, ganti di konfigurasi, baru ulangi. Karena tidak ada yang dikerjakan, tidak ada risiko duplikasi.
#Jangan tertukar dengan
Bedakan dari invalid_api_key (401), yang berarti key-nya sendiri tidak dikenali, dan dari forbidden (403 juga), yang berarti izin Anda cukup tapi keadaan datanya yang tidak mengizinkan. Ketiganya butuh tindakan yang sama sekali berbeda: perbaiki key, buat key baru dengan scope lain, atau tunggu sampai keadaannya berubah.
#Mencegahnya terulang
Tentukan scope saat merancang integrasi, bukan saat error pertama muncul. Daftarkan operasi apa saja yang akan dipanggil, lalu ambil gabungan scope-nya. Godaan untuk memberi semua scope pada satu key besar memang kuat, tapi itu menghapus satu-satunya manfaat sistem scope: kalau key semacam itu bocor, tidak ada satu pun hal yang tidak bisa dilakukan pemegangnya atas nama Anda.
#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 === 'insufficient_scope') {
// Scope **tidak bisa ditambahkan ke key yang sudah ada** — ini disengaja, supaya key yang…
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