Documentação da API
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:
Requisições sem um token válido recebem uma resposta 401 UNAUTHORIZED.
⟩ URL Base
Todos os caminhos de endpoints abaixo são relativos a:
⟩ Formato de Resposta
Toda resposta retorna JSON com um envelope consistente. Todas as respostas incluem um cabeçalho x-request-id para depuração.
{
"success": true,
"data": { ... }
} {
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable message"
}
} /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
{
"success": true,
"data": [
{
"id": 6,
"code": "ID",
"name": "Indonesia",
"dial_code": "+62",
"emoji": "🇮🇩",
"active": true
}
]
} /catalog/services Retorna uma lista de serviços (plataformas) disponíveis. Opcionalmente filtre por país.
Parâmetros de Consulta
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
country_id | integer | Não | Filtrar 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
{
"success": true,
"data": [
{
"id": 3,
"code": "wa",
"name": "WhatsApp",
"active": true
}
]
} /catalog/products Retorna uma lista paginada de produtos disponíveis. Filtre por país e/ou plataforma.
Parâmetros de Consulta
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
country_id | integer | Não | Filtrar por ID do país |
platform_id | integer | Não | Filtrar por ID da plataforma/serviço |
sort | string | Não | Ordenação: price_asc (padrão), price_desc, available_asc, available_desc, name_asc, name_desc |
limit | integer | Não | Resultados por página (1-10.000, padrão 1.000) |
page | integer | Não | Nú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
{
"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 }
} /catalog/exchange-rate Retorna a taxa de câmbio atual para um par de moedas. Útil para converter preços.
Parâmetros de Consulta
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
pair | string | Não | Par 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
{
"success": true,
"data": {
"pair": "USD/IDR",
"base_currency": "USD",
"quote_currency": "IDR",
"rate": 16250
}
} /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
{
"success": true,
"data": {
"currency": "IDR",
"balance": 500000
}
} /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
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
limit | integer | Não | Máximo de resultados (1-100, padrão 20) |
offset | integer | Não | Número de resultados a pular (padrão 0) |
status | string | Não | Filtrar 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
{
"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
}
]
} /orders/{id} Retorna um único pedido por ID. Retorna apenas pedidos do usuário autenticado.
Parâmetros de Caminho
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | integer | Sim | ID 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
{
"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
}
} /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
{
"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
}
]
} /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
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
product_id | integer | Sim | ID do produto a ser pedido |
quantity | integer | Não | Quantidade 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
{
"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
}
} /orders/cancel Cancela um pedido ativo. O custo do aluguel é reembolsado ao saldo da sua conta.
Corpo da Requisição
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | integer | Sim | ID 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
{
"success": true,
"data": {
"order_id": 1001,
"status": "CANCELED",
"refund_amount": 15000,
"new_balance": 515000
}
} /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
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | integer | Sim | ID 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
{
"success": true,
"data": {
"order_id": 1001,
"status": "COMPLETED"
}
} /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
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | integer | Sim | ID 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
{
"success": true,
"data": {
"order_id": 1001,
"status": "ACTIVE",
"resent": true
}
} /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
{
"success": true,
"data": {
"webhook_url": "https://example.com/webhook",
"webhook_secret": "a1b2c3d4e5f6..."
}
} /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
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
webhook_url | string | Não | URL HTTPS para receber eventos de webhook (string vazia para limpar) |
webhook_secret | string | Não | Segredo 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
{
"success": true,
"data": {
"webhook_url": "https://example.com/webhook",
"webhook_secret": "a1b2c3d4e5f6..."
}
} /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
{
"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
| Evento | Gatilho |
|---|---|
order.otp_received | Código OTP entregue ao número alugado |
order.completed | Pedido marcado como concluído (manualmente ou por expiração) |
order.expired | Pedido expirado sem OTP (saldo reembolsado) |
order.canceled | Pedido cancelado pelo usuário (saldo reembolsado) |
Payload
{
"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:
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 Endpoints | Limite | Janela |
|---|---|---|
| Catálogo (countries, services, products, exchange-rate) | 1.200 requisições | 60 segundos |
| Saldo | 600 requisições | 60 segundos |
| Consulta de pedidos (list, get, active) | 1.200 requisições | 60 segundos |
| Criação de pedido | 1.200 requisições | 60 segundos |
| Cancelamento de pedido | 600 requisições | 60 segundos |
| Ações de pedido (finish, resend) | 600 requisições | 60 segundos |
| Config de webhook (get, update, test) | 120 requisições | 60 segundos |
⟩ Códigos de Erro
Respostas de erro incluem um destes códigos em error.code:
| Código | HTTP | Descrição |
|---|---|---|
UNAUTHORIZED | 401 | Token de API ausente ou inválido |
FORBIDDEN | 403 | Acesso negado |
NOT_FOUND | 404 | Recurso não encontrado (pedido, taxa de câmbio, etc.) |
CONFLICT | 409 | Requisição duplicada ou conflito de recurso |
INSUFFICIENT_BALANCE | 409 | Saldo insuficiente para criar o pedido |
VALIDATION_ERROR | 422 | Os parâmetros da requisição falharam na validação |
RATE_LIMIT_EXCEEDED | 429 | Muitas requisições (verifique o cabeçalho Retry-After) |
INTERNAL_ERROR | 500 | Erro interno do servidor |
PROVIDER_ERROR | 422 | O provedor de SMS upstream rejeitou a requisição |
CANCEL_TOO_EARLY | 409 | Pedido muito recente para cancelar — aguarde 2 minutos |
SERVICE_UNAVAILABLE | 503 | Serviço temporariamente indisponível (manutenção) |