Documentazione dell'API

API REST per l'accesso batch / automatizzato a jiema.my. Usala per integrare la verifica via SMS nei tuoi servizi. Tutti gli endpoint restituiscono JSON.

Accedi per creare la tua prima API key.

Autenticazione

Ogni richiesta deve includere la tua API key:

Authorization: Bearer jm_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Forma alternativa dell'header: X-API-Key: jm_xxx…

Crea e revoca le chiavi su /account/api-keys. Ogni utente può avere fino a 10 chiavi attive. Il token completo viene mostrato solo una volta alla creazione — conservalo in modo sicuro.

Errori e limiti di frequenza

Tutti gli errori restituiscono JSON:

{ "ok": false, "code": "RATE_LIMITED", "message": "..." }
HTTPcodesignificato
401AUTH_MISSING / AUTH_INVALIDNessuna chiave o revocata
403FORBIDDENBannato o senza accesso
400BAD_REQUEST / INSUFFICIENT / NO_NUMBERS / …Errore di validazione o di business
404NOT_FOUNDL'ordine non esiste (o non è tuo)
429RATE_LIMITEDLimite raggiunto — riprova dopo il reset della finestra. Limite per utente, condiviso tra tutte le chiavi.
500INTERNALErrore del server (segnalato automaticamente)

Limiti di frequenza: Per utente (quota condivisa fra tutte le tue chiavi API), finestra scorrevole di 60s. Endpoint di scrittura (orders, cancel, next-sms) 10 req/min; endpoint di lettura (account, services, prices, list) 60 req/min. Creare altre chiavi non aumenta la tua quota.

GET /v1/account

Recupera il tuo saldo attuale e il profilo di base.

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

Elenca i servizi con disponibilità. Cache lato server ~5 min.

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 },
  ...
] }}

Usa code (o lo slug amichevole) come campo service quando crei un ordine.

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 è l'identificativo numerico del paese del fornitore; slug è il codice breve SEO (es. "my" / "us"). Entrambe le forme funzionano come campo country.

GET /v1/prices?service=tg

Prezzo e disponibilità per paese per un dato servizio. I prezzi includono già il ricarico/sconto configurato dalle operations.

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

Crea un ordine di verifica via SMS. Il sistema riserva un numero di telefono dal fornitore e detrae l'importo addebitato dal tuo saldo.

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"
}}

Nessun campo opzionale oltre a service / country.

Codici di errore comuni: INSUFFICIENT (è necessaria una ricarica), NO_NUMBERS, BAD_SERVICE, BAD_COUNTRY.

GET /v1/orders/:id

Esegui il polling finché status diventa RECEIVED e smsBody non è 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",
  ...
}}

Stati: WAITING (numero attivo, in attesa dell'SMS) · RECEIVED (codice arrivato) · COMPLETED / FAILED / CANCELLED sono finali.

Intervallo di polling consigliato: ogni 3–5 secondi. La sincronizzazione con il fornitore avviene all'interno di questo endpoint, quindi facendo polling lo stato avanza anche se il worker in background è occupato.

POST /v1/orders/:id/cancel

Annulla un ordine che non ha ancora ricevuto un codice. Rimborso totale sul tuo saldo.

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

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

Rifiutato con CODE_RECEIVED se il numero ha già ricevuto qualche SMS, oppure ALREADY_CHANGED se lo stato è cambiato in modo concorrente.

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

Dopo RECEIVED, richiedi al fornitore di mantenere il numero attivo e attendere un altro SMS (senza costi aggiuntivi entro la finestra attiva).

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

Elenco paginato a cursore dei tuoi ordini recenti.

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
}}

Query opzionale: status · limit 1–100 (predefinito 20) · cursor = nextCursor della pagina precedente.

Flusso di lavoro tipico

  1. Ricarica dall'interfaccia web → GET /v1/account per confermare il saldo.
  2. Scegli un servizio: GET /v1/services e GET /v1/prices?service=tg.
  3. Crea un ordine: POST /v1/orders con service + country.
  4. Leggi data.phone e attiva l'SMS dal tuo client (es. incollalo nella registrazione di Telegram).
  5. Esegui polling su GET /v1/orders/:id ogni 3–5s. Quando status === "RECEIVED", leggi smsBody.
  6. Se l'SMS è sbagliato o vuoi un secondo codice: POST /v1/orders/:id/next-sms → torna a WAITING.
  7. Fatto. Se annulli prima che arrivi alcun SMS: POST /v1/orders/:id/cancel per rimborso totale.