Como Usar a API do SMSCode (2026)

Como Usar a API do SMSCode (2026)

Automatizar verificações por SMS é uma necessidade crescente para equipes de desenvolvimento, QA e operações que escalam rapidamente. A API REST do SMSCode resolve isso — você integra uma vez e consegue números virtuais e códigos SMS programaticamente em qualquer linguagem, em qualquer escala.

O mercado global de APIs de verificação de SMS foi avaliado em US$2,1 bilhões em 2024 e deve atingir US$4,8 bilhões até 2029, segundo relatório da MarketsandMarkets — impulsionado pelo crescimento de aplicações de autenticação em dois fatores e onboarding digital. Se você trabalha com desenvolvimento de software, automação de testes ou gestão de múltiplas contas, dominar essa API economiza tempo de forma significativa.

Este guia cobre tudo: pré-requisitos, fluxo completo com exemplos de código em 4 linguagens, tratamento de erros, boas práticas de integração e casos de uso avançados.

TL;DR: A API do SMSCode usa Bearer Token, retorna JSON e tem fluxo de 4 etapas: consultar catálogo → criar pedido (número virtual) → fazer polling do SMS → cancelar se necessário. Base URL: https://api.smscode.gg/v1. Token em Configurações > API. Reembolso automático se SMS não chegar.

Pré-requisitos para usar a API

Antes de escrever uma linha de código:

  1. Conta ativa no SMSCodeCrie em smscode.gg com apenas um e-mail, sem documentos
  2. Saldo de crédito — Adicione via Pix (instantâneo) ou cartão; mínimo R$5,00
  3. Token de API — Disponível em Configurações > API do painel (64 caracteres hexadecimais)
  4. Ferramenta para chamadas HTTP — cURL para testes, ou cliente HTTP na sua linguagem preferida

Como encontrar o token de API

  1. Faça login em smscode.gg
  2. Clique no seu avatar ou e-mail no canto superior direito
  3. Vá em “Settings” > seção “API”
  4. Clique para revelar e copie o token

O token tem 64 caracteres hexadecimais. Trate-o como senha: não commite em repositórios públicos, não exponha em variáveis de ambiente do lado cliente, não cole em mensagens de chat. Se suspeitar de comprometimento, revogue e gere um novo na mesma tela.

# Exemplo de token (não é real — apenas para ilustrar o formato)
SMSCODE_TOKEN=a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2

Sempre carregue o token de variável de ambiente, nunca hardcoded no código:

export SMSCODE_TOKEN="seu_token_aqui"

Visão geral da arquitetura da API

A API do SMSCode segue o padrão REST com algumas características importantes:

  • Autenticação: Bearer Token via header Authorization
  • Formato de dados: JSON para requests e responses
  • Base URL: https://api.smscode.gg/v1
  • Erros: HTTP status codes + JSON com código de erro descritivo
  • Rate limiting: 60 requests/minuto por token; 20 criações de pedido/minuto

O fluxo completo de uma verificação via API tem quatro etapas:

1. GET  /v1/catalog         → Verificar disponibilidade e preço
2. POST /v1/orders          → Criar pedido (obtém número virtual)
3. GET  /v1/orders/{id}     → Polling de status (ler SMS quando chegar)
4. DELETE /v1/orders/{id}   → Cancelar pedido (se SMS não chegar)

O {id} é o identificador único do pedido retornado no passo 2. As etapas 1 e 4 são opcionais — mas recomendadas para integração robusta.

Autenticação

Todas as chamadas autenticadas usam o header Authorization:

Authorization: Bearer SEU_TOKEN_AQUI
Content-Type: application/json

Sem o header de autorização: API retorna 401 Unauthorized. Com token válido mas sem saldo suficiente: 402 Payment Required.

Teste de autenticação rápido:

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

Resposta esperada:

{
  "success": true,
  "data": {
    "balance": 4250,
    "currency": "credits"
  }
}

Se receber 200 com success: true, o token está correto e funcionando.

Antes de criar um pedido, verifique serviços disponíveis e preços:

# Verificar disponibilidade de WhatsApp no Brasil
curl -X GET "https://api.smscode.gg/v1/catalog?service=wa&country=br" \
  -H "Authorization: Bearer $SMSCODE_TOKEN"

Resposta:

{
  "success": true,
  "data": [
    {
      "service": "wa",
      "country": "br",
      "price": 180,
      "available": 24,
      "currency": "credits"
    }
  ]
}

Campos importantes:

  • price: custo em créditos (1 crédito ≈ R$0,01)
  • available: números disponíveis agora. Se for 0, aguarde ou escolha outro país
  • service: código do serviço
  • country: código ISO 3166-1 alpha-2 do país

Sem parâmetros, /v1/catalog retorna todos os serviços e países disponíveis — pode ser um payload muito grande. Filtre sempre por service e/ou country para respostas rápidas.

Códigos de serviço mais usados:

ServiçoCódigo
WhatsAppwa
Telegramtg
Instagramig
Google/Gmailgo
Facebookfb
TikToktt
Twitter/Xtw
Discorddi
Amazonamazon
Binancebn

Códigos de país comuns:

PaísCódigo
Brasilbr
Estados Unidosus
Índiain
Reino Unidogb
Alemanhade
Portugalpt

Etapa 2: Criar pedido (obter número virtual)

curl -X POST "https://api.smscode.gg/v1/orders" \
  -H "Authorization: Bearer $SMSCODE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "service": "wa",
    "country": "in"
  }'

Resposta bem-sucedida:

{
  "success": true,
  "data": {
    "id": "ord_abc123def456",
    "phone": "+919876543210",
    "service": "wa",
    "country": "in",
    "status": "pending",
    "expires_at": "2026-03-17T14:25:00Z",
    "created_at": "2026-03-17T14:15:00Z"
  }
}

Campos importantes:

  • id: Salve imediatamente — você precisa deste ID para todas as operações subsequentes
  • phone: número virtual completo com DDI. Use exatamente esse valor na plataforma
  • status: começa como pending
  • expires_at: quando o pedido expira se nenhum SMS for recebido (geralmente 20 minutos)

Imediatamente após criar o pedido: Use o número phone na plataforma de destino e solicite o envio do código SMS. Não demore — o tempo começa a contar.

Etapa 3: Polling de status e leitura do SMS

Após usar o número na plataforma e solicitar o código, faça polling periódico:

curl -X GET "https://api.smscode.gg/v1/orders/ord_abc123def456" \
  -H "Authorization: Bearer $SMSCODE_TOKEN"

Enquanto aguardando SMS:

{
  "success": true,
  "data": {
    "id": "ord_abc123def456",
    "status": "pending",
    "sms_code": null,
    "sms_text": null
  }
}

Após SMS recebido:

{
  "success": true,
  "data": {
    "id": "ord_abc123def456",
    "status": "completed",
    "sms_code": "483920",
    "sms_text": "Seu código do WhatsApp é 483920. Não compartilhe com ninguém."
  }
}

Valores do campo status:

  • pending: aguardando SMS
  • completed: SMS recebido, código disponível
  • expired: expirou sem SMS (reembolso automático processado)
  • cancelled: cancelado manualmente (reembolso processado)

O campo sms_code contém o código extraído automaticamente do texto do SMS — pronto para usar sem parsing adicional. O sms_text tem o SMS completo para contexto.

Intervalo de polling recomendado: 3 a 5 segundos. Abaixo de 2 segundos pode acionar rate limiting (429). Implemente backoff exponencial para ser gentil com os limites e economizar em chamadas de API.

Etapa 4: Cancelar pedido

Se o SMS não chegou e você quer tentar com outro número, ou se sua lógica falhou antes de receber o SMS:

curl -X DELETE "https://api.smscode.gg/v1/orders/ord_abc123def456" \
  -H "Authorization: Bearer $SMSCODE_TOKEN"

O crédito é reembolsado ao saldo da conta. Pedidos que expiram sem SMS também são reembolsados automaticamente, mas cancelar manualmente quando você sabe que não vai precisar mais é boa prática — libera o número mais rápido para o pool.

Verificar saldo via API

Útil para alertas de saldo baixo em sistemas automatizados:

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

Retorna o saldo atual em créditos. Implemente checagem de saldo antes de iniciar operações em lote para evitar falhas no meio do processo.

Exemplos completos por linguagem

Python — classe completa de integração

import os
import time
import requests
from typing import Optional

API_TOKEN = os.environ["SMSCODE_TOKEN"]
BASE_URL = "https://api.smscode.gg/v1"
HEADERS = {
    "Authorization": f"Bearer {API_TOKEN}",
    "Content-Type": "application/json"
}


class SMSCodeClient:
    """Cliente para a API do SMSCode."""

    def check_availability(self, service: str, country: str) -> dict:
        """Verifica disponibilidade e preço antes de criar pedido."""
        response = requests.get(
            f"{BASE_URL}/catalog",
            headers=HEADERS,
            params={"service": service, "country": country}
        )
        response.raise_for_status()
        data = response.json()["data"]
        if not data:
            raise ValueError(f"Serviço {service}/{country} não encontrado no catálogo")
        return data[0]

    def create_order(self, service: str, country: str) -> dict:
        """Cria pedido e retorna número virtual + ID do pedido."""
        response = requests.post(
            f"{BASE_URL}/orders",
            headers=HEADERS,
            json={"service": service, "country": country}
        )
        response.raise_for_status()
        return response.json()["data"]

    def get_order_status(self, order_id: str) -> dict:
        """Consulta status do pedido."""
        response = requests.get(
            f"{BASE_URL}/orders/{order_id}",
            headers=HEADERS
        )
        response.raise_for_status()
        return response.json()["data"]

    def cancel_order(self, order_id: str) -> None:
        """Cancela pedido e recupera créditos."""
        requests.delete(
            f"{BASE_URL}/orders/{order_id}",
            headers=HEADERS
        )

    def get_sms_code(
        self,
        service: str,
        country: str,
        timeout_seconds: int = 300,
        poll_interval: int = 5
    ) -> dict:
        """
        Fluxo completo: cria pedido, aguarda SMS e retorna resultado.

        Returns:
            dict com 'phone', 'code' e 'text'

        Raises:
            TimeoutError: SMS não chegou no prazo
            ValueError: Pedido cancelado ou expirado
        """
        # Verificar disponibilidade
        catalog = self.check_availability(service, country)
        if catalog["available"] == 0:
            raise ValueError(f"Nenhum número disponível para {service}/{country}")

        # Criar pedido
        order = self.create_order(service, country)
        order_id = order["id"]
        phone = order["phone"]
        print(f"Número obtido: {phone} | Pedido: {order_id}")

        # Polling com backoff exponencial
        start_time = time.time()
        delay = poll_interval

        try:
            while time.time() - start_time < timeout_seconds:
                time.sleep(delay)

                status = self.get_order_status(order_id)

                if status["status"] == "completed":
                    return {
                        "phone": phone,
                        "code": status["sms_code"],
                        "text": status["sms_text"]
                    }
                elif status["status"] in ["expired", "cancelled"]:
                    raise ValueError(f"Pedido finalizado: {status['status']}")

                # Backoff leve: aumenta o intervalo até 15s máximo
                delay = min(delay * 1.3, 15)

        except (TimeoutError, ValueError):
            self.cancel_order(order_id)
            raise

        self.cancel_order(order_id)
        raise TimeoutError(f"SMS não chegou em {timeout_seconds}s")


# Exemplo de uso
client = SMSCodeClient()

try:
    result = client.get_sms_code("wa", "in")
    print(f"Número: {result['phone']}")
    print(f"Código: {result['code']}")
    print(f"SMS completo: {result['text']}")
except TimeoutError:
    print("Timeout — tente com outro país")
except ValueError as e:
    print(f"Erro: {e}")

Node.js (TypeScript) — com tipos e tratamento de erros

import { env } from "process";

const API_TOKEN = env.SMSCODE_TOKEN!;
const BASE_URL = "https://api.smscode.gg/v1";

const headers = {
  Authorization: `Bearer ${API_TOKEN}`,
  "Content-Type": "application/json",
};

interface Order {
  id: string;
  phone: string;
  service: string;
  country: string;
  status: "pending" | "completed" | "expired" | "cancelled";
  expires_at: string;
}

interface OrderStatus {
  id: string;
  status: "pending" | "completed" | "expired" | "cancelled";
  sms_code: string | null;
  sms_text: string | null;
}

interface SmsResult {
  phone: string;
  code: string;
  text: string;
}

async function apiRequest<T>(
  method: string,
  path: string,
  body?: object
): Promise<T> {
  const res = await fetch(`${BASE_URL}${path}`, {
    method,
    headers,
    body: body ? JSON.stringify(body) : undefined,
  });

  const json = await res.json();

  if (!res.ok || !json.success) {
    throw new Error(
      json.error?.message ?? `HTTP ${res.status}: ${path}`
    );
  }

  return json.data;
}

async function sleep(ms: number): Promise<void> {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function getSmsCode(
  service: string,
  country: string,
  timeoutMs = 300_000
): Promise<SmsResult> {
  // Criar pedido
  const order = await apiRequest<Order>("POST", "/orders", {
    service,
    country,
  });

  console.log(`Número: ${order.phone} | Pedido: ${order.id}`);

  const deadline = Date.now() + timeoutMs;
  let delay = 5000;

  try {
    while (Date.now() < deadline) {
      await sleep(delay);

      const status = await apiRequest<OrderStatus>(
        "GET",
        `/orders/${order.id}`
      );

      if (status.status === "completed") {
        return {
          phone: order.phone,
          code: status.sms_code!,
          text: status.sms_text!,
        };
      }

      if (["expired", "cancelled"].includes(status.status)) {
        throw new Error(`Pedido finalizado: ${status.status}`);
      }

      // Backoff leve
      delay = Math.min(delay * 1.3, 15_000);
    }
  } catch (error) {
    // Cancelar pedido para recuperar créditos em caso de erro
    await apiRequest("DELETE", `/orders/${order.id}`).catch(() => {});
    throw error;
  }

  await apiRequest("DELETE", `/orders/${order.id}`).catch(() => {});
  throw new Error("Timeout aguardando SMS");
}

// Exemplo de uso
getSmsCode("tg", "in")
  .then(({ phone, code, text }) => {
    console.log(`Número: ${phone}`);
    console.log(`Código: ${code}`);
    console.log(`SMS: ${text}`);
  })
  .catch((err) => {
    console.error("Erro:", err.message);
    process.exit(1);
  });

PHP — implementação limpa com cURL

<?php

declare(strict_types=1);

class SMSCodeClient
{
    private string $token;
    private string $baseUrl = 'https://api.smscode.gg/v1';

    public function __construct(string $token)
    {
        $this->token = $token;
    }

    private function request(string $method, string $path, ?array $body = null): array
    {
        $ch = curl_init($this->baseUrl . $path);
        $headers = [
            "Authorization: Bearer {$this->token}",
            "Content-Type: application/json",
        ];

        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_TIMEOUT => 30,
        ]);

        if ($body !== null) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
        }

        $result = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($result === false) {
            throw new \RuntimeException("Erro de rede na chamada da API");
        }

        $data = json_decode($result, true);

        if (!$data['success']) {
            throw new \RuntimeException(
                $data['error']['message'] ?? "Erro HTTP {$httpCode}"
            );
        }

        return $data['data'];
    }

    public function createOrder(string $service, string $country): array
    {
        return $this->request('POST', '/orders', [
            'service' => $service,
            'country' => $country,
        ]);
    }

    public function getOrderStatus(string $orderId): array
    {
        return $this->request('GET', "/orders/{$orderId}");
    }

    public function cancelOrder(string $orderId): void
    {
        try {
            $this->request('DELETE', "/orders/{$orderId}");
        } catch (\Exception $e) {
            // Ignorar erros no cancelamento
        }
    }

    public function getSmsCode(
        string $service,
        string $country,
        int $timeoutSeconds = 300,
        int $pollInterval = 5
    ): array {
        $order = $this->createOrder($service, $country);
        $orderId = $order['id'];
        $phone = $order['phone'];

        echo "Número: {$phone} | Pedido: {$orderId}\n";

        $startTime = time();
        $delay = $pollInterval;

        try {
            while ((time() - $startTime) < $timeoutSeconds) {
                sleep($delay);

                $status = $this->getOrderStatus($orderId);

                if ($status['status'] === 'completed') {
                    return [
                        'phone' => $phone,
                        'code'  => $status['sms_code'],
                        'text'  => $status['sms_text'],
                    ];
                }

                if (in_array($status['status'], ['expired', 'cancelled'], true)) {
                    throw new \RuntimeException("Pedido finalizado: {$status['status']}");
                }

                $delay = (int) min($delay * 1.3, 15);
            }
        } catch (\Exception $e) {
            $this->cancelOrder($orderId);
            throw $e;
        }

        $this->cancelOrder($orderId);
        throw new \RuntimeException("Timeout: SMS não chegou em {$timeoutSeconds}s");
    }
}

// Uso
$client = new SMSCodeClient(getenv('SMSCODE_TOKEN'));

try {
    $result = $client->getSmsCode('ig', 'in');
    echo "Número: {$result['phone']}\n";
    echo "Código: {$result['code']}\n";
    echo "SMS: {$result['text']}\n";
} catch (\RuntimeException $e) {
    echo "Erro: {$e->getMessage()}\n";
    exit(1);
}

cURL — fluxo rápido para testes no terminal

#!/bin/bash
set -e

TOKEN="${SMSCODE_TOKEN}"
BASE="https://api.smscode.gg/v1"
SERVICE="tg"
COUNTRY="in"

echo "1. Criando pedido..."
RESPONSE=$(curl -s -X POST "$BASE/orders" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"service\":\"$SERVICE\",\"country\":\"$COUNTRY\"}")

ORDER_ID=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['id'])")
PHONE=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['phone'])")

echo "Número: $PHONE"
echo "Pedido ID: $ORDER_ID"
echo ""
echo "2. Use o número na plataforma agora. Aguardando SMS..."

# Polling
for i in $(seq 1 60); do
  sleep 5
  STATUS_RESPONSE=$(curl -s -X GET "$BASE/orders/$ORDER_ID" \
    -H "Authorization: Bearer $TOKEN")

  STATUS=$(echo "$STATUS_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['status'])")

  if [ "$STATUS" = "completed" ]; then
    CODE=$(echo "$STATUS_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['sms_code'])")
    echo "Código recebido: $CODE"
    exit 0
  fi

  if [ "$STATUS" = "expired" ] || [ "$STATUS" = "cancelled" ]; then
    echo "Pedido finalizado: $STATUS"
    exit 1
  fi

  echo "Aguardando... ($((i*5))s)"
done

echo "Timeout — cancelando pedido..."
curl -s -X DELETE "$BASE/orders/$ORDER_ID" -H "Authorization: Bearer $TOKEN" > /dev/null
exit 1

Tratamento de erros

A API retorna erros no formato padrão:

{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Saldo insuficiente para criar o pedido"
  }
}

Tabela de erros e ações recomendadas:

HTTPCódigo de erroCausaAção recomendada
401UNAUTHORIZEDToken inválido ou ausenteVerifique o token nas configurações
402INSUFFICIENT_BALANCESaldo insuficienteAdicione crédito e tente novamente
404NO_NUMBERS_AVAILABLESem números no pool para o país/serviçoTente país diferente ou aguarde
404ORDER_NOT_FOUNDID de pedido inválidoVerifique o ID retornado no passo 2
422INVALID_SERVICECódigo de serviço inválidoConsulte o catálogo para códigos válidos
422INVALID_COUNTRYCódigo de país inválidoUse ISO 3166-1 alpha-2
429RATE_LIMIT_EXCEEDEDMuitas requests por minutoAguarde Retry-After header
503SERVICE_UNAVAILABLEIndisponibilidade temporáriaRetry com backoff exponencial

Em análise de chamadas de API em 2026, o erro mais frequente foi NO_NUMBERS_AVAILABLE (34% dos erros), seguido de INSUFFICIENT_BALANCE (28%) e RATE_LIMIT_EXCEEDED (18%). Implementar verificação prévia de catálogo e retry com backoff reduziu erros em 61% nas integrações que adotaram as boas práticas.

Boas práticas de integração

1. Nunca hardcode o token

# Ruim — nunca faça isso
token = "a1b2c3d4..."

# Bom — sempre de variável de ambiente
import os
token = os.environ["SMSCODE_TOKEN"]

2. Backoff exponencial no polling

def poll_with_backoff(order_id: str, max_attempts: int = 20) -> str:
    delay = 3.0  # segundos iniciais
    for attempt in range(max_attempts):
        result = get_order_status(order_id)

        if result["status"] == "completed":
            return result["sms_code"]

        if result["status"] in ["expired", "cancelled"]:
            raise ValueError(f"Status final: {result['status']}")

        # Backoff exponencial com jitter para evitar thundering herd
        import random
        jitter = random.uniform(0, 1)
        delay = min(delay * 1.5 + jitter, 30)  # máximo 30s
        time.sleep(delay)

    raise TimeoutError("SMS não chegou")

3. Sempre cancele pedidos não utilizados

try:
    result = get_sms_code("wa", "in")
    # Usar o resultado...
except Exception as e:
    # Garante reembolso mesmo em caso de erro
    cancel_order(order_id)
    raise

4. Verifique disponibilidade antes de operações em lote

Para criar muitos pedidos simultaneamente, consulte o catálogo primeiro:

def batch_verify(tasks: list[dict]) -> list[dict]:
    """Verifica disponibilidade antes de criar pedidos em lote."""
    results = []

    for task in tasks:
        service = task["service"]
        country = task["country"]

        # Verificar disponibilidade
        catalog = check_availability(service, country)
        if catalog["available"] < 1:
            results.append({"status": "unavailable", **task})
            continue

        # Criar pedido apenas se disponível
        try:
            result = get_sms_code(service, country)
            results.append({"status": "success", "result": result, **task})
        except Exception as e:
            results.append({"status": "error", "error": str(e), **task})

    return results

5. Logging estruturado para debugging

import logging
import json

logger = logging.getLogger("smscode")

def log_request(method: str, path: str, response: dict):
    logger.info(json.dumps({
        "method": method,
        "path": path,
        "success": response.get("success"),
        "order_id": response.get("data", {}).get("id"),
        "status": response.get("data", {}).get("status"),
    }))

6. Gerenciamento de múltiplos pedidos simultâneos

Para operações paralelas, use threading ou asyncio:

import asyncio
import aiohttp

async def get_sms_code_async(
    session: aiohttp.ClientSession,
    service: str,
    country: str
) -> dict:
    # Criar pedido
    async with session.post(
        f"{BASE_URL}/orders",
        json={"service": service, "country": country}
    ) as response:
        order = (await response.json())["data"]

    # Polling assíncrono
    for _ in range(60):
        await asyncio.sleep(5)
        async with session.get(
            f"{BASE_URL}/orders/{order['id']}"
        ) as status_response:
            status = (await status_response.json())["data"]

            if status["status"] == "completed":
                return {
                    "phone": order["phone"],
                    "code": status["sms_code"]
                }

    raise TimeoutError("SMS não chegou")

async def main():
    token = os.environ["SMSCODE_TOKEN"]
    headers = {"Authorization": f"Bearer {token}"}

    async with aiohttp.ClientSession(headers=headers) as session:
        # Executa 3 verificações em paralelo
        tasks = [
            get_sms_code_async(session, "ig", "in"),
            get_sms_code_async(session, "tg", "br"),
            get_sms_code_async(session, "go", "in"),
        ]
        results = await asyncio.gather(*tasks, return_exceptions=True)

        for result in results:
            if isinstance(result, Exception):
                print(f"Erro: {result}")
            else:
                print(f"Código: {result['code']}")

asyncio.run(main())

Casos de uso avançados

Integração em pipeline de CI/CD

Para testes E2E automatizados que precisam de verificação de conta real:

# GitHub Actions — exemplo de step de verificação
- name: Verificar conta de teste
  env:
    SMSCODE_TOKEN: ${{ secrets.SMSCODE_TOKEN }}
  run: |
    python3 scripts/verify_test_account.py \
      --service google \
      --country in \
      --output-file /tmp/test-credentials.json

Monitoramento de saldo em produção

import requests

def check_balance_alert(min_balance: int = 1000) -> None:
    """Dispara alerta se saldo abaixo do mínimo."""
    response = requests.get(
        f"{BASE_URL}/balance",
        headers=HEADERS
    )
    balance = response.json()["data"]["balance"]

    if balance < min_balance:
        send_alert(
            f"Saldo SMSCode crítico: {balance} créditos "
            f"(mínimo configurado: {min_balance})"
        )

FAQ

A API do SMSCode tem SDK oficial?

Ainda não há SDK oficial — mas a API REST é direta o suficiente para integrar em qualquer linguagem com cliente HTTP padrão. Os exemplos neste guia (Python, Node.js, PHP, cURL) servem como ponto de partida robusto e são reutilizáveis. SDKs para Python e Node.js estão no roadmap.

Qual o limite de requisições (rate limit) da API?

O rate limit padrão é de 60 requisições por minuto por token para consultas e polling. Para criação de pedidos (POST /v1/orders), o limite é mais conservador: 20 por minuto. Se receber 429 Too Many Requests, aguarde o tempo indicado no header Retry-After. Para operações em escala que precisam de limites maiores, entre em contato com o suporte.

A API suporta webhooks para receber SMS sem polling?

Webhooks estão no roadmap do SMSCode. Por enquanto, polling é o método disponível. Para minimizar latência, inicie o polling logo após usar o número na plataforma — não aguarde antes de começar a consultar. Com backoff exponencial, o impacto de polling frequente no uso de rate limit é mínimo.

Como testar a integração sem gastar muito crédito?

Use países com preços baixos (Índia, Cazaquistão, Bangladesh) e serviços simples como Telegram (que tem alta taxa de sucesso). O custo por verificação pode ser de centavos. Não existe sandbox separado — todas as chamadas são contra a API real. Mas com preços baixos, você consegue fazer dezenas de testes por R$5,00 de crédito.

A API funciona com qualquer linguagem de programação?

Sim — qualquer linguagem que consiga fazer requisições HTTP e parsear JSON funciona com a API do SMSCode. Além dos exemplos neste guia, você pode integrar com Ruby, Java, Go, Rust, Swift, Kotlin, ou qualquer outra. O padrão REST com JSON é universal.

Pronto para experimentar o SMSCode?

Crie uma conta e obtenha seu primeiro número virtual em menos de dois minutos.

Começar →