> ## Documentation Index
> Fetch the complete documentation index at: https://docs.leviacloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Format respons & error

> Bentuk jawaban sukses dan error, bahasa pesan, kode error umum, dan X-Request-Id.

## Jawaban sukses

Semua jawaban sukses dibungkus `data`:

```json Satu resource theme={null}
{ "data": { "id": "7f1c2d3e-0000-4000-8000-000000000001", "name": "web-1", "status": "running" } }
```

```json Daftar theme={null}
{
  "data": [ { "id": "…" } ],
  "pagination": { "page": 1, "per_page": 20, "total": 1, "total_pages": 1, "next_page": null }
}
```

```json Hapus theme={null}
{ "data": { "id": "7f1c2d3e-0000-4000-8000-000000000001", "status": "deleting" } }
```

| Status | Kapan |
| - | - |
| `200 OK` | Baca, ubah, atau aksi yang langsung selesai |
| `201 Created` | Resource baru dibuat (biasanya masih disiapkan, lihat `status`) |
| `202 Accepted` | Aksi diterima dan berjalan di belakang. Lihat [Operasi asinkron](https://docs.leviacloud.com/konsep/operasi-asinkron.md). |

`DELETE` tidak pernah menjawab `204`. Jawabannya `200` dengan `"status": "deleted"` bila sudah selesai, atau `202` dengan `"status": "deleting"` bila masih berjalan. Setelah selesai, resource hilang dari daftar dan detailnya menjawab `404`.

## Format data

* Nama field `snake_case`. Id selalu string: UUID, kecuali id image yang berupa slug (mis. `ubuntu-24-04`).
* Waktu dalam RFC 3339, UTC, tanpa milidetik: `2026-11-08T07:15:00Z`. Tanggal saja (`2026-11-08`) dipakai untuk hari kalender Asia/Jakarta di billing.
* Uang di billing dalam **sen** (1/100 Rupiah, field `*_cents`). Harga paket dalam **Rupiah** (`price_monthly`, `price_hourly`).
* Field opsional yang kosong tidak dikirim. Daftar kosong dikirim sebagai `[]`.

## Jawaban error

```json theme={null}
{
  "error": {
    "code": "validation_error",
    "message": "Input tidak valid.",
    "details": { "fields": { "region_id": "harus UUID" } }
  }
}
```

* `code`: string `snake_case` yang stabil. Pakai ini di kode Anda, bukan `message`.
* `message`: penjelasan untuk manusia. Teksnya bisa berubah.
* `details`: opsional. Untuk `validation_error`, field yang salah ada di `details.fields`.

## Bahasa pesan

Kirim `Accept-Language` untuk memilih bahasa `message`:

| Header | Bahasa |
| - | - |
| tidak dikirim, atau `id` | Indonesia (bawaan) |
| `en` | Inggris. Alasan dari platform (berbahasa Indonesia) ada di `details.reason`. |

Header `Content-Language` di jawaban menyebut bahasa yang dipakai. Data resource (nama, status, dll.) tidak diterjemahkan.

## Kode error umum

| HTTP | `code` | Arti |
| - | - | - |
| 400 | `bad_request`, `invalid_json`, `idempotency_key_invalid` | Request tidak terbaca |
| 401 | `missing_api_key`, `invalid_api_key` | Key tidak dikirim, tidak valid, dicabut, atau kedaluwarsa |
| 403 | `insufficient_scope` | Key tidak punya scope endpoint ini |
| 403 | `forbidden` | Role pemilik key tidak boleh mengakses area ini |
| 404 | `not_found`, `route_not_found` | Resource tidak ada atau milik organisasi lain; endpoint tidak ada |
| 405 | `method_not_allowed` | Method tidak didukung untuk endpoint ini |
| 409 | `conflict`, `idempotency_in_progress`, kode spesifik | Bertabrakan dengan keadaan resource, mis. VM sudah mati, atau task sebelumnya masih berjalan |
| 413 | `payload_too_large` | Body lebih dari 1 MB |
| 422 | `validation_error` | Field tidak valid; rinciannya di `details.fields` |
| 422 | `unprocessable`, `idempotency_key_reused`, kode spesifik | Tidak bisa diproses (mis. saldo tidak cukup, fitur belum didukung); alasannya di `message` |
| 429 | `rate_limited`, `too_many_auth_failures` | Terlalu banyak request. Lihat [Rate limit](https://docs.leviacloud.com/konsep/rate-limit.md). |
| 500 | `internal_error` | Kesalahan tak terduga |
| 502 | `upstream_error` | Kesalahan di platform |
| 503 | `core_unavailable` | Layanan sementara tidak bisa dihubungi; ulangi |

**Kode spesifik**: bila platform punya alasan yang lebih tepat, `code` memakai nama itu dalam huruf kecil, mis. `volume_has_snapshots` (`409`) saat menghapus volume yang masih punya snapshot. Tangani kode yang tidak Anda kenal berdasarkan status HTTP-nya.

## Kapan mengulang

| Status | Ulangi? |
| - | - |
| `429` | Ya, setelah `Retry-After`. |
| `502`, `503`, error jaringan | Ya, dengan jeda yang makin panjang. Untuk `POST`, pakai `Idempotency-Key` yang sama. |
| `409` | Ya untuk `idempotency_in_progress` dan task yang masih berjalan, setelah beberapa detik. Selain itu, periksa keadaan resource dulu. |
| `4xx` lainnya | Tidak. Perbaiki request-nya. |

## Pelacakan request

Setiap jawaban membawa header `X-Request-Id`. Anda boleh mengirim `X-Request-Id` sendiri (8–64 karakter: huruf, angka, `.`, `_`, `-`); bila valid, nilai itu dipakai dan dikembalikan. Catat id ini di log aplikasi Anda dan sertakan saat menghubungi dukungan. **Jangan** sertakan API key.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.