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:
- Conta ativa no SMSCode — Crie em smscode.gg com apenas um e-mail, sem documentos
- Saldo de crédito — Adicione via Pix (instantâneo) ou cartão; mínimo R$5,00
- Token de API — Disponível em Configurações > API do painel (64 caracteres hexadecimais)
- Ferramenta para chamadas HTTP — cURL para testes, ou cliente HTTP na sua linguagem preferida
Como encontrar o token de API
- Faça login em smscode.gg
- Clique no seu avatar ou e-mail no canto superior direito
- Vá em “Settings” > seção “API”
- 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.
Etapa 1: Consultar o catálogo
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ísservice: código do serviçocountry: 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ço | Código |
|---|---|
wa | |
| Telegram | tg |
ig | |
| Google/Gmail | go |
fb | |
| TikTok | tt |
| Twitter/X | tw |
| Discord | di |
| Amazon | amazon |
| Binance | bn |
Códigos de país comuns:
| País | Código |
|---|---|
| Brasil | br |
| Estados Unidos | us |
| Índia | in |
| Reino Unido | gb |
| Alemanha | de |
| Portugal | pt |
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 subsequentesphone: número virtual completo com DDI. Use exatamente esse valor na plataformastatus: começa comopendingexpires_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 SMScompleted: SMS recebido, código disponívelexpired: 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:
| HTTP | Código de erro | Causa | Ação recomendada |
|---|---|---|---|
| 401 | UNAUTHORIZED | Token inválido ou ausente | Verifique o token nas configurações |
| 402 | INSUFFICIENT_BALANCE | Saldo insuficiente | Adicione crédito e tente novamente |
| 404 | NO_NUMBERS_AVAILABLE | Sem números no pool para o país/serviço | Tente país diferente ou aguarde |
| 404 | ORDER_NOT_FOUND | ID de pedido inválido | Verifique o ID retornado no passo 2 |
| 422 | INVALID_SERVICE | Código de serviço inválido | Consulte o catálogo para códigos válidos |
| 422 | INVALID_COUNTRY | Código de país inválido | Use ISO 3166-1 alpha-2 |
| 429 | RATE_LIMIT_EXCEEDED | Muitas requests por minuto | Aguarde Retry-After header |
| 503 | SERVICE_UNAVAILABLE | Indisponibilidade temporária | Retry 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.