Panduan Lengkap API SMSCode untuk Developer — 2026

Panduan Lengkap API SMSCode untuk Developer — 2026

Kalau kamu developer yang butuh verifikasi SMS secara programatis — untuk QA testing, automation, atau integrasi ke pipeline CI/CD — SMSCode menyediakan REST API yang bisa kamu pakai langsung dari kode. Beli nomor, polling OTP, cancel order: semuanya tersedia via API dengan response JSON yang konsisten.

Artikel ini adalah panduan teknis lengkap: dari setup autentikasi, endpoint yang tersedia, contoh kode, sampai tips praktis untuk production.

TL;DR: SMSCode punya REST API dengan bearer token auth. Tiga endpoint utama: /v1/catalog/products (lihat nomor tersedia), /v1/orders/create (beli nomor), dan polling status order untuk membaca SMS. Daftar gratis, langsung bisa coba.

Kenapa Developer Butuh API Nomor Virtual?

Sebelum masuk ke teknisnya, ini beberapa use case yang paling umum dari developer yang pakai API SMSCode:

QA Testing dan End-to-End Testing. Kalau kamu develop aplikasi yang butuh verifikasi nomor HP (signup flow, 2FA, dll), kamu butuh nomor nyata untuk testing. Pakai nomor pribadimu buat testing production berisiko dan tidak scalable. Dengan API, kamu bisa generate nomor baru untuk setiap test run secara otomatis.

CI/CD Pipeline. Integrasikan verifikasi SMS ke pipeline continuous integration. Setiap kali ada perubahan di flow autentikasi, test otomatis jalan dengan nomor virtual fresh — tanpa intervensi manual.

Automation untuk akun-akun layanan. Kalau kamu perlu mendaftarkan beberapa akun di layanan tertentu sebagai bagian dari setup infrastruktur (monitoring, testing environment, dll), API memungkinkan proses ini diautomasi.

Research dan data collection. Developer yang butuh akun di berbagai platform untuk research atau data scraping (sesuai ToS platform tersebut) bisa automasikan proses pendaftaran.

Layanan SaaS yang integrasikan verifikasi SMS. Kalau kamu build SaaS dan perlu menawarkan fitur “verifikasi nomor” ke pengguna kamu, SMSCode API bisa jadi backend-nya.

Autentikasi — Bearer Token

SMSCode API menggunakan Bearer Token untuk autentikasi. Token ini unik per akun dan tidak boleh di-share atau di-expose ke client-side.

Cara dapat API token:

  1. Daftar akun di smscode.gg/auth/signup
  2. Login ke dashboard
  3. Buka menu “API” atau “Pengaturan Akun”
  4. Copy API token kamu

Format header autentikasi:

Authorization: Bearer YOUR_API_TOKEN

Semua endpoint API wajib menyertakan header ini. Request tanpa token atau dengan token invalid akan mendapat response 401 Unauthorized.

Keamanan token:

  • Jangan commit token ke repository (gunakan environment variable)
  • Jangan expose token di frontend atau client-side code
  • Rotasi token kalau dicurigai bocor — hubungi support SMSCode

Base URL dan Format Response

Base URL:

https://api.smscode.gg/v1

Semua endpoint di bawah ini menggunakan base URL tersebut.

Format response sukses:

{
  "success": true,
  "data": {}
}

Format response error:

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Deskripsi error"
  }
}

Format ini konsisten di semua endpoint — mudah untuk error handling di kode kamu.

Endpoint 1 — Catalog: Cek Nomor yang Tersedia

Sebelum beli nomor, kamu perlu tahu layanan apa yang tersedia dan harganya.

GET /v1/catalog/products

Query parameters (semua opsional):

  • country_id — ID integer dari GET /v1/catalog/countries
  • platform_id — ID integer dari GET /v1/catalog/services?country_id=...
  • limit — jumlah hasil per halaman
  • page — nomor halaman mulai dari 1

Contoh request dengan curl:

curl -X GET "https://api.smscode.gg/v1/catalog/products?country_id=7&platform_id=1" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Contoh response:

{
  "success": true,
  "data": [
    {
      "id": 1024,
      "name": "WhatsApp - Indonesia",
      "country_id": 7,
      "platform_id": 1,
      "price": 350,
      "available": 87,
      "active": true,
      "catalog_product_id": 88
    }
  ],
  "meta": {
    "page": 1,
    "limit": 1000,
    "count": 1
  }
}

Contoh dengan Python:

import requests

API_TOKEN = "your_api_token_here"
BASE_URL = "https://api.smscode.gg/v1"

headers = {
    "Authorization": f"Bearer {API_TOKEN}"
}

def get_products(country_id, platform_id):
    params = {"country_id": country_id, "platform_id": platform_id}
    response = requests.get(
        f"{BASE_URL}/catalog/products",
        headers=headers,
        params=params
    )
    response.raise_for_status()
    return response.json()["data"]

# ID 7 dan 1 hanya contoh; resolve lewat endpoint countries/services.
products = get_products(country_id=7, platform_id=1)
print(products)

Endpoint 2 — Orders: Beli Nomor Virtual

Setelah tahu product ID dari catalog, kamu bisa buat order untuk mendapatkan nomor virtual.

POST /v1/orders/create

Request body (JSON):

{
  "product_id": 42
}

Contoh request dengan curl:

IDEMPOTENCY_KEY="$(uuidgen)" # Buat sekali untuk order logis ini
curl -X POST "https://api.smscode.gg/v1/orders/create" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -d '{"product_id": 42}'

Contoh response (order berhasil dibuat):

{
  "success": true,
  "data": {
    "orders": [
      {
        "id": 90210,
        "phone_number": "+14155552671",
        "status": "ACTIVE",
        "expires_at": "2026-03-15T10:35:00Z",
        "product_id": 42,
        "amount": 150
      }
    ],
    "failed_count": 0
  }
}

Contoh dengan Python:

import uuid

def create_order(product_id, idempotency_key):
    payload = {"product_id": product_id}

    response = requests.post(
        f"{BASE_URL}/orders/create",
        headers={
            **headers,
            "Content-Type": "application/json",
            "Idempotency-Key": idempotency_key,
        },
        json=payload
    )
    response.raise_for_status()
    return response.json()["data"]["orders"][0]

# Beli nomor untuk Instagram US
create_key = str(uuid.uuid4())
order = create_order(42, idempotency_key=create_key)
print(f"Nomor: {order['phone_number']}")
print(f"Order ID: {order['id']}")

Pembuatan order memotong saldo. Jika response hilang atau request perlu diulang, gunakan kembali Idempotency-Key yang sama dengan body yang sama. Jangan buat key baru di dalam retry loop karena itu dapat membuat dan mendebit order kedua.

Endpoint 3 — Polling Status Order dan Ambil OTP

Setelah beli nomor dan masukkan ke layanan target, kamu perlu polling status order untuk menunggu OTP masuk.

GET /v1/orders/{order_id}

Contoh request dengan curl:

curl -X GET "https://api.smscode.gg/v1/orders/90210" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Contoh response (OTP sudah masuk):

{
  "success": true,
  "data": {
    "id": 90210,
    "phone_number": "+14155552671",
    "status": "OTP_RECEIVED",
    "otp_code": "847293",
    "otp_message": "Instagram: Your OTP code is 847293",
    "otp_received_at": "2026-03-15T10:33:45Z",
    "sms_revision": 1,
    "expires_at": "2026-03-15T10:35:00Z"
  }
}

Status order yang mungkin:

  • ACTIVE — order aktif, menunggu SMS
  • OTP_RECEIVED — SMS diterima; lihat otp_code dan otp_message
  • COMPLETED — order diselesaikan setelah delivery
  • CANCELED — order dibatalkan; refund hanya jika belum ada SMS
  • EXPIRED — order habis tanpa SMS (saldo dikembalikan)

Implementasi polling dengan Python:

import time
import uuid

def poll_for_sms(order_id, timeout_seconds=120, poll_interval=5):
    """
    Poll status order sampai SMS masuk, status terminal, atau timeout lokal.

    Args:
        order_id: ID order yang mau di-poll
        timeout_seconds: Maksimum waktu tunggu (default 120 detik)
        poll_interval: Interval polling dalam detik (default 5 detik)

    Returns:
        Snapshot order kalau selesai menunggu, None kalau timeout lokal
    """
    start_time = time.monotonic()

    while time.monotonic() - start_time < timeout_seconds:
        response = requests.get(
            f"{BASE_URL}/orders/{order_id}",
            headers=headers
        )
        response.raise_for_status()
        data = response.json()["data"]

        if data.get("otp_received_at") is not None:
            return data
        elif data["status"] in ["COMPLETED", "CANCELED", "EXPIRED"]:
            return data

        # Masih ACTIVE, tunggu sebentar
        time.sleep(poll_interval)

    return None  # Timeout

# Contoh penggunaan lengkap
def verify_instagram_account():
    # 1. Cek catalog
    products = get_products(country_id=7, platform_id=1)
    available = [product for product in products if product["available"] > 0]
    if not available:
        raise Exception("Tidak ada nomor tersedia")

    product_id = available[0]["id"]

    # 2. Buat order
    create_key = str(uuid.uuid4())
    order = create_order(product_id, idempotency_key=create_key)
    order_id = order["id"]
    phone_number = order["phone_number"]

    print(f"Gunakan nomor ini di Instagram: {phone_number}")

    # 3. [Di sini: masukkan nomor ke Instagram via Selenium/Playwright]
    # submit_number_to_instagram(phone_number)

    # 4. Poll untuk OTP
    delivery = poll_for_sms(order_id)

    if delivery and delivery.get("otp_received_at") is not None:
        if delivery.get("otp_code"):
            print(f"OTP berhasil diterima: {delivery['otp_code']}")
        else:
            print(f"SMS masuk tanpa kode: {delivery.get('otp_message')}")
        return delivery

    print("SMS tidak masuk dalam batas waktu")
    return None

Endpoint 4 — Cancel Order

Kalau kamu sudah tidak butuh nomor tersebut (misalnya layanan target sedang down atau kamu mau coba nomor lain), kamu bisa cancel order untuk mendapatkan saldo kembali.

POST /v1/orders/cancel

curl -X POST "https://api.smscode.gg/v1/orders/cancel" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id": 90210}'

Order hanya bisa di-cancel kalau can_cancel=true dan belum menerima SMS. SMS teks/link tanpa kode juga menutup cancel dan refund.

Endpoint 5 — Cek Saldo

Monitoring saldo akun penting untuk automation — pastikan ada cukup saldo sebelum buat order.

GET /v1/balance

curl -X GET "https://api.smscode.gg/v1/balance" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Response:

{
  "success": true,
  "data": {
    "balance": 50000,
    "currency": "IDR"
  }
}

Saldo dalam satuan Rupiah. Integrasikan ke monitoring script kamu untuk alerting kalau saldo di bawah threshold tertentu.

Rate Limits

SMSCode API memiliki rate limit untuk mencegah abuse:

Scope Limit
Semua request untuk satu token 300 request/menit

Kalau kamu melebihi rate limit, API akan return 429 Too Many Requests dengan header Retry-After yang menunjukkan berapa detik harus menunggu sebelum request berikutnya.

Best practice untuk polling: Jangan polling terlalu agresif — interval 5 detik sudah cukup untuk sebagian besar use case. OTP biasanya masuk dalam 30-120 detik setelah nomor dimasukkan ke layanan target.

Error Handling yang Baik

Implementasi production harus handle error dengan benar. Berikut error codes yang umum:

HTTP Status Error Code Keterangan
422 VALIDATION_ERROR Parameter request tidak valid
401 UNAUTHORIZED Token tidak valid atau tidak ada
409 INSUFFICIENT_BALANCE Saldo tidak cukup
404 NOT_FOUND Order atau product tidak ditemukan
409 CONFLICT Order tidak bisa di-cancel pada status saat ini
429 RATE_LIMIT_EXCEEDED Melebihi rate limit
500 INTERNAL_ERROR Error di sisi server
def retry_after_seconds(headers, fallback=60):
    """Parse Retry-After safely; invalid or non-positive values use fallback."""
    raw_value = headers.get("Retry-After")
    try:
        seconds = int(raw_value) if raw_value is not None else fallback
    except (TypeError, ValueError):
        return fallback
    return seconds if seconds > 0 else fallback

def safe_api_call(func, *args, **kwargs):
    """Wrapper untuk handle error API dengan baik."""
    try:
        return func(*args, **kwargs)
    except requests.exceptions.HTTPError as e:
        response = e.response
        error_data = response.json().get("error", {})
        code = error_data.get("code", "UNKNOWN")
        if code == "INSUFFICIENT_BALANCE":
            print("Saldo tidak cukup. Top up dulu di smscode.gg")
        elif code in ("CONFLICT", "CANCEL_TOO_EARLY", "REQUEST_IN_PROGRESS"):
            print(f"Order belum dapat menjalankan aksi ini: {code}")
        elif response.status_code == 429:
            retry_after = retry_after_seconds(response.headers)
            print(f"Rate limited. Tunggu {retry_after} detik")
            time.sleep(retry_after)
        elif response.status_code == 500:
            print("Server error. Coba lagi dalam beberapa saat")
        else:
            print(f"API error [{code}]: {error_data.get('message', '')}")
        raise

Contoh Integrasi Lengkap: Pytest + SMSCode

Berikut contoh lengkap bagaimana mengintegrasikan SMSCode ke test suite Python pakai pytest:

# tests/conftest.py
import pytest
import requests
import time
import os
import uuid

SMSCODE_TOKEN = os.environ["SMSCODE_API_TOKEN"]
SMSCODE_BASE = "https://api.smscode.gg/v1"

@pytest.fixture
def sms_order():
    """Fixture yang menyediakan order SMSCode untuk test."""
    headers = {"Authorization": f"Bearer {SMSCODE_TOKEN}"}

    # Cek catalog
    products = requests.get(
        f"{SMSCODE_BASE}/catalog/products",
        headers=headers,
        params={"platform_id": 1, "country_id": 7},
    ).json()["data"]

    available = [product for product in products if product["available"] > 0]
    if not available:
        pytest.skip("Tidak ada produk tersedia untuk fixture")
    product_id = available[0]["id"]

    # Buat order
    create_key = str(uuid.uuid4())
    order = requests.post(
        f"{SMSCODE_BASE}/orders/create",
        headers={**headers, "Idempotency-Key": create_key},
        json={"product_id": product_id}
    ).json()

    created = order["data"]["orders"][0]

    yield created

    current = requests.get(
        f"{SMSCODE_BASE}/orders/{created['id']}",
        headers=headers,
    ).json()["data"]
    if current["can_cancel"]:
        requests.post(
            f"{SMSCODE_BASE}/orders/cancel",
            headers=headers,
            json={"id": created["id"]},
        ).raise_for_status()

# tests/test_signup.py
def test_signup_with_sms(sms_order, your_app):
    # Gunakan nomor untuk signup di aplikasi kamu
    result = your_app.signup(phone=sms_order["phone_number"])
    assert result.success

    # Ambil OTP dari API
    delivery = poll_for_sms(sms_order["id"])
    assert delivery is not None
    assert delivery.get("otp_received_at") is not None
    otp = delivery.get("otp_code")
    assert otp is not None, f"SMS masuk tanpa kode: {delivery.get('otp_message')}"

    # Verifikasi OTP
    verified = your_app.verify_otp(otp)
    assert verified

Tips Keamanan untuk Production

Gunakan environment variable untuk token.

# .env (jangan commit ke git!)
SMSCODE_API_TOKEN=your_token_here
import os
API_TOKEN = os.environ["SMSCODE_API_TOKEN"]

Tambahkan SMSCODE_API_TOKEN ke .gitignore atau gunakan secrets manager. Kalau pakai GitHub Actions, simpan token di GitHub Secrets. Kalau pakai AWS, pakai AWS Secrets Manager atau Parameter Store.

Implement circuit breaker. Kalau SMSCode API sedang down atau lambat, kamu tidak mau test suite atau automation kamu terus retry tanpa henti. Implement circuit breaker pattern — setelah N kali gagal, berhenti dan alert.

Log semua order untuk audit. Simpan log order ID, nomor yang didapat, layanan yang diverifikasi, dan hasilnya. Berguna untuk debugging dan monitoring penggunaan saldo.

Use Case: Automation QA Testing dengan Playwright

# Contoh integrasi SMSCode + Playwright untuk E2E test
from playwright.sync_api import sync_playwright
import requests
import uuid

def test_signup_flow():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()

        # Ambil nomor virtual
        create_key = str(uuid.uuid4())
        order = create_order(product_id=42, idempotency_key=create_key)
        phone = order["phone_number"]
        order_id = order["id"]

        # Buka halaman signup
        page.goto("https://your-app.com/signup")
        page.fill("#phone-input", phone)
        page.click("#send-otp-button")

        # Tunggu OTP
        delivery = poll_for_sms(order_id, timeout_seconds=60)
        assert delivery is not None, "SMS tidak masuk"
        otp = delivery.get("otp_code")
        assert otp is not None, f"SMS masuk tanpa kode: {delivery.get('otp_message')}"

        # Masukkan OTP
        page.fill("#otp-input", otp)
        page.click("#verify-button")

        # Verifikasi berhasil
        assert page.url == "https://your-app.com/dashboard"

        browser.close()

FAQ

Apakah API SMSCode tersedia 24/7?

Ya, API SMSCode beroperasi 24/7. Ketersediaan nomor tergantung pada stok dari provider — beberapa layanan atau negara mungkin kehabisan stok di waktu-waktu tertentu. Selalu cek catalog sebelum buat order dan handle kasus available == 0.

Bagaimana cara top up saldo via API?

Top up saldo tidak tersedia via API — harus dilakukan manual melalui dashboard di smscode.gg. Untuk automation, monitor saldo via endpoint /v1/balance dan set alerting kalau saldo di bawah threshold.

Apakah ada SDK resmi untuk bahasa pemrograman tertentu?

Ada. SDK resmi JavaScript dan Python menyediakan resource order, helper polling, tipe webhook, serta field otp_message dan sms_revision. Lihat dokumentasi API untuk tautan paket dan contoh terbaru.

Berapa lama data order tersimpan?

Data order tersimpan di sistem SMSCode untuk keperluan audit dan dispute. Kamu bisa akses riwayat order via dashboard. Untuk keperluan audit internal kamu sendiri, simpan log order ID dan hasilnya di database atau log system kamu sendiri.

Bagaimana cara handle kalau OTP tidak masuk?

Setelah polling timeout, baca ulang order. Jika otp_message terisi tetapi otp_code null, tampilkan isi pesan SMS kepada pengguna; SMS tersebut tetap billable. Hanya panggil POST /v1/orders/cancel jika capability can_cancel dari server bernilai true. Jika tidak ada SMS hingga order EXPIRED, saldo dikembalikan otomatis.


Siap mulai integrasi? Daftar gratis di SMSCode, top up saldo minimal Rp 10.000, dan langsung test API dengan contoh-contoh di atas. Cek halaman pricing untuk lihat harga per layanan dan negara, atau baca panduan mengenal SMSCode untuk gambaran umum layanan. Kalau butuh jumlah order skala besar, hubungi tim SMSCode untuk enterprise pricing.

Siap mencoba SMSCode?

Buat akun dan dapatkan nomor virtual pertamamu dalam dua menit.

Mulai sekarang →