API Reseller
Referensi REST lengkap untuk program reseller: daftar, login, top-up kuota, minting, dan pengelolaan pelanggan.
API reseller adalah permukaan REST di bawah /api/reseller. Setiap endpoint kecuali signup dan login membutuhkan JWT reseller yang dikirim sebagai Authorization: Bearer <token>. Token diterbitkan saat login dan berlaku selama 24 jam (HS256).
Endpoint autentikasi#
/api/reseller/auth/signupMendaftarkan akun reseller baru. Saat berhasil, akun dibuat dalam status pending dan menunggu review admin.
Parameters
Email login. Tidak boleh masuk daftar hitam.
Kata sandi akun. Minimal 8 karakter.
Nama tampilan reseller.
Nomor WhatsApp untuk kontak, hanya digit dengan kode negara (misalnya `6281234567890`).
Request Example
curl -X POST "https://api.zrouter.dev/api/reseller/auth/signup" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "<password>",
"name": "Your Name",
"wa_number": "6281234567890"
}'Responses
{
"reseller": {
"id": "<reseller-id>",
"email": "[email protected]",
"name": "Your Name",
"status": "pending"
}
}/api/reseller/auth/loginMengautentikasi dan memperoleh JWT reseller. Token berjenis HS256 dan berlaku 24 jam.
Parameters
Email reseller yang terdaftar.
Kata sandi akun.
Request Example
curl -X POST "https://api.zrouter.dev/api/reseller/auth/login" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "<password>"
}'Responses
{
"token": "<token>",
"reseller": {
"id": "<reseller-id>",
"email": "[email protected]",
"name": "Your Name",
"status": "active"
}
}Endpoint akun#
/api/reseller/meMengembalikan profil reseller yang sedang terautentikasi, termasuk status terkini.
Responses
{
"id": "<reseller-id>",
"email": "[email protected]",
"name": "Your Name",
"status": "active"
}/api/reseller/balanceMengembalikan saldo kuota terkini sebagai nilai integer micro-USD.
Responses
{
"balance_usd_micro": "99500000"
}Endpoint top-up#
/api/reseller/topupMembuat order top-up yang menambah kuota USD. Method yang tersedia: qris (IDR, kurs tetap), crypto (USDC/USDT di Solana, 1:1), sumopod (QRIS, tanpa biaya), atau crypto_bep20 (USDT/USDC di BNB Smart Chain, 1:1). Order dimulai dalam status pending dan dikreditkan hanya setelah terkonfirmasi.
Parameters
Metode pembayaran untuk order ini.
qriscryptosumopodcrypto_bep20Jumlah pokok dalam IDR. Wajib saat `method` adalah `qris` atau `sumopod`.
Jumlah dalam micro-USD. Wajib saat `method` adalah `crypto` atau `crypto_bep20`.
Token deposit untuk `crypto_bep20` (BEP20 di BSC chain 56). Diabaikan oleh method lain.
usdtusdcRequest Example
curl -X POST "https://api.zrouter.dev/api/reseller/topup" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"method": "qris", "amount_idr": 50000}'Responses
{
"id": "0d9c6f5e-4c1b-4f6e-9d2a-7b3f8c1e5a20",
"order_number": "RTO-0d9c6f5e-4c1b-4f6e-9d2a-7b3f8c1e5a20",
"payment_method": "qris",
"provider": "tako",
"amount_idr": 50000,
"fee_idr": 2500,
"total_idr": 52500,
"quota_usd_micro": 5000000,
"status": "pending",
"payment_status": "pending",
"provider_payment_id": "...",
"expires_at": "2026-09-16T00:15:00Z",
"created_at": "2026-09-16T00:00:00Z",
"qr_content": "0002...",
"qr_image_url": "https://...",
"payment_url": "https://..."
}curl -X POST "https://api.zrouter.dev/api/reseller/topup" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"method": "crypto", "amount_usd_micro": 20000000}'curl -X POST "https://api.zrouter.dev/api/reseller/topup" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"method": "crypto_bep20", "amount_usd_micro": 20000000, "token_kind": "usdt"}'/api/reseller/topup/{orderID}Mengambil status order top-up dan merekonsiliasinya. Jika pembayaran telah final, order ditandai paid dan kuota Anda dikreditkan dalam panggilan yang sama. Field status adalah siklus hidup order (pending → crediting → credited, atau expired / failed); payment_status adalah tampilan pembayaran hasil derivasi (paid, pending, expired, failed) — pembayaran paid pada order yang belum dikredit tetap dikreditkan. Gunakan endpoint GET ini untuk polling.
Parameters
Field `id` order yang dikembalikan oleh `POST /api/reseller/topup`.
Request Example
curl "https://api.zrouter.dev/api/reseller/topup/<order-id>" \
-H "Authorization: Bearer <token>"Responses
{
"id": "0d9c6f5e-4c1b-4f6e-9d2a-7b3f8c1e5a20",
"order_number": "RTO-0d9c6f5e-4c1b-4f6e-9d2a-7b3f8c1e5a20",
"payment_method": "qris",
"provider": "tako",
"amount_idr": 50000,
"fee_idr": 2500,
"total_idr": 52500,
"quota_usd_micro": 5000000,
"status": "credited",
"payment_status": "paid",
"provider_payment_id": "...",
"expires_at": "2026-09-16T00:15:00Z",
"created_at": "2026-09-16T00:00:00Z",
"paid_at": "2026-09-16T00:07:41Z",
"credited_at": "2026-09-16T00:07:41Z"
}/api/reseller/topupsMenampilkan daftar order top-up Anda, terbaru lebih dulu. Setiap entri bentuknya sama dengan respons order tunggal. total adalah total jumlah order Anda (bukan ukuran halaman), untuk pagination.
Parameters
Ukuran halaman, default 20, maksimum 100.
Offset halaman, default 0.
Request Example
curl "https://api.zrouter.dev/api/reseller/topups?limit=20&offset=0" \
-H "Authorization: Bearer <token>"Responses
{
"topups": [
{
"id": "0d9c6f5e-...",
"order_number": "RTO-0d9c6f5e-...",
"payment_method": "qris",
"provider": "tako",
"amount_idr": 50000,
"fee_idr": 2500,
"total_idr": 52500,
"quota_usd_micro": 5000000,
"status": "credited",
"payment_status": "paid",
"expires_at": "2026-09-16T00:15:00Z",
"created_at": "2026-09-16T00:00:00Z",
"paid_at": "2026-09-16T00:07:41Z",
"credited_at": "2026-09-16T00:07:41Z"
}
],
"total": 1
}/api/reseller/topup/{orderID}/checkAlias legacy dari GET /api/reseller/topup/{orderID} — perilaku poll-dan-rekonsiliasi sama, body respons juga sama. Dipertahankan untuk kompatibilitas mundur.
Parameters
ID order yang dikembalikan oleh `POST /api/reseller/topup`.
Request Example
curl -X POST "https://api.zrouter.dev/api/reseller/topup/<order-id>/check" \
-H "Authorization: Bearer <token>"Responses
Endpoint minting#
/api/reseller/mintMe-mint tier Token Plan kepada pelanggan, mendebit kuota Anda secara atomik. Idempoten pada operation_id. Lihat Kuota & Minting.
Parameters
Key idempotensi yang dibuat klien. Non-kosong, maksimal 128 karakter.
Email pelanggan target (seorang pengguna zrouter).
Tier Token Plan yang diberikan. Lihat [halaman pricing](/id/pricing) yang live.
Request Example
curl -X POST "https://api.zrouter.dev/api/reseller/mint" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"operation_id": "op_1234567890abcdef",
"customer_email": "[email protected]",
"plan_tier_id": "<tier-id>"
}'Responses
{
"customer_user_id": "<user-id>",
"model_id": "<model-id>",
"granted_tokens": 1000,
"price_usd_micro": "1000000",
"balance_after": "98500000",
"already_applied": false
}Katalog tier#
GET /api/reseller/tiers menampilkan daftar tier Token Plan yang dapat Anda mint, satu entri per tier, diurutkan berdasarkan harga tier menaik lalu nama model menaik. Field topup_idr_required adalah kuota top-up IDR yang dibutuhkan untuk menutupi tier pada kurs tetap Rp10.000 per USD (tier_usd_cents × 100); fee pemrosesan QRIS 5% terpisah dan tidak pernah disertakan. Hanya field publik yang aman yang dikembalikan.
/api/reseller/tiersMengembalikan daftar tier Token Plan yang tersedia untuk di-mint, diurutkan berdasarkan harga tier menaik lalu nama model menaik. Field pricing internal tidak pernah diekspos.
Responses
{
"tiers": [
{
"plan_tier_id": "<tier-id>",
"model_id": "<model-id>",
"model_name": "<public-name>",
"tier_usd_cents": 100,
"price_usd_micro": 1000000,
"granted_tokens": 1000,
"topup_idr_required": 10000
}
]
}Endpoint pelanggan#
/api/reseller/customersMenampilkan daftar pelanggan yang terkait dengan reseller ini.
Responses
{
"customers": [
{ "user_id": "<user-id>", "email": "[email protected]" }
]
}/api/reseller/customersResolve-atau-buat pelanggan berdasarkan email. Jika pengguna zrouter belum ada, satu dibuat dan ditautkan ke reseller ini.
Parameters
Email pelanggan.
Request Example
curl -X POST "https://api.zrouter.dev/api/reseller/customers" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'Responses
{
"user_id": "<user-id>",
"email": "[email protected]",
"created": false
}/api/reseller/customers/{userID}/keysMembuat API key untuk pelanggan. Secret ditampilkan sekali dan tidak pernah disimpan. Respons dikirim dengan Cache-Control: no-store.
Parameters
User id pelanggan.
Label untuk key ini.
Request Example
curl -X POST "https://api.zrouter.dev/api/reseller/customers/<user-id>/keys" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name": "production"}'Responses
{
"key_id": "<key-id>",
"name": "production",
"secret": "zr_<public-id>_<secret>"
}/api/reseller/keys/{keyID}Mencabut API key. Terbatas ruang lingkup: key harus milik pelanggan reseller ini, jika tidak request gagal dengan 404.
Parameters
ID key yang akan dicabut.
Request Example
curl -X DELETE "https://api.zrouter.dev/api/reseller/keys/<key-id>" \
-H "Authorization: Bearer <token>"Responses
Endpoint saldo#
Endpoint saldo berbagi satu bentuk respons: objek payg dengan saldo USD sebagai string desimal, dan array token_plans berisi jumlah token integer. Uang selalu berupa string desimal micro-USD (misalnya "0.000001" adalah $0.000001) — tidak pernah float — dan jumlah token selalu integer. Key yang dicabut tetap bisa di-resolve ke saldo pemiliknya, sehingga Anda dapat merekonsiliasi pemakaian historis.
/api/reseller/keys/{keyID}/balancesMengembalikan saldo PAYG dan saldo Token Plan milik pelanggan pemilik API key yang diberikan. Tetap berfungsi meskipun key sudah dicabut, untuk rekonsiliasi historis. Terbatas ruang lingkup: key harus milik pelanggan reseller ini, jika tidak request gagal dengan 404.
Parameters
ID API key (UUID) yang akan dicari.
Request Example
curl "https://api.zrouter.dev/api/reseller/keys/<key-id>/balances" \
-H "Authorization: Bearer <token>"Responses
{
"key_id": "<key-id>",
"customer_user_id": "<user-id>",
"payg": {
"currency": "USD",
"balance": "0.000001"
},
"token_plans": [
{
"model": "<public-name>",
"purchased_tokens": 1000,
"used_tokens": 123,
"remaining_tokens": 877,
"status": "active"
}
],
"as_of": "2026-09-16T00:00:00Z"
}/api/reseller/customers/{userID}/balancesMengembalikan saldo PAYG dan saldo Token Plan untuk salah satu pelanggan Anda. Bentuknya sama dengan endpoint saldo key, dikurangi field key_id. Pelanggan harus dimiliki oleh reseller ini, jika tidak request gagal dengan 404.
Parameters
User id pelanggan (UUID).
Request Example
curl "https://api.zrouter.dev/api/reseller/customers/<user-id>/balances" \
-H "Authorization: Bearer <token>"Responses
{
"customer_user_id": "<user-id>",
"payg": {
"currency": "USD",
"balance": "0.000001"
},
"token_plans": [
{
"model": "<public-name>",
"purchased_tokens": 1000,
"used_tokens": 123,
"remaining_tokens": 877,
"status": "active"
}
],
"as_of": "2026-09-16T00:00:00Z"
}Endpoint penggunaan#
/api/reseller/usageMengembalikan penggunaan yang sudah settle untuk pelanggan reseller ini, terbaru lebih dulu, dengan paginasi cursor. Setiap item memuat biaya persisnya sebagai display_cost_usd_micro.
Parameters
50Ukuran halaman. Minimal 1, maksimal 100.
Cursor buram dari `next_cursor` respons sebelumnya.
Responses
{
"data": [
{
"user_id": "<user-id>",
"model": "<public-name>",
"total_tokens": 49,
"display_cost_usd_micro": "0.000120",
"timestamp": "2026-09-16T00:00:00Z"
}
],
"next_cursor": "<opaque-string>"
}