Documentação da API

v1.0.0

Acesso programático a números virtuais, pedidos e saldo da conta.

Autenticação

Todas as requisições da API exigem um Bearer token. Gere um nas Configurações da Conta no painel, e inclua-o em cada requisição:

Authorization: Bearer YOUR_API_TOKEN

Requisições sem um token válido recebem uma resposta 401 UNAUTHORIZED.

URL Base

Todos os caminhos de endpoints abaixo são relativos a:

https://api.smscode.gg/v1

Formato de Resposta

Toda resposta retorna JSON com um envelope consistente. Todas as respostas incluem um cabeçalho x-request-id para depuração.

Sucesso
{
  "success": true,
  "data": { ... }
}
Erro
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable message"
  }
}
GET /catalog/countries

Retorna uma lista de todos os países disponíveis.

Parâmetros

Nenhum

Exemplo de Requisição

curl -s https://api.smscode.gg/v1/catalog/countries \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/catalog/countries", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/catalog/countries",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": [
    {
      "id": 6,
      "code": "ID",
      "name": "Indonesia",
      "dial_code": "+62",
      "emoji": "🇮🇩",
      "active": true
    }
  ]
}
GET /catalog/services

Retorna uma lista de serviços (plataformas) disponíveis. Opcionalmente filtre por país.

Parâmetros de Consulta

NomeTipoObrigatórioDescrição
country_idintegerNãoFiltrar serviços disponíveis para este país

Exemplo de Requisição

curl -s "https://api.smscode.gg/v1/catalog/services?country_id=6" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/catalog/services?country_id=6", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/catalog/services",
    params={"country_id": 6},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": [
    {
      "id": 3,
      "code": "wa",
      "name": "WhatsApp",
      "active": true
    }
  ]
}
GET /catalog/products

Retorna uma lista paginada de produtos disponíveis. Filtre por país e/ou plataforma.

Parâmetros de Consulta

NomeTipoObrigatórioDescrição
country_idintegerNãoFiltrar por ID do país
platform_idintegerNãoFiltrar por ID da plataforma/serviço
sortstringNãoOrdenação: price_asc (padrão), price_desc, available_asc, available_desc, name_asc, name_desc
limitintegerNãoResultados por página (1-10.000, padrão 1.000)
pageintegerNãoNúmero da página (mín. 1, padrão 1)

Exemplo de Requisição

curl -s "https://api.smscode.gg/v1/catalog/products?country_id=6&platform_id=3&limit=10&page=1" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const params = new URLSearchParams({
  country_id: "6", platform_id: "3", limit: "10", page: "1",
});
const res = await fetch(`https://api.smscode.gg/v1/catalog/products?${params}`, {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/catalog/products",
    params={"country_id": 6, "platform_id": 3, "limit": 10, "page": 1},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": [
    {
      "id": 142,
      "name": "WhatsApp Indonesia",
      "country_id": 6,
      "platform_id": 3,
      "available": 42,
      "price": 15000,
      "active": true
    }
  ],
  "meta": { "page": 1, "limit": 10, "count": 1 }
}
GET /catalog/exchange-rate

Retorna a taxa de câmbio atual para um par de moedas. Útil para converter preços.

Parâmetros de Consulta

NomeTipoObrigatórioDescrição
pairstringNãoPar de moedas (padrão: USD/IDR)

Exemplo de Requisição

curl -s "https://api.smscode.gg/v1/catalog/exchange-rate?pair=USD/IDR" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/catalog/exchange-rate?pair=USD/IDR", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/catalog/exchange-rate",
    params={"pair": "USD/IDR"},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": {
    "pair": "USD/IDR",
    "base_currency": "USD",
    "quote_currency": "IDR",
    "rate": 16250
  }
}
GET /balance

Retorna o saldo da conta do usuário autenticado em IDR.

Parâmetros

Nenhum

Exemplo de Requisição

curl -s https://api.smscode.gg/v1/balance \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/balance", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/balance",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": {
    "currency": "IDR",
    "balance": 500000
  }
}
GET /orders

Retorna uma lista dos pedidos do usuário autenticado, ordenados do mais recente. Suporta filtragem por status e paginação via offset.

Parâmetros de Consulta

NomeTipoObrigatórioDescrição
limitintegerNãoMáximo de resultados (1-100, padrão 20)
offsetintegerNãoNúmero de resultados a pular (padrão 0)
statusstringNãoFiltrar por status: ACTIVE, OTP_RECEIVED, COMPLETED, CANCELED, EXPIRED (sem distinção de maiúsculas)

Exemplo de Requisição

curl -s "https://api.smscode.gg/v1/orders?limit=5&status=ACTIVE" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const params = new URLSearchParams({
  limit: "5", status: "ACTIVE", offset: "0",
});
const res = await fetch(`https://api.smscode.gg/v1/orders?${params}`, {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/orders",
    params={"limit": 5, "status": "ACTIVE", "offset": 0},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": [
    {
      "id": 1001,
      "status": "ACTIVE",
      "created_at": "2026-02-25T10:00:00Z",
      "product_id": 142,
      "phone_number": "+6281234567890",
      "amount": 15000,
      "otp_code": null,
      "otp_received_at": null,
      "expires_at": "2026-02-25T10:20:00Z",
      "canceled_at": null,
      "failed_reason": null
    }
  ]
}
GET /orders/{id}

Retorna um único pedido por ID. Retorna apenas pedidos do usuário autenticado.

Parâmetros de Caminho

NomeTipoObrigatórioDescrição
idintegerSimID do pedido (parâmetro de caminho)

Exemplo de Requisição

curl -s https://api.smscode.gg/v1/orders/1001 \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/orders/1001", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/orders/1001",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": {
    "id": 1001,
    "status": "OTP_RECEIVED",
    "created_at": "2026-02-25T10:00:00Z",
    "product_id": 142,
    "phone_number": "+6281234567890",
    "amount": 15000,
    "otp_code": "123456",
    "otp_received_at": "2026-02-25T10:05:00Z",
    "expires_at": "2026-02-25T10:20:00Z",
    "canceled_at": null,
    "failed_reason": null
  }
}
GET /orders/active

Lista todos os pedidos ativos no momento (ACTIVE + OTP_RECEIVED). Use para verificar atualizações de status de OTP.

Parâmetros

Nenhum

Exemplo de Requisição

curl -s https://api.smscode.gg/v1/orders/active \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/orders/active", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/orders/active",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": [
    {
      "id": 1001,
      "status": "OTP_RECEIVED",
      "otp_code": "123456",
      "otp_message": "Your verification code is 123456",
      "otp_received_at": "2026-02-25T10:05:00Z",
      "expires_at": "2026-02-25T10:20:00Z",
      "failed_reason": null
    },
    {
      "id": 1002,
      "status": "ACTIVE",
      "otp_code": null,
      "otp_message": null,
      "otp_received_at": null,
      "expires_at": "2026-02-25T10:50:00Z",
      "failed_reason": null
    }
  ]
}
POST /orders/create

Cria um novo pedido de número virtual. Debita o saldo automaticamente. Suporta um cabeçalho Idempotency-Key opcional para evitar pedidos duplicados em retentativas de rede.

Corpo da Requisição

NomeTipoObrigatórioDescrição
product_idintegerSimID do produto a ser pedido
quantityintegerNãoQuantidade de itens (1-100, padrão 1)

Envie um cabeçalho Idempotency-Key (qualquer string única) para fazer retentativas com segurança sem criar pedidos duplicados.

Exemplo de Requisição

curl -s -X POST https://api.smscode.gg/v1/orders/create \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: unique-request-id-123" \
  -d '{"product_id":142,"quantity":1}'
const res = await fetch("https://api.smscode.gg/v1/orders/create", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_TOKEN",
    "Content-Type": "application/json",
    "Idempotency-Key": "unique-request-id-123",
  },
  body: JSON.stringify({ product_id: 142, quantity: 1 }),
});
const data = await res.json();
import requests

res = requests.post("https://api.smscode.gg/v1/orders/create",
    json={"product_id": 142, "quantity": 1},
    headers={
        "Authorization": "Bearer YOUR_API_TOKEN",
        "Idempotency-Key": "unique-request-id-123",
    })
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": {
    "orders": [
      {
        "id": 1002,
        "status": "ACTIVE",
        "phone_number": "+6281234567891",
        "otp_code": null,
        "otp_received_at": null,
        "expires_at": "2026-02-25T10:50:00Z",
        "failed_reason": null
      }
    ],
    "failed_count": 0
  }
}
POST /orders/cancel

Cancela um pedido ativo. O custo do aluguel é reembolsado ao saldo da sua conta.

Corpo da Requisição

NomeTipoObrigatórioDescrição
idintegerSimID do pedido a cancelar

Exemplo de Requisição

curl -s -X POST https://api.smscode.gg/v1/orders/cancel \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id":1001}'
const res = await fetch("https://api.smscode.gg/v1/orders/cancel", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ id: 1001 }),
});
const data = await res.json();
import requests

res = requests.post("https://api.smscode.gg/v1/orders/cancel",
    json={"id": 1001},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": {
    "order_id": 1001,
    "status": "CANCELED",
    "refund_amount": 15000,
    "new_balance": 515000
  }
}
POST /orders/finish

Marca um pedido como concluído após receber o OTP. Isso libera o número imediatamente em vez de aguardar a expiração.

Corpo da Requisição

NomeTipoObrigatórioDescrição
idintegerSimID do pedido a finalizar

Exemplo de Requisição

curl -s -X POST https://api.smscode.gg/v1/orders/finish \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id":1001}'
const res = await fetch("https://api.smscode.gg/v1/orders/finish", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ id: 1001 }),
});
const data = await res.json();
import requests

res = requests.post("https://api.smscode.gg/v1/orders/finish",
    json={"id": 1001},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": {
    "order_id": 1001,
    "status": "COMPLETED"
  }
}
POST /orders/resend

Solicita que a plataforma reenvie o SMS para o número alugado. Nem todas as plataformas suportam reenvio — verifique o campo resent na resposta.

Corpo da Requisição

NomeTipoObrigatórioDescrição
idintegerSimID do pedido para reenviar SMS

Exemplo de Requisição

curl -s -X POST https://api.smscode.gg/v1/orders/resend \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id":1001}'
const res = await fetch("https://api.smscode.gg/v1/orders/resend", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ id: 1001 }),
});
const data = await res.json();
import requests

res = requests.post("https://api.smscode.gg/v1/orders/resend",
    json={"id": 1001},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": {
    "order_id": 1001,
    "status": "ACTIVE",
    "resent": true
  }
}
GET /webhook

Retorna a configuração atual de notificação por webhook.

Parâmetros

Nenhum

Exemplo de Requisição

curl -s https://api.smscode.gg/v1/webhook \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/webhook", {
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.get("https://api.smscode.gg/v1/webhook",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": {
    "webhook_url": "https://example.com/webhook",
    "webhook_secret": "a1b2c3d4e5f6..."
  }
}
PATCH /webhook

Atualiza a URL e/ou o segredo do webhook. Um segredo é gerado automaticamente quando você define uma URL pela primeira vez. Envie uma string vazia para limpar. A URL deve usar HTTPS.

Corpo da Requisição

NomeTipoObrigatórioDescrição
webhook_urlstringNãoURL HTTPS para receber eventos de webhook (string vazia para limpar)
webhook_secretstringNãoSegredo compartilhado para assinatura HMAC-SHA256 (gerado automaticamente se omitido na primeira configuração)

Pelo menos um campo é obrigatório.

Exemplo de Requisição

curl -s -X PATCH https://api.smscode.gg/v1/webhook \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"webhook_url":"https://example.com/webhook"}'
const res = await fetch("https://api.smscode.gg/v1/webhook", {
  method: "PATCH",
  headers: {
    Authorization: "Bearer YOUR_API_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ webhook_url: "https://example.com/webhook" }),
});
const data = await res.json();
import requests

res = requests.patch("https://api.smscode.gg/v1/webhook",
    json={"webhook_url": "https://example.com/webhook"},
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": {
    "webhook_url": "https://example.com/webhook",
    "webhook_secret": "a1b2c3d4e5f6..."
  }
}
POST /webhook/test

Envia um evento de teste para a URL de webhook configurada. Retorna o código de status HTTP do seu servidor. Útil para verificar se o seu endpoint está funcionando antes de começar a usar.

Parâmetros

Nenhum

Exemplo de Requisição

curl -s -X POST https://api.smscode.gg/v1/webhook/test \
  -H "Authorization: Bearer YOUR_API_TOKEN"
const res = await fetch("https://api.smscode.gg/v1/webhook/test", {
  method: "POST",
  headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json();
import requests

res = requests.post("https://api.smscode.gg/v1/webhook/test",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json()

Exemplo de Resposta

200 OK
{
  "success": true,
  "data": {
    "status_code": 200
  }
}

Notificações por Webhook

Configure uma URL de webhook para receber notificações push em tempo real sobre eventos de pedidos em vez de fazer polling. Esta é a abordagem recomendada para scripts de bot.

Eventos

EventoGatilho
order.otp_receivedCódigo OTP entregue ao número alugado
order.completedPedido marcado como concluído (manualmente ou por expiração)
order.expiredPedido expirado sem OTP (saldo reembolsado)
order.canceledPedido cancelado pelo usuário (saldo reembolsado)

Payload

Corpo do POST do Webhook
{
  "event": "order.otp_received",
  "timestamp": "2026-02-25T12:00:00Z",
  "data": {
    "order_id": 1001,
    "phone_number": "+628123456789",
    "otp_code": "1234",
    "otp_message": "Your verification code is 1234",
    "product_id": 42,
    "country": "Indonesia",
    "platform": "WhatsApp"
  }
}

Verificação de Assinatura

Cada requisição de webhook inclui um cabeçalho X-Webhook-Signature com uma assinatura HMAC-SHA256 do corpo da requisição, usando seu webhook_secret como chave:

X-Webhook-Signature: sha256={HMAC-SHA256(body, webhook_secret)}

Verifique esta assinatura no seu servidor para garantir que a requisição é autêntica. A entrega é do tipo disparar e esquecer, com timeout de 3 segundos e sem retentativas.

Rate Limits

As requisições da API possuem limites por grupo de endpoint. Exceder o limite retorna 429 Too Many Requests com um cabeçalho Retry-After indicando quantos segundos aguardar.

Grupo de EndpointsLimiteJanela
Catálogo (countries, services, products, exchange-rate)1.200 requisições60 segundos
Saldo600 requisições60 segundos
Consulta de pedidos (list, get, active)1.200 requisições60 segundos
Criação de pedido1.200 requisições60 segundos
Cancelamento de pedido600 requisições60 segundos
Ações de pedido (finish, resend)600 requisições60 segundos
Config de webhook (get, update, test)120 requisições60 segundos

Códigos de Erro

Respostas de erro incluem um destes códigos em error.code:

CódigoHTTPDescrição
UNAUTHORIZED401Token de API ausente ou inválido
FORBIDDEN403Acesso negado
NOT_FOUND404Recurso não encontrado (pedido, taxa de câmbio, etc.)
CONFLICT409Requisição duplicada ou conflito de recurso
INSUFFICIENT_BALANCE409Saldo insuficiente para criar o pedido
VALIDATION_ERROR422Os parâmetros da requisição falharam na validação
RATE_LIMIT_EXCEEDED429Muitas requisições (verifique o cabeçalho Retry-After)
INTERNAL_ERROR500Erro interno do servidor
PROVIDER_ERROR422O provedor de SMS upstream rejeitou a requisição
CANCEL_TOO_EARLY409Pedido muito recente para cancelar — aguarde 2 minutos
SERVICE_UNAVAILABLE503Serviço temporariamente indisponível (manutenção)