Documentación de la API
API REST para acceso por lotes / automatizado a jiema.my. Úsala para integrar la verificación por SMS en tus propios servicios. Todos los endpoints devuelven JSON.
Autenticación
Cada solicitud debe incluir tu API key:
Authorization: Bearer jm_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Forma alternativa del encabezado: X-API-Key: jm_xxx…
Crea y revoca claves en /account/api-keys. Cada usuario puede tener hasta 10 claves activas. El token completo se muestra solo una vez al crearlo: guárdalo de forma segura.
Errores y límites de tasa
Todos los errores devuelven JSON:
{ "ok": false, "code": "RATE_LIMITED", "message": "..." }| HTTP | code | significado |
|---|---|---|
| 401 | AUTH_MISSING / AUTH_INVALID | Sin clave o revocada |
| 403 | FORBIDDEN | Baneado o sin acceso |
| 400 | BAD_REQUEST / INSUFFICIENT / NO_NUMBERS / … | Error de validación o de negocio |
| 404 | NOT_FOUND | El pedido no existe (o no es tuyo) |
| 429 | RATE_LIMITED | Limitación por clave |
| 500 | INTERNAL | Error del servidor (reportado automáticamente) |
Límites de tasa: Por clave, ventana deslizante de 60s. Endpoints de escritura (orders, cancel, next-sms) 10 req/min; endpoints de lectura (account, services, prices, list) 60 req/min.
GET /v1/account
Obtén tu saldo actual y el perfil básico.
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
Lista los servicios con stock. Cacheado en el servidor ~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 el slug amigable) como campo service al crear un pedido.
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 es el identificador numérico de país del proveedor; slug es el código corto SEO (p. ej. "my" / "us"). Cualquiera de las dos formas funciona como campo country.
GET /v1/prices?service=tg
Precio y stock por país para un servicio dado. Los precios ya incluyen el margen/descuento configurado por operaciones.
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 pedido de verificación por SMS. El sistema reserva un número de teléfono del proveedor y descuenta el importe correspondiente de tu 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"
}}No hay campos opcionales además de service / country.
Códigos de error comunes: INSUFFICIENT (recarga necesaria), NO_NUMBERS, BAD_SERVICE, BAD_COUNTRY.
GET /v1/orders/:id
Consulta hasta que status sea RECEIVED y smsBody no sea 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",
...
}}Estados: WAITING (número activo, esperando SMS) · RECEIVED (código recibido) · COMPLETED / FAILED / CANCELLED son terminales.
Intervalo de sondeo sugerido: cada 3–5 segundos. La sincronización con el proveedor se ejecuta dentro de este endpoint, por lo que sondearlo hace avanzar el estado aunque el worker en segundo plano esté ocupado.
POST /v1/orders/:id/cancel
Cancela un pedido que aún no ha recibido código. Reembolso total a tu saldo.
curl -X POST https://jiema.my/api/v1/orders/ckxxxxx/cancel \
-H "Authorization: Bearer jm_xxx"
{ "ok": true, "data": { "id": "ckxxxxx", "status": "CANCELLED" }}Rechazado con CODE_RECEIVED si el número ya recibió algún SMS, o ALREADY_CHANGED si el estado cambió de forma concurrente.
POST /v1/orders/:id/next-sms
Después de RECEIVED, solicita al proveedor que mantenga el número activo y espere otro SMS (sin cargo adicional dentro de la ventana activa).
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
Lista paginada por cursor de tus pedidos recientes.
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
}}Consulta opcional: status · limit 1–100 (por defecto 20) · cursor = nextCursor de la página anterior.
Flujo de trabajo típico
- Recarga desde la interfaz web → GET /v1/account para confirmar el saldo.
- Elige un servicio: GET /v1/services y GET /v1/prices?service=tg.
- Crea un pedido: POST /v1/orders con service + country.
- Lee data.phone y dispara el SMS del proveedor desde tu cliente (p. ej. pégalo en el registro de Telegram).
- Sondea GET /v1/orders/:id cada 3–5s. Cuando status === "RECEIVED", lee smsBody.
- Si el SMS es incorrecto o quieres un segundo código: POST /v1/orders/:id/next-sms → vuelve a WAITING.
- Listo. Si cancelas antes de que llegue ningún SMS: POST /v1/orders/:id/cancel para reembolso total.