API v1

REST dan JSON. Aplikasi Onix sendiri memakai API yang sama, jadi data yang kamu lihat di aplikasi datang lewat endpoint ini.

Base URL: https://onix.sassly.ai/api/v1. Semua path di halaman ini relatif terhadap base URL. Body request berformat JSON (Content-Type: application/json). Spesifikasi lengkap OpenAPI 3.1: /docs/openapi.yaml — bisa diimpor ke Postman, Insomnia, atau generator SDK.

Autentikasi

Aplikasi Onix (browser)Integrasi (server-mu)
IdentitasCookie sesi setelah masuk dengan GoogleHeader Authorization: Bearer onx_live_…
Request yang mengubah dataWajib header X-CSRF-Token milik sesi; aplikasi mengirimnya otomatisTanpa CSRF; key ber-scope write
Hak aksesSesuai role dan akses channel penggunaSeluruh workspace, dibatasi scope key
PaketSemua paketPro dan Custom

Membuat API key

  1. Buka Pengaturan → API (butuh akses Kelola API key; khusus Pro).
  2. Klik Buat key, beri nama (mis. "Integrasi CRM"), lalu pilih scope: read (hanya membaca) atau write (membaca dan mengubah data).
  3. Key berawalan onx_live_ dan hanya ditampilkan sekali. Simpan di secret manager; jangan taruh di kode frontend atau repositori.
  4. Maksimal 10 key aktif per workspace. Request dengan key yang sudah dicabut dibalas 401.
export ONIX_API_KEY="onx_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

API key bertindak atas nama workspace dan tidak dibatasi role, jadi perlakukan seperti password. Endpoint pengelolaan (anggota, role, pengaturan, API key, tagihan) hanya bisa dari aplikasi. API tidak mendukung CORS: panggil dari server, bukan dari JavaScript di browser.

Format respons

Respons sukses selalu berbentuk {"data": …, "meta": {…}}; meta hanya ada bila relevan. Respons error selalu berbentuk:

{
  "error": {
    "code": "validation_error",
    "message": "Nama workspace 2–120 karakter.",
    "fields": {"name": "Nama workspace 2–120 karakter."}
  }
}
  • code tetap dan aman dipakai di logika program; message adalah teks untuk manusia yang mengikuti bahasa (header X-Locale: en|id).
  • fields hanya ada pada error input, berisi pesan per kolom.
  • Waktu selalu UTC dalam ISO 8601, mis. 2026-10-08T02:30:00Z. Ubah ke zona waktumu sendiri saat menampilkan; aplikasi Onix memakai zona pribadi pengguna atau zona workspace.
  • Daftar berhalaman menerima page (mulai 1) dan per_page (maks. 100, bawaan 25 kecuali disebut lain), lalu mengembalikan meta.page, meta.per_page, meta.total, dan meta.pages.

Batas request

  • 120 request per menit per API key.
  • Respons memuat header X-RateLimit-Limit dan X-RateLimit-Remaining.
  • Lewat batas dibalas 429 rate_limited dengan header Retry-After (detik sampai menit berikutnya).

Kode error

HTTPcodeArti
401unauthorizedAPI key tidak ada, formatnya salah, atau sudah dicabut; atau sesi aplikasi sudah berakhir.
402plan_requiredWorkspace bukan Pro atau Custom yang aktif (API key dan fitur khusus Pro).
403forbiddenTidak punya permission, endpoint khusus aplikasi dipanggil dengan API key, atau key read mencoba mengubah data.
404not_foundEndpoint atau data tidak ada, termasuk data milik workspace lain.
405method_not_allowedMethod tidak didukung endpoint ini; lihat header Allow.
409conflict / workspace_requiredData bentrok dengan keadaan sekarang (mis. role masih dipakai), atau pengguna belum punya workspace.
419csrf_mismatchRequest aplikasi selain GET tanpa X-CSRF-Token yang valid. Muat ulang halaman lalu coba lagi.
422validation_errorInput tidak valid; rincian per kolom ada di error.fields.
429rate_limitedTerlalu banyak request; tunggu sesuai Retry-After.
500server_errorGangguan di server. Aman dicoba lagi beberapa saat kemudian.

Endpoint

Kolom Permission menunjukkan hak akses yang dibutuhkan pengguna aplikasi (diatur lewat role); "—" berarti semua anggota workspace. API key dianggap punya semua permission workspace.

Bisa dipanggil dengan API key

EndpointPermissionKeterangan
GET /me—Pengguna, workspace aktif, role, permission, dan zona waktu efektif. Lewat API key: pengguna = pembuat key, via = "key".
GET /workspace—Workspace aktif: nama, paket, masa aktif, zona waktu, dan batas paket.
GET /dashboarddashboard.viewLangkah awal, pemakaian kuota, aktivitas 14 hari, aktivitas terbaru, dan ringkasan tim (bagian tertentu butuh permission tambahan).
GET /channels—Channel yang boleh diakses, beserta kuota channel.
GET /settingssettings.workspacePengaturan General (zona waktu workspace, target respons, …) dan pilihannya di meta.choices.
GET /memberssettings.membersSemua anggota termasuk Owner.
GET /invitationssettings.membersUndangan yang belum diterima, termasuk yang kedaluwarsa.
GET /rolessettings.rolesSemua role beserta permission dan jumlah pemakai (atau settings.members).
GET /roles/{id}settings.rolesSatu role.
GET /permissionssettings.rolesKatalog permission per kelompok menu; meta.grantable = yang boleh diberikan pengguna ini.
GET /audit-logssettings.auditAudit log terbaru dulu. Filter: category, user, from, to (YYYY-MM-DD, zona pembaca), q. Bawaan 50 per halaman.

Khusus aplikasi Onix

Endpoint berikut hanya menerima sesi aplikasi (cookie + X-CSRF-Token). Dengan API key dibalas 403 forbidden.

EndpointPermissionKeterangan
PATCH /me—Bahasa & zona waktu pribadi: {"locale": "id", "timezone": "Asia/Makassar"} ("" = ikut workspace).
POST /me/preferences—Preferensi pribadi, mis. status tur dan sidebar.
GET /me/invitations—Undangan berlaku untuk email akun ini.
POST /me/invitations/{id}/accept—Terima undangan; workspace itu menjadi workspace aktif.
POST /me/workspace—Pindah workspace aktif: {"workspace_id": 3}.
GET /workspaces—Workspace tempat pengguna menjadi anggota aktif.
POST /workspaces—Buat workspace (onboarding): {"name": "…", "timezone": "Asia/Jakarta"}.
PATCH /workspacesettings.workspaceGanti nama workspace.
POST /workspace/leave—Keluar dari workspace aktif (bukan Owner).
PATCH /settingssettings.workspaceUbah sebagian pengaturan General, mis. {"timezone": "Asia/Jakarta"}.
GET /notifications—20 notifikasi terbaru dan jumlah yang belum dibaca.
POST /notifications/read—Tandai satu ({"id": 12}) atau semua notifikasi dibaca.
POST /realtime/token—Token WebSocket (Centrifugo) untuk pembaruan langsung.
PATCH /members/{id}settings.membersUbah role, akses channel, atau status (active/disabled).
POST /invitationssettings.membersUndang anggota: email, role_id, channel_access, channel_ids.
POST /invitations/{id}/resendsettings.membersKirim ulang undangan dengan tautan baru.
DELETE /invitations/{id}settings.membersBatalkan undangan.
POST /rolessettings.rolesBuat role: name dan permissions.
PATCH /roles/{id}settings.rolesUbah nama dan permission role (kecuali Owner).
DELETE /roles/{id}settings.rolesHapus role yang tidak dipakai siapa pun.
POST /roles/{id}/duplicatesettings.rolesSalin role.
GET /api-keyssettings.apiAPI key aktif, tanpa nilai rahasianya.
POST /api-keyssettings.apiBuat key: {"name": "…", "scope": "read"}. Nilai utuh hanya dikembalikan sekali.
DELETE /api-keys/{id}settings.apiCabut key.
GET /billingsettings.billingPaket, pemakaian, invoice, dan profil tagihan.
POST /billing/upgradesettings.billingTerbitkan/pakai invoice upgrade lalu buat checkout Sassly Pay.
GET /billing/invoices/{number}settings.billingDetail invoice beserta riwayat percobaan bayar.
POST /billing/invoices/{number}/paysettings.billingAlamat checkout Sassly Pay (percobaan yang masih berlaku dipakai ulang).
PATCH /billing/profilesettings.billingProfil tagihan untuk invoice berikutnya.
POST /billing/downgrade-choicesettings.billingPilih channel & anggota yang tetap aktif setelah turun ke Free.
GET /billing/returnsettings.billingStatus pembayaran setelah kembali dari checkout (dicek ke Sassly Pay di server).

Publik

EndpointPermissionKeterangan
GET /public/config—Harga & kuota paket, pajak, dan aturan retensi (mengikuti X-Locale).
POST /plan-requests—Permintaan paket Custom: name, email, message, opsional company, phone, channels, agents.
GET /invite/{token}—Ringkasan undangan dari tautan email.

Contoh

Siapa pemilik key ini

curl -s "https://onix.sassly.ai/api/v1/me" \
  -H "Authorization: Bearer $ONIX_API_KEY"
{
  "data": {
    "user": {"id": 12, "name": "Budi Santoso", "email": "[email protected]", "avatar_url": null, "locale": "id", "timezone": null, "last_login_at": "2026-10-08T02:00:00Z"},
    "via": "key",
    "timezone": "Asia/Jakarta",
    "workspace": {
      "id": 3, "name": "Toko Budi", "slug": "toko-budi", "plan": "pro", "pro_until": "2026-11-08T03:15:00Z", "in_grace": false, "timezone": "Asia/Jakarta",
      "limits": {"channels": 4, "users": 10, "tickets_per_month": 200, "replies_per_day": 0, "ai_per_month": 2000, "ai": true, "api": true},
      "created_at": "2026-10-08T02:00:00Z"
    },
    "role": {"id": 1, "name": "Owner"},
    "is_owner": true,
    "is_platform_admin": false,
    "permissions": ["dashboard.view", "settings.members", "settings.roles", "settings.billing", "settings.audit", "settings.workspace", "settings.api"],
    "channel_ids": null,
    "realtime": true
  }
}

Pada limits, nilai 0 berarti tanpa batas. channel_ids bernilai null berarti akses ke semua channel. timezone adalah zona efektif (zona pribadi pengguna, atau zona workspace).

Audit log anggota sejak awal bulan

curl -s "https://onix.sassly.ai/api/v1/audit-logs?category=anggota&from=2026-10-01&per_page=20" \
  -H "Authorization: Bearer $ONIX_API_KEY"
{
  "data": [
    {
      "id": 41, "action": "member.invited", "label": "Mengundang anggota", "category": "anggota", "icon": "user-plus",
      "target": "[email protected]", "details": "Role: Agent",
      "user": {"id": 12, "name": "Budi Santoso", "avatar_url": null},
      "ip": "203.0.113.10", "created_at": "2026-10-08T03:20:00Z"
    }
  ],
  "meta": {"page": 1, "per_page": 20, "total": 1, "pages": 1, "categories": [{"key": "anggota", "label": "Anggota & undangan"}, "…"], "users": [{"id": 12, "name": "Budi Santoso"}]}
}

Contoh JavaScript (Node 18+) dan PHP

const res = await fetch("https://onix.sassly.ai/api/v1/members", {
  headers: { Authorization: `Bearer ${process.env.ONIX_API_KEY}` },
});
const { data, error } = await res.json();
if (error) throw new Error(`${error.code}: ${error.message}`);
$ch = curl_init('https://onix.sassly.ai/api/v1/roles');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('ONIX_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);

Event real-time

Aplikasi menerima event lewat WebSocket (Centrifugo) di kanal ws:{workspace_id} dan user:{user_id}. Isi setiap event: {"event": "…", "data": {…}, "at": "…Z"}.

EventKanalKapan
notification.createduser:{id}Notifikasi baru untuk pengguna.
workspace.updatedws:{id}Nama workspace berubah.
settings.updatedws:{id}Pengaturan General berubah (mis. zona waktu).
members.changedws:{id}Anggota/undangan berubah.
billing.updatedws:{id}Paket berubah (Pro aktif, turun ke Free, diatur admin).

Endpoint Inbox WhatsApp, Tiket, Kontak, dan Knowledge base ditambahkan bersama fiturnya di tahap berikutnya.