Dokumentasi API

REST API untuk akses batch / automatik ke jiema.my. Gunakan ini untuk menyepadukan pengesahan SMS ke dalam perkhidmatan anda sendiri. Semua endpoint mengembalikan JSON.

Log masuk untuk membuat API key pertama anda.

Pengesahan

Setiap permintaan mesti menyertakan API key anda:

Authorization: Bearer jm_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Bentuk header alternatif: X-API-Key: jm_xxx…

Cipta dan batalkan key di /account/api-keys. Setiap pengguna boleh menyimpan sehingga 10 key aktif. Token penuh hanya dipaparkan sekali semasa penciptaan — simpan dengan selamat.

Ralat & had kadar

Semua ralat mengembalikan JSON:

{ "ok": false, "code": "RATE_LIMITED", "message": "..." }
HTTPcodemaksud
401AUTH_MISSING / AUTH_INVALIDTiada key atau dibatalkan
403FORBIDDENDiharamkan atau tiada akses
400BAD_REQUEST / INSUFFICIENT / NO_NUMBERS / …Ralat pengesahan atau perniagaan
404NOT_FOUNDOrder tidak wujud (atau bukan milik anda)
429RATE_LIMITEDHad kadar tercapai — cuba semula selepas tetingkap ditetapkan semula. Had per pengguna, dikongsi antara semua key.
500INTERNALRalat pelayan (dilaporkan automatik)

Had kadar: Per pengguna (kuota dikongsi antara semua API key anda), tetingkap gelongsor 60s. Endpoint tulis (orders, cancel, next-sms) 10 req/min; endpoint baca (account, services, prices, list) 60 req/min. Menambah lebih banyak key tidak menaikkan kuota anda.

GET /v1/account

Dapatkan baki semasa dan profil asas anda.

curl https://jiema.my/api/v1/account \
  -H "Authorization: Bearer jm_xxx"

# 200 OK
{ "ok": true, "data": {
  "id": "clxxxxxxxxxxx",
  "balanceCents": "1200",       // string to preserve precision; $12.00
  "referralCode": "abc123",
  "displayName": "Alice",
  "lang": "en"
}}

GET /v1/services

Senaraikan service dengan stok. Cache di sebelah pelayan ~5 minit.

curl https://jiema.my/api/v1/services -H "Authorization: Bearer jm_xxx"

{ "ok": true, "data": { "items": [
  { "code": "tg", "slug": "telegram", "name": "Telegram",
    "minCostUsd": 0.18, "totalCount": 1234, "countryCount": 24 },
  ...
] }}

Gunakan code (atau slug mesra) sebagai medan service apabila mencipta order.

GET /v1/countries

curl https://jiema.my/api/v1/countries -H "Authorization: Bearer jm_xxx"

{ "ok": true, "data": { "items": [
  { "id": 7, "slug": "my", "name": "Malaysia" },
  ...
] }}

id ialah country id berangka upstream; slug ialah kod pendek SEO (cth. "my" / "us"). Kedua-dua bentuk berfungsi sebagai medan country.

GET /v1/prices?service=tg

Harga setiap negara dan stok untuk service tertentu. Harga sudah termasuk markup/diskaun yang dikonfigurasi oleh ops.

curl "https://jiema.my/api/v1/prices?service=tg" -H "Authorization: Bearer jm_xxx"

{ "ok": true, "data": {
  "service": "tg",
  "items": [
    { "countryId": 7, "countrySlug": "my", "priceCents": "32", "count": 540 },
    ...
  ]
}}

POST /v1/orders

Cipta order pengesahan SMS. Sistem akan menempah nombor telefon daripada upstream dan menolak jumlah yang dicaj daripada baki anda.

curl -X POST https://jiema.my/api/v1/orders \
  -H "Authorization: Bearer jm_xxx" \
  -H "content-type: application/json" \
  -d '{ "service": "tg", "country": 7 }'

{ "ok": true, "data": {
  "id": "ckxxxxx",
  "status": "WAITING",
  "service": "tg",
  "country": "7",
  "phone": "+60123456789",
  "expiresAt": "2026-05-22T08:30:00.000Z",
  "chargedCents": "32"
}}

Tiada medan pilihan selain service / country.

Kod ralat biasa: INSUFFICIENT (perlu tambah nilai), NO_NUMBERS, BAD_SERVICE, BAD_COUNTRY.

GET /v1/orders/:id

Polling sehingga status menjadi RECEIVED dan smsBody bukan null.

curl https://jiema.my/api/v1/orders/ckxxxxx -H "Authorization: Bearer jm_xxx"

{ "ok": true, "data": {
  "id": "ckxxxxx",
  "status": "RECEIVED",
  "phone": "+60123456789",
  "smsBody": "Your verification code is 123456",
  "smsHistory": [
    { "body": "Your verification code is 123456", "receivedAt": "..." }
  ],
  "smsReceivedAt": "2026-05-22T08:12:34.000Z",
  ...
}}

Status: WAITING (nombor aktif, menunggu SMS) · RECEIVED (kod tiba) · COMPLETED / FAILED / CANCELLED adalah terminal.

Polling yang dicadangkan: setiap 3–5 saat. Penyegerakan upstream berjalan di dalam endpoint ini supaya polling memacu status walaupun worker latar sibuk.

POST /v1/orders/:id/cancel

Batalkan order yang belum menerima kod. Bayaran balik penuh ke baki anda.

curl -X POST https://jiema.my/api/v1/orders/ckxxxxx/cancel \
  -H "Authorization: Bearer jm_xxx"

{ "ok": true, "data": { "id": "ckxxxxx", "status": "CANCELLED" }}

Ditolak dengan CODE_RECEIVED jika nombor sudah menerima sebarang SMS, atau ALREADY_CHANGED jika status berubah secara serentak.

POST /v1/orders/:id/next-sms

Selepas RECEIVED, minta upstream mengekalkan nombor aktif dan menunggu SMS lain (tanpa caj tambahan dalam tetingkap aktif).

curl -X POST https://jiema.my/api/v1/orders/ckxxxxx/next-sms \
  -H "Authorization: Bearer jm_xxx"

{ "ok": true, "data": { "id": "ckxxxxx", "status": "WAITING" }}

GET /v1/orders

Senarai order terkini anda dengan halaman berasaskan cursor.

curl "https://jiema.my/api/v1/orders?limit=20" -H "Authorization: Bearer jm_xxx"

{ "ok": true, "data": {
  "items": [ { "id": "ck...", "status": "RECEIVED", "service": "tg", ... }, ... ],
  "nextCursor": "ck..." | null
}}

Pertanyaan pilihan: status · limit 1–100 (lalai 20) · cursor = nextCursor halaman sebelumnya.

Aliran kerja biasa

  1. Tambah nilai melalui UI web → GET /v1/account untuk mengesahkan baki.
  2. Pilih service: GET /v1/services dan GET /v1/prices?service=tg.
  3. Cipta order: POST /v1/orders dengan service + country.
  4. Baca data.phone dan picu SMS upstream daripada klien anda (cth. tampal ke pendaftaran Telegram).
  5. Polling GET /v1/orders/:id setiap 3–5s. Apabila status === "RECEIVED", baca smsBody.
  6. Jika SMS salah atau mahu kod kedua: POST /v1/orders/:id/next-sms → kembali ke WAITING.
  7. Selesai. Jika anda membatalkan sebelum sebarang SMS tiba: POST /v1/orders/:id/cancel untuk bayaran balik penuh.