---
title: GET /pricing-tiers
source: https://se-hari.com/docs/api/api-catalog-pricing-tiers
updated: 2026-08-15T18:52:40.166555+00:00
---

> Katalog paket meeting. GET /pricing-tiers — tanpa scope khusus.

Daftar paket harga meeting yang aktif: kapasitas peserta, durasi, dan biaya kredit. Nilai `id` dari endpoint ini adalah satu-satunya sumber sah untuk `pricing_tier_id` saat membuat meeting — jangan menebak atau menyimpannya secara permanen di sisi klien, karena paket bisa ditambah, dinonaktifkan, atau berubah harga. Endpoint ini publik dan tidak memerlukan API key, sehingga bisa dipakai untuk menampilkan pilihan harga di halaman yang belum terautentikasi.
## Endpoint
```bash
GET https://se-hari.com/api/v1/pricing-tiers
```
Endpoint ini tidak menuntut scope apa pun. API key yang paling sempit sekalipun bisa memanggilnya, jadi ia adalah tempat pertama yang harus dicoba ketika Anda ragu apakah masalahnya ada pada kredensial atau pada izin. Kalau endpoint ini menjawab 200 sementara endpoint lain menjawab 403, kredensial Anda baik-baik saja dan yang kurang adalah scope-nya.
## Contoh
```bash
curl -X GET "https://se-hari.com/api/v1/pricing-tiers" \
  -H "Authorization: Bearer $SEHARI_API_KEY"
```
```javascript
const res = await fetch('https://se-hari.com/api/v1/pricing-tiers', {
	method: 'GET',
	headers: {
			'Authorization': `Bearer ${process.env.SEHARI_API_KEY}`,
		}
});

if (!res.ok) {
	const { error } = await res.json();
	// error.code stabil dan bisa dicabang; error.message untuk manusia.
	throw new Error(`${error.code}: ${error.message}`);
}

const data = await res.json();
```
```python
import os, requests

res = requests.get(
    "https://se-hari.com/api/v1/pricing-tiers",
    headers={"Authorization": f"Bearer {os.environ['SEHARI_API_KEY']}"},
    timeout=30,
)

if not res.ok:
    err = res.json()["error"]
    raise RuntimeError(f"{err['code']}: {err['message']}")

data = res.json()
```
## Field tiap item di `data`

| Field | Tipe | Keterangan |
|---|---|---|
| `id` | `string` | — |
| `label` | `string` | — |
| `max_participants` | `integer` | — |
| `duration_hours` | `number` | — |
| `duration_unit` | `string` | — |
| `credits` | `integer` | — |
| `recording_extra_credits` | `integer` | — |
| `price_idr` | `integer` | — |

## Kalau gagal
Setiap kegagalan memakai amplop yang sama, dan `code` di dalamnya stabil — cabangkan logika Anda ke sana, jangan ke `message` yang teksnya bisa diperbaiki sewaktu-waktu.
```json
{
  "error": {
    "code": "rate_limited",
    "message": "Penjelasan untuk manusia.",
    "docs_url": "https://se-hari.com/docs/error/rate-limited",
    "request_id": "req_a1b2c3d4e5f6",
    "details": {}
  }
}
```
| Status | Kode | Artinya di endpoint ini |
|---|---|---|
| 429 | [`rate_limited`](/docs/error/rate-limited) | Terlalu banyak request. Hormati header `Retry-After`. |
| 500 | [`internal_error`](/docs/error/internal-error) | Kesalahan di sisi kami. Sertakan `request_id` saat melapor. |
Simpan `request_id` dari setiap respons gagal. Itu satu-satunya cara kami menemukan kembali request Anda di log ketika Anda melapor, dan ia juga ada di header `X-Request-Id` pada respons yang berhasil.
## Seberapa sering boleh dipanggil

Katalog harga berubah beberapa kali setahun, jadi cache satu jam adalah kompromi yang aman. Yang **tidak** boleh dilakukan adalah menyalin id paket ke dalam kode: id yang di-hardcode akan diam-diam menunjuk paket yang salah begitu katalog diperbarui, dan gejalanya adalah meeting dengan kapasitas atau durasi yang tidak Anda maksudkan — bukan sebuah error.

Endpoint ini bersifat publik dan tidak menuntut scope, jadi ia aman dipanggil dari mana saja termasuk dari antarmuka pengguna Anda sendiri. Meski begitu, memanggilnya dari browser setiap kali halaman dibuka tetap boros; ambil sekali di sisi server Anda lalu sajikan dari sana.

Kalau daftar yang kembali kosong, itu bukan kondisi normal — laporkan dengan menyertakan `request_id`, karena tanpa katalog tidak ada satu pun meeting yang bisa dibuat.

## Alur khas

Katalog harga bersifat publik dan jarang berubah, tapi id paketnya wajib diambil dari sini — bukan disalin ke dalam kode. Id yang di-hardcode akan diam-diam menunjuk paket yang salah begitu katalognya diperbarui.

1. `GET /pricing-tiers` — ambil daftar paket
2. Simpan hasilnya sebentar (satu jam sudah cukup) supaya tidak diminta di setiap request
3. Pakai `id` dari daftar itu saat memanggil `POST /meetings`

`POST /meetings` dengan `pricing_tier_id` yang tidak dikenal menjawab `not_found`, bukan membuat meeting dengan paket bawaan. Ini disengaja: menebak paket berarti menebak berapa kredit yang boleh dipotong.

## Yang sering keliru

- **Hormati `Retry-After`.** Mencoba lagi lebih cepat dari yang disebutkan hanya memperpanjang masa tunggu. Kalau Anda sering menyentuhnya, kemungkinan besar Anda sedang polling sesuatu yang seharusnya ditangani webhook.

## Selanjutnya
- [Autentikasi dan API key](/docs/autentikasi) — cara membuat key dan memilih scope
- [Kode error](/docs/error) — arti setiap kode dan cara memperbaikinya
- [Idempotency](/docs/idempotency) — kenapa retry aman kalau dilakukan dengan benar
- [Spesifikasi OpenAPI](https://se-hari.com/api/v1/openapi.json) — kontrak mesin, cocok untuk men-generate klien