---
title: REST API
description: Panggil API pelanggan instalasi NexCMP Anda: autentikasi, referensi interaktif, unduhan OpenAPI dan Postman, galat, batas rate, idempotensi, dan contoh curl.
url: https://nexcmp.com/id/docs/developers/api/
applies_to: NexCMP 1.6.1
updated: 2026-11-02
---

# REST API

> **Where in the portal:** Referensi API di `https://<your-domain>/apidoc` (publik) dan kunci API di `/api-keys`. **Where in the admin:** Customers › API keys (`/customers/apikeys`) mencantumkan kunci yang dibuat oleh pelanggan.

## Fungsi {#what-it-does}

Setiap tindakan yang dapat dilakukan pelanggan di portal — mencantumkan dan mengontrol VM, membaca faktur, mengelola SSH Keys, Kubernetes, storage, tiket dukungan — tersedia melalui REST API berversi di bawah `https://<your-domain>/v1/`. Pelanggan memanggilnya dari skrip dan CI dengan **API key** yang dibatasi cakupannya. API yang sama memberi daya pada [`cmp` command-line tool](https://nexcmp.com/id/docs/developers/cmp-cli/) dan [MCP server](https://nexcmp.com/id/docs/developers/mcp/), dan referensinya dihasilkan dari instalasi yang sedang berjalan, sehingga selalu mencantumkan persis fitur yang telah Anda aktifkan.

## Persyaratan {#requirements}

| Item | Persyaratan |
|---|---|
| Alamat HTTPS publik | API disajikan pada domain utama Anda (dan pada domain masing-masing reseller). |
| Sebuah kunci API | Dibuat oleh pelanggan di portal; lihat [API keys](https://nexcmp.com/id/docs/developers/api-keys/). |
| Dependensi | Tidak ada. Endpoint modul yang tidak Anda aktifkan (misalnya Kubernetes atau Object Storage) disembunyikan dari referensi dan ditolak. |

## Siapkan infrastruktur {#prepare-the-infrastructure}

Tidak ada yang perlu diinstal. Jika reverse proxy berada di depan NexCMP, teruskan `/v1/`, `/mcp`, `/cli/`, dan `/apidoc` ke panel (konfigurasi nginx penginstal sudah melakukannya).

## Hubungkan di NexCMP {#connect-in-nexcmp}

### Referensi interaktif {#the-interactive-reference}

Buka `https://cloud.example.com/apidoc` (ganti host dengan domain Anda; pelanggan reseller melihat referensi pada domain reseller, dengan nama reseller). Halaman ini memiliki dokumentasi endpoint dengan contoh permintaan dan respons dalam curl, `cmp` CLI, JavaScript, Python, dan Go, kotak pencarian (Ctrl atau Cmd + K), dan panel **Try it**. Try it mengirimkan permintaan ke situs yang sama saja, dengan kunci yang ditempel oleh pengunjung (disimpan dalam sesi browser); secara default bersifat baca-saja, dan panggilan tulis atau berbayar memerlukan sakelar tambahan dan konfirmasi.


### Unduhan dan dokumen yang dapat dibaca mesin {#downloads-and-machine-readable-documents}

Semua bersifat publik, tidak memerlukan kunci, dan dihasilkan per situs:

| URL | Konten |
|---|---|
| `/apidoc` | Referensi interaktif. |
| `/v1/public/openapi.json` | Dokumen OpenAPI 3.1. |
| `/v1/public/openapi.yaml` | Sama, YAML. |
| `/v1/public/postman.json` | Koleksi Postman. |
| `/v1/public/insomnia.json` | Ekspor Insomnia. |
| `/v1/public/api.md` | Referensi sebagai satu file Markdown. |
| `/v1/public/api-catalog` | JSON Ringkas: merek, URL dasar, awalan kunci, setiap cakupan dan setiap titik akhir dengan metode, jalur, cakupan, dan apakah memerlukan `Idempotency-Key`. |

```bash
curl -s https://cloud.example.com/v1/public/api-catalog | python3 -m json.tool | head -40
curl -sO https://cloud.example.com/v1/public/openapi.yaml
```

Di Postman, pilih **Import › Link** dan tempel `https://cloud.example.com/v1/public/postman.json`. Halaman referensi juga menyediakan klien API satu berkas untuk JavaScript dan Python.

### Autentikasi {#authentication}

Kirimkan kunci dalam header `Authorization`:

```bash
curl -s https://cloud.example.com/v1/billing/wallet \
  -H "Authorization: Bearer vk_XXXX"
```

- Kunci pelanggan dimulai dengan `vk_`. Kunci **terikat situs**: kunci yang dibuat di `cloud.example.com` tidak berfungsi di domain pengecer.
- Token sesi peramban (`pt_...`) hanya untuk portal; gunakan kunci untuk otomatisasi.
- **Cakupan** kunci menentukan apa saja yang boleh dipanggil; cakupan yang hilang akan membalas HTTP 403 `scope_required`. Lihat [API keys](https://nexcmp.com/id/docs/developers/api-keys/).
- Periksa kunci dengan `GET /v1/apikeys/self`: perintah ini mengembalikan nama kunci pemanggil, cakupan, masa kedaluwarsa, dan sisa batas laju yang diizinkan (setiap kunci dapat memanggilnya).

### Contoh {#examples}

```bash
# List virtual machines
curl -s "https://cloud.example.com/v1/vm?page=1" -H "Authorization: Bearer vk_XXXX"

# Start one (needs vm:write)
curl -s -X POST https://cloud.example.com/v1/vm/3f2a1c9e-0000-4000-8000-000000000000/start \
  -H "Authorization: Bearer vk_XXXX"

# Create a VM (paid: needs vm:create and an Idempotency-Key)
curl -s -X POST https://cloud.example.com/v1/vm \
  -H "Authorization: Bearer vk_XXXX" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d @vm.json
```

Ambil bidang permintaan persis dari setiap operasi dari `/apidoc`.

### Galat {#errors}

Setiap galat berupa JSON dengan `code` yang stabil and `message` yang mudah dibaca manusia:

```json
{"error": {"code": "scope_required", "message": "Key lacks scope vm:write"}}
```

| HTTP | Khas `code` | Arti |
|---|---|---|
| 401 | `unauthenticated`, `key_invalid`, `key_revoked`, `key_expired`, `key_ip_denied`, `site_mismatch`, `api_keys_disabled` | Kunci hilang atau tidak dikenal, dicabut, kedaluwarsa, IP pemanggil di luar daftar izin kunci, kunci dari situs lain, atau kunci API dimatikan. |
| 403 | `scope_required`, `endpoint_not_public`, `account_blocked`, `quota_exceeded`, `impersonate_forbidden` | Kunci tidak memiliki cakupan; titik akhir tidak tersedia untuk kunci; akun terkunci; [kuota](https://nexcmp.com/id/docs/billing/quotas/) tercapai; tindakan tidak diizinkan dalam sesi yang disamar. |
| 404 | `not_found` | Tidak ditemukan — juga dikembalikan untuk sumber daya milik orang lain. |
| 422 | `invalid_argument` | Galat validasi (bidang disebutkan dalam respons). |
| 429 | `rate_limited` | Terlalu banyak permintaan; tunggu selama `Retry-After`. |
| 503 | `maintenance` | Mode pemeliharaan aktif: pembacaan berfungsi, penulisan ditolak. |

### Batas laju {#rate-limits}

| Batas | Default |
|---|---|
| Per kunci | 120 permintaan per menit |
| Per akun (semua kunci digabungkan) | 300 permintaan per menit |

Setiap respons membawa `X-RateLimit-Limit`, `X-RateLimit-Remaining`, dan `X-RateLimit-Reset`; kode 429 menambahkan `Retry-After`.

### Idempotensi {#idempotency}

Perintah yang memakan biaya atau tidak dapat diulang (membuat, mengubah paket, membeli, menghapus ...) **memerlukan** header `Idempotency-Key` (string apa pun hingga 200 karakter; UUID sangat cocok). Kirim kunci yang sama lagi setelah waktu habis dan server akan mengembalikan hasil **asli** (dengan `Idempotency-Replayed: 1`) alih-alih mengulangi operasi. Menggunakan kembali kunci untuk perintah yang berbeda akan menjawab 422; permintaan yang masih berjalan menjawab 409/`Retry-After`. Tanpa header tersebut, panggilan berbayar akan ditolak.

## Verifikasi {#verify}

1. Buat kunci dengan cakupan `vm:read` di portal (**API keys › Create key**).
2. Jalankan:

   ```bash
   curl -i https://cloud.example.com/v1/apikeys/self -H "Authorization: Bearer vk_XXXX"
   ```

   Anda mendapatkan HTTP 200 dan header batas laju.
3. `curl -s https://cloud.example.com/v1/vm -H "Authorization: Bearer vk_XXXX"` mencantumkan VM akun. Di portal, kolom **Last used** milik kunci dan **Key usage log** menampilkan panggilan tersebut.

## Batas & catatan {#limits-notes}

- **Tidak pernah tersedia untuk kunci:** isi ulang, tarik dana, ubah kartu atau isi ulang otomatis, ubah sandi, email atau 2FA, hapus akun, buat, edit, atau cabut kunci lainnya. Tindakan tersebut memerlukan sesi peramban yang masuk.
- **Modul tersembunyi:** referensi dan dokumen OpenAPI hanya mencantumkan fitur yang diaktifkan di situs tersebut.
- **Ukuran respons dan penomoran halaman:** titik akhir daftar menggunakan penomoran halaman (`page`, `per_page`); baca dokumen OpenAPI untuk setiap titik akhir.
- **Waktu dan uang:** mata uang dalam sen USD kecuali nama bidang menyatakan sebaliknya.
- **API Admin:** konsol admin memiliki halaman **System › Admin › API** sendiri dan kunci administrator (`ofw_...`) untuk administrasi; keduanya terpisah dari API pelanggan yang dijelaskan di sini.
- **Pengartian versi:** awalan jalur `/v1` bersifat stabil; bidang baru dapat ditambahkan ke respons.

## Pemecahan Masalah {#troubleshooting}

| Gejala | Penyebab | Solusi |
|---|---|---|
| 401 pada kunci baru | Kunci dari domain lain, Kedaluwarsa, atau diketik dengan spasi | Buat kunci pada domain yang Anda panggil; periksa header `Authorization: Bearer vk_...`. |
| 403 `scope_required` | Cakupan tidak ada | Edit kunci di portal dan tambahkan cakupan tersebut. |
| 401 `key_ip_denied` atau `site_mismatch` | Kunci dibatasi ke IP lain ("IP yang diizinkan") atau dibuat di domain lain | Tambahkan IP server Anda ke IP yang diizinkan pada kunci, atau panggil domain tempat kunci dibuat. |
| 404 pada VM yang ada | VM tersebut milik akun lain | Gunakan kunci milik pemiliknya. |
| 400/422 meminta `Idempotency-Key` | Operasi berbayar tanpa header | Tambahkan `Idempotency-Key: <uuid>`. |
| 429 | Melebihi batas | Kurangi permintaan; gunakan `Retry-After`. |
| `/apidoc` menampilkan hasil yang lebih sedikit dari perkiraan | Modul dimatikan | Aktifkan modul di License & updates. |


