---
title: insufficient_scope — API key kurang izin
source: https://se-hari.com/docs/error/insufficient-scope
updated: 2026-08-15T22:09:53.847376+00:00
---

> HTTP 403. Key Anda valid dan dikenali, tapi tidak punya scope yang dibutuhkan endpoint ini. Perbedaan antara 401 dan 403 di sini bermakna: 401 berarti…

`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.

```json
{
  "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

```bash
# 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

```bash
# 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.

```javascript
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](/docs/error) — daftar lengkap
- [Autentikasi](/docs/autentikasi) — scope dan siklus hidup API key
- [Referensi API](/docs/api) — error apa saja yang mungkin muncul di tiap endpoint