SMSCode API Geliştirici Rehberi: SMS Doğrulamasını Otomatize Edin

SMSCode API Geliştirici Rehberi: SMS Doğrulamasını Otomatize Edin

TL;DR: SMSCode API, SMS doğrulama akışlarını tamamen otomatize etmenizi sağlar. REST tabanlı bu API ile numara kiralayabilir, gelen SMS’leri okuyabilir ve numaraları serbest bırakabilirsiniz. Bearer token ile kimlik doğrulama, anında aktivasyon ve otomatik iade mevcut. Üç temel endpoint yeterlidir.


Web panelinden manuel numara kiralama, tek seferlik işlemler için gayet uygundur. Ancak büyük hacimde SMS doğrulaması yapıyorsanız, otomatik test akışları kuruyorsanız ya da ürününüze SMS doğrulama özelliği entegre etmek istiyorsanız, API kullanımı kaçınılmazdır.

SMSCode API, geliştiricilere odaklanarak tasarlanmış minimal ve güçlü bir REST arayüzüdür. Bu rehberde API’yi en başından ele alıyoruz: kimlik doğrulama, temel üç endpoint akışı, Python ve JavaScript örnekleri, hata yönetimi, rate limiting ve üretim ortamı için öneriler. Bu rehberi bitirdiğinizde, kendi entegrasyonunuzu sıfırdan yazabilecek bilgiye sahip olacaksınız.

API’ye Başlamadan Önce: Gereksinimler

Hesap ve API Anahtarı

Henüz hesabınız yoksa SMSCode’a kayıt olun. Kayıt yalnızca e-posta gerektirir, abonelik yoktur.

Hesap oluşturduktan sonra:

  1. Dashboard’a giriş yapın
  2. Sağ üst menüden Hesap Ayarları bölümüne gidin
  3. API Anahtarı sekmesini açın
  4. “Yeni API Anahtarı Oluştur” butonuna tıklayın
  5. Anahtarı hemen kopyalayın ve güvenli bir yerde saklayın

Önemli güvenlik notu: API anahtarı yalnızca oluşturulduğu anda tam olarak görüntülenir. Kaybederseniz iptal edip yenisini oluşturmanız gerekir. Anahtarı kaynak koduna, Git commit geçmişine veya log dosyasına yazmayın. Ortam değişkeni (environment variable) veya bir secrets yönetim sistemi (HashiCorp Vault, AWS Secrets Manager) kullanın.

Base URL ve Kimlik Doğrulama

Tüm API istekleri şu base URL’ye yapılır:

https://api.smscode.gg/v1

Her istekte kimlik doğrulama için Authorization başlığı zorunludur:

Authorization: Bearer YOUR_API_KEY

POST ve PATCH isteklerinde içerik tipi başlığı da eklenmelidir:

Content-Type: application/json

Temel API Akışı: Üç Endpoint, Üç Adım

SMS doğrulama otomasyonunun tüm akışı üç adıma sığar:

1. POST   /orders            → Numara kirala
2. GET    /orders/{id}/sms   → SMS bekle ve oku
3. DELETE /orders/{id}       → Numarayı serbest bırak

Bu minimalist yapı kasıtlıdır — öğrenme eğrisini düşürmek ve entegrasyonu hızlandırmak için.

Adım 1: Numara Kiralama

Belirli bir platform ve ülke için numara kiralamak üzere POST isteği gönderin:

POST /v1/orders
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
  "service": "google",
  "country": "tr"
}

Başarılı yanıt (HTTP 200):

{
  "success": true,
  "data": {
    "id": "ord_01J8X...",
    "phone": "+905551234567",
    "country": "tr",
    "service": "google",
    "status": "active",
    "expires_at": "2026-03-16T14:35:00Z"
  }
}

Yanıttaki alan açıklamaları:

  • id: Sonraki adımlarda kullanacağınız sipariş kimliği. Kayıt altına alın.
  • phone: Platforma gireceksiniz tam telefon numarası. Ülke kodu dahil.
  • expires_at: Numaranın geçerlilik süresi. Genellikle 20 dakika. Bu süre içinde SMS gelmezse otomatik iade yapılır.

Desteklenen Ülke Kodları

ISO 3166-1 alpha-2 formatında ülke kodu kullanılır:

KodÜlkeYaygın Kullanım
trTürkiyeWhatsApp, Trendyol, yerel platformlar
usABDGoogle, OpenAI, büyük küresel platformlar
uaUkraynaTelegram, WhatsApp (ekonomik)
plPolonyaInstagram, WhatsApp (Avrupa)
deAlmanyaKripto borsaları, fintech
gbİngiltereFintech, bankacılık uygulamaları
ruRusyaTelegram, VK
brBrezilyaWhatsApp, Mercado Libre

Tam liste ve güncel stok durumu için sanal numara kataloğuna bakın.

Desteklenen Platform (service) Kodları

Platform kodu, numarayı hangi hizmet için kullanacağınızı belirtir:

  • Sosyal medya: google, whatsapp, telegram, instagram, facebook, twitter, tiktok, snapchat
  • Teknoloji: openai, steam, discord, spotify, netflix, apple
  • Kripto/Finans: binance, coinbase, kraken, paypal, wise
  • E-ticaret: amazon, ebay

Tam platform listesi API dokümantasyonundan veya GET /v1/catalog endpoint’inden alınabilir.

Adım 2: SMS Bekleme ve Okuma

Numarayı platforma girdikten sonra OTP kodunu beklemek için bu endpoint’i düzenli aralıklarla sorgulayın (polling):

GET /v1/orders/ord_01J8X.../sms
Authorization: Bearer YOUR_API_KEY

SMS henüz gelmediğinde (HTTP 200):

{
  "success": true,
  "data": {
    "sms": null,
    "status": "waiting"
  }
}

SMS geldiğinde (HTTP 200):

{
  "success": true,
  "data": {
    "sms": {
      "body": "Your Google verification code is 847291. Don't share it with anyone.",
      "received_at": "2026-03-16T14:32:15Z"
    },
    "status": "received"
  }
}

Polling Stratejisi

Üretim ortamında önerilen polling aralığı 3–5 saniye’dir.

  • 3 saniyeden kısa aralıklar: Rate limit riskini artırır, ek hız sağlamaz
  • 10 saniyeden uzun aralıklar: OTP kodları zaman sınırlıdır (genellikle 5–10 dakika); geç polling kod süresi dolmadan önce işlemi tamamlayamayabilir

Python’da polling örneği:

import time
import requests

API_KEY = "your_api_key_here"  # Gerçekte os.environ.get("SMSCODE_API_KEY") kullanın
BASE_URL = "https://api.smscode.gg/v1"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

def wait_for_sms(order_id, timeout=120, interval=3):
    """
    SMS gelene kadar bekle.

    Args:
        order_id: Sipariş kimliği
        timeout: Toplam bekleme süresi (saniye)
        interval: Sorgulama aralığı (saniye)

    Returns:
        SMS içeriği (str) veya None (timeout'ta)
    """
    deadline = time.time() + timeout
    while time.time() < deadline:
        response = requests.get(
            f"{BASE_URL}/orders/{order_id}/sms",
            headers=HEADERS
        )
        response.raise_for_status()

        data = response.json()["data"]
        if data["sms"]:
            return data["sms"]["body"]

        time.sleep(interval)

    return None  # Timeout

OTP Kodu Çıkarma

SMS içeriğinden OTP kodunu ayıklamak için düzenli ifade (regex) kullanın:

import re

def extract_otp(sms_body, min_digits=4, max_digits=8):
    """
    SMS içeriğinden OTP kodunu çıkar.

    Yaygın OTP formatları: 4 haneli, 5 haneli, 6 haneli, 8 haneli
    """
    # Önce sayı-harf kombinasyonunu (alfanümerik OTP) dene
    alphanumeric = re.search(r'\b[A-Z0-9]{6,8}\b', sms_body)
    if alphanumeric and not alphanumeric.group().isdigit():
        return alphanumeric.group()

    # Yalnızca rakamlardan oluşan blok ara
    pattern = rf'\b\d{{{min_digits},{max_digits}}}\b'
    match = re.search(pattern, sms_body)
    return match.group() if match else None

Adım 3: Numara Serbest Bırakma

İşiniz bittiğinde — başarılı da olsa başarısız da olsa — numarayı serbest bırakın:

DELETE /v1/orders/ord_01J8X...
Authorization: Bearer YOUR_API_KEY

Yanıt:

{
  "success": true,
  "data": {
    "status": "cancelled",
    "refunded": false
  }
}
  • refunded: false: SMS başarıyla alındı, ücret kesildi
  • refunded: true: SMS alınmadan iptal edildi, bakiye iade edildi

Numarayı her zaman serbest bırakın. Bu, iki önemli nedenden dolayı kritiktir:

  1. Iade doğruluğu: Başarısız işlemlerde otomatik iade ancak iptal isteğiyle tetiklenir
  2. Numara havuzu kalitesi: Serbest bırakılmayan numaralar havuzu kirletir; hizmet kalitesini düşürür

Tam Entegrasyon Örneği: Python

import time
import re
import os
import requests
from contextlib import contextmanager

API_KEY = os.environ.get("SMSCODE_API_KEY")
if not API_KEY:
    raise ValueError("SMSCODE_API_KEY ortam değişkeni tanımlı değil")

BASE_URL = "https://api.smscode.gg/v1"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}


def rent_number(service: str, country: str = "tr") -> dict:
    """Belirtilen platform ve ülke için numara kirala."""
    response = requests.post(
        f"{BASE_URL}/orders",
        headers=HEADERS,
        json={"service": service, "country": country}
    )
    response.raise_for_status()
    return response.json()["data"]


def wait_for_sms(order_id: str, timeout: int = 120) -> str | None:
    """SMS gelene kadar bekle, timeout'ta None döndür."""
    deadline = time.time() + timeout
    while time.time() < deadline:
        response = requests.get(
            f"{BASE_URL}/orders/{order_id}/sms",
            headers=HEADERS
        )
        response.raise_for_status()
        data = response.json()["data"]

        if data.get("sms"):
            return data["sms"]["body"]

        time.sleep(3)

    return None


def release_number(order_id: str) -> None:
    """Numarayı her durumda serbest bırak."""
    try:
        requests.delete(
            f"{BASE_URL}/orders/{order_id}",
            headers=HEADERS
        )
    except Exception:
        pass  # Serbest bırakma başarısız olursa sessizce geç


def extract_otp(sms_body: str) -> str | None:
    """SMS içeriğinden OTP kodunu çıkar."""
    match = re.search(r'\b\d{4,8}\b', sms_body)
    return match.group() if match else None


@contextmanager
def sms_session(service: str, country: str = "tr"):
    """
    SMS doğrulama oturumu context manager.

    Kullanım:
        with sms_session("google", "tr") as (phone, get_code):
            # platform.register(phone)
            code = get_code()
    """
    order = rent_number(service, country)
    order_id = order["id"]
    phone = order["phone"]

    def get_code(timeout: int = 120) -> str | None:
        sms = wait_for_sms(order_id, timeout)
        return extract_otp(sms) if sms else None

    try:
        yield phone, get_code
    finally:
        release_number(order_id)


# Kullanım örneği
if __name__ == "__main__":
    with sms_session("google", "tr") as (phone, get_code):
        print(f"Numara: {phone}")

        # Buraya Google kayıt kodu gelir
        # google_signup(phone)

        otp = get_code(timeout=120)
        if otp:
            print(f"OTP kodu: {otp}")
            # google_verify(otp)
        else:
            print("SMS alınamadı, numara otomatik iade edilecek")

Tam Entegrasyon Örneği: JavaScript/Node.js

const axios = require('axios');

const API_KEY = process.env.SMSCODE_API_KEY;
if (!API_KEY) throw new Error('SMSCODE_API_KEY ortam değişkeni tanımlı değil');

const BASE_URL = 'https://api.smscode.gg/v1';
const headers = {
  'Authorization': `Bearer ${API_KEY}`,
  'Content-Type': 'application/json'
};

async function rentNumber(service, country = 'tr') {
  const { data } = await axios.post(
    `${BASE_URL}/orders`,
    { service, country },
    { headers }
  );
  return data.data;
}

async function waitForSMS(orderId, timeout = 120000, interval = 3000) {
  const deadline = Date.now() + timeout;
  while (Date.now() < deadline) {
    const { data } = await axios.get(
      `${BASE_URL}/orders/${orderId}/sms`,
      { headers }
    );
    if (data.data.sms) {
      return data.data.sms.body;
    }
    await new Promise(r => setTimeout(r, interval));
  }
  return null;
}

async function releaseNumber(orderId) {
  try {
    await axios.delete(`${BASE_URL}/orders/${orderId}`, { headers });
  } catch (_) {
    // Serbest bırakma başarısız olsa da devam et
  }
}

function extractOTP(smsBody) {
  const match = smsBody.match(/\b\d{4,8}\b/);
  return match ? match[0] : null;
}

async function withSMSSession(service, country, callback) {
  const order = await rentNumber(service, country);
  const { id: orderId, phone } = order;

  const getCode = (timeout = 120000) =>
    waitForSMS(orderId, timeout).then(sms => sms ? extractOTP(sms) : null);

  try {
    return await callback(phone, getCode);
  } finally {
    await releaseNumber(orderId);
  }
}

// Kullanım örneği
(async () => {
  await withSMSSession('google', 'tr', async (phone, getCode) => {
    console.log(`Numara: ${phone}`);

    // Buraya platform kayıt kodu gelir
    // await googleSignup(phone);

    const otp = await getCode();
    if (otp) {
      console.log(`OTP kodu: ${otp}`);
      // await googleVerify(otp);
    } else {
      console.log('SMS alınamadı');
    }
  });
})();

Hata Yönetimi

API her hata için tutarlı bir JSON yapısı döndürür:

{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Bakiye yetersiz"
  }
}

Yaygın hata kodları ve çözüm yolları:

HTTP KoduHata KoduNedenÇözüm
402INSUFFICIENT_BALANCEBakiye yetersizDashboard’dan bakiye yükleyin
404NO_NUMBERS_AVAILABLESeçilen ülke/platform için stok yokFarklı ülke veya bekleme stratejisi deneyin
404ORDER_NOT_FOUNDGeçersiz ya da silinmiş siparişID’yi kontrol edin
410ORDER_EXPIREDNumara kiralama süresi dolduYeni numara kiralayın
429RATE_LIMIT_EXCEEDEDÇok fazla istekPolling aralığını artırın, backoff uygulayın
400INVALID_SERVICEGeçersiz platform koduKatalogdan geçerli kodu alın
400INVALID_COUNTRYGeçersiz ülke koduISO 3166-1 alpha-2 kullanın
401UNAUTHORIZEDAPI anahtarı geçersiz veya eksikAnahtarı kontrol edin

Kapsamlı hata yönetimi örneği (Python):

class SMSCodeError(Exception):
    def __init__(self, code: str, message: str, http_status: int):
        self.code = code
        self.message = message
        self.http_status = http_status
        super().__init__(f"[{http_status}] {code}: {message}")


def rent_number_safe(service: str, country: str, fallback_countries: list = None) -> dict:
    """
    Retry ve fallback destekli numara kiralama.

    Args:
        service: Platform kodu
        country: Birincil ülke kodu
        fallback_countries: Stok yoksa deneyecek alternatif ülkeler
    """
    countries_to_try = [country] + (fallback_countries or [])

    for attempt_country in countries_to_try:
        try:
            return rent_number(service, attempt_country)
        except requests.HTTPError as e:
            error_data = e.response.json().get("error", {})
            error_code = error_data.get("code", "UNKNOWN")

            if error_code == "NO_NUMBERS_AVAILABLE":
                # Stok yok — sonraki ülkeyi dene
                continue
            elif error_code == "INSUFFICIENT_BALANCE":
                raise SMSCodeError(
                    code=error_code,
                    message="Bakiye yetersiz — lütfen bakiye yükleyin",
                    http_status=402
                )
            else:
                raise

    raise SMSCodeError(
        code="NO_NUMBERS_AVAILABLE",
        message=f"Hiçbir ülkede numara bulunamadı: {countries_to_try}",
        http_status=404
    )


# Kullanım
try:
    order = rent_number_safe(
        service="google",
        country="tr",
        fallback_countries=["de", "pl", "us"]
    )
except SMSCodeError as e:
    if e.code == "INSUFFICIENT_BALANCE":
        # Bakiye yükleme akışını başlat
        pass
    else:
        raise

Rate Limiting

API, dakika başına istek sayısını sınırlar. Yanıt başlıklarında mevcut limit durumu yer alır:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1710596400

X-RateLimit-Remaining sıfıra yaklaştığında polling aralığını artırın. X-RateLimit-Reset Unix timestamp formatında limitlerin yenilenme zamanını gösterir.

Exponential backoff ile retry (Python):

import time
import random

def rent_with_retry(service: str, country: str, max_retries: int = 3) -> dict:
    """Geçici hatalar için exponential backoff ile yeniden deneme."""
    for attempt in range(max_retries):
        try:
            return rent_number(service, country)
        except requests.HTTPError as e:
            if e.response.status_code == 429:
                # Rate limit — bekle ve tekrar dene
                wait = (2 ** attempt) + random.uniform(0, 1)  # Jitter ekle
                time.sleep(wait)
            elif e.response.status_code in (500, 502, 503, 504):
                # Geçici sunucu hatası — bekle ve tekrar dene
                time.sleep(2 ** attempt)
            else:
                raise  # Kalıcı hata — yeniden deneme yapma

    raise RuntimeError(f"{max_retries} denemede başarısız olundu")

Bakiye Yönetimi

API ile bakiye durumunu programatik olarak takip edebilirsiniz:

GET /v1/balance
Authorization: Bearer YOUR_API_KEY

Yanıt:

{
  "success": true,
  "data": {
    "balance": "12.50",
    "currency": "USD"
  }
}

Otomatik bakiye uyarısı (Python):

import smtplib  # Ya da tercih ettiğiniz bildirim servisini kullanın

BALANCE_THRESHOLD = 5.0  # USD cinsinden uyarı eşiği

def check_balance_and_alert():
    response = requests.get(f"{BASE_URL}/balance", headers=HEADERS)
    response.raise_for_status()

    balance = float(response.json()["data"]["balance"])

    if balance < BALANCE_THRESHOLD:
        print(f"UYARI: Bakiye düşük! Mevcut: ${balance:.2f}")
        # E-posta veya Slack bildirimi gönderin

    return balance

Üretim Ortamı için En İyi Pratikler

Yapılandırma yönetimi:

API anahtarınızı ve diğer hassas değerleri ortam değişkenleri olarak saklayın. Python için python-dotenv, Node.js için dotenv kütüphanelerini kullanabilirsiniz. Bulut ortamlarında (AWS, GCP, Azure) yerel secret manager servislerini tercih edin.

Loglama stratejisi:

Her numara kiralama ve SMS alma işlemini loglayın. Ancak log satırlarında API anahtarını ve OTP kodunu asla yazmayın:

import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def rent_number_logged(service: str, country: str) -> dict:
    logger.info(f"Numara kiralama başlıyor: service={service}, country={country}")
    order = rent_number(service, country)
    logger.info(f"Numara kiralandı: order_id={order['id']}, country={country}")
    return order

Eşzamanlılık yönetimi:

Paralel olarak birden fazla numara kiralamak istiyorsanız, Python’da asyncio veya concurrent.futures, Node.js’de Promise.all kullanabilirsiniz. Ancak eşzamanlı aktif sipariş sayısına dikkat edin — çok sayıda paralel istek rate limit’e takılabilir.

Ülke fallback stratejisi:

Belirli bir ülkede stok bittiğinde otomatik olarak alternatif ülkeye geçmek, otomasyon kesintisini önler. Yaygın fallback zinciri: tr → ua → pl → de → us

Monitoring ve alerting:

Üretim sistemlerinde başarı oranını, ortalama SMS teslimat süresini ve hata oranını izleyin. Başarı oranı belirli bir eşiğin altına düştüğünde uyarı alın.

Kurumsal Kullanım Senaryoları

Otomatik test altyapısı:

Yazılım geliştirme süreçlerinde SMS doğrulama içeren akışları CI/CD pipeline’ına entegre etmek için ideal. Her test çalışmasında gerçek numara kullanılır, test biter bitmez numara iade edilir. Manuel müdahale sıfıra iner.

# pytest test örneği
import pytest

@pytest.fixture
def verified_account():
    with sms_session("google", "tr") as (phone, get_code):
        account = google_api.create_account(phone)
        code = get_code()
        assert code is not None, "SMS kodu alınamadı"
        google_api.verify(account, code)
        yield account
        # Fixture bittikten sonra hesap temizleme
        google_api.delete_account(account)

Müşteri onboarding otomasyonu:

Toplu müşteri hesabı oluşturma süreçlerinde her kullanıcı için ayrı SMS doğrulaması gerekiyorsa API kullanımı tek pratik yoldur.

Pazar araştırması:

Farklı ülke numaralarıyla platform davranışlarını test etmek, bölgesel fiyat veya içerik farklılıklarını analiz etmek için kullanılır.

Güvenlik testi:

Kendi uygulamanızın SMS doğrulama akışlarını gerçekçi test verileriyle doğrulamak için.

FAQ

API anahtarım ele geçirilirse ne yapmalıyım?

Hesap ayarlarından API anahtarını hemen iptal edin ve yeni bir tane oluşturun. İptal işlemi anlıktır — eski anahtar derhal çalışmaz hale gelir. Anahtarı kaynak koduna, commit geçmişine veya log dosyasına yazmayın. .env dosyası + .gitignore kombinasyonu minimum güvenlik gerekliliğidir. Git geçmişinizde anahtar varsa, geçmişi yeniden yazmak yerine anahtarı iptal etmek çok daha pratiktir.

Aynı anda kaç paralel sipariş verilebilir?

Hesap bakiyesi ve hesap limiti kısıtlar. Standart hesaplarda orta düzey eşzamanlılık desteklenir. 50’den fazla paralel sipariş veya kurumsal hacimde otomasyon ihtiyacı için destek ekibiyle iletişime geçin.

API Webhook destekliyor mu?

Mevcut sürümde polling tabanlı SMS okuma destekleniyor. Webhook desteği için güncel API dokümantasyonunu ve değişiklik günlüğünü takip edin.

SMS Activate uyumlu API ile SMSCode arasındaki fark nedir?

Bu rehberde açıklanan api.smscode.gg/v1 endpointleri, SMSCode’un modern REST API’sidir. Bunun yanı sıra SMSCode, SMS Activate uyumlu bir eski API formatını da destekler. SMS Activate uyumlu kütüphaneler kullananlar için geçiş yapmadan SMSCode’u kullanmak mümkündür; ancak modern REST API daha temiz, daha öngörülebilir ve daha iyi dokümante edilmiştir.

API test ortamı (sandbox) var mı?

Küçük bir bakiye ile gerçek ortamda test yapabilirsiniz. Başarısız numara denemeleri otomatik iade edildiğinden test maliyeti oldukça düşük kalır. Güncel sandbox durumu için API dokümantasyonunu kontrol edin.

Polling yerine SMS’i daha hızlı almak için ne yapılabilir?

Polling aralığını 3 saniyeye düşürebilirsiniz — bu genellikle yeterlidir çünkü çoğu platform SMS’i 10-30 saniye içinde iletir. Daha agresif polling rate limit’e takılır. Webhook desteği geldiğinde push bildirimi mümkün olacak ve polling tamamen ortadan kalkacak.

SMSCode'i denemeye hazır mısınız?

Hesap oluşturun ve ilk sanal numaranızı iki dakikadan kısa sürede alın.

Başlayın →