Receive SMS online
Compre um número para uma verificação única por SMS, alugue um por meses e receba um webhook no momento em que o código chegar. Tudo o que o site faz, via HTTPS.
Documentação
Contentshow
Introdução
A API SMSZ oferece acesso programático a tudo o que o site faz: comprar um número para uma única verificação de SMS, alugar um número por dias ou meses, ler mensagens recebidas e receber um webhook no momento em que um código chega.
URL base
https://www.smsz.net/api/v1
Tudo é JSON sobre HTTPS. Todos os valores estão em USD, todos os timestamps estão em ISO 8601 em UTC, e cada compra é cobrada do saldo da sua conta — recarregue pelo site antes da sua primeira chamada.
A versão atual da API é 2026-07-01, retornada em cada resposta como o cabeçalho SMSZ-Version. Mudanças aditivas (novos campos, novos endpoints, novos tipos de evento) são lançadas sem incremento de versão, então escreva clientes que ignorem campos desconhecidos.
Dois produtos
| Ativações | Aluguéis | |
|---|---|---|
| Finalidade | Um código de verificação | Uso contínuo de um número |
| Duração | ~15-20 minutos | 1 dia a 12 meses |
| Endpoint | POST /activations | POST /rentals |
| Mensagens | Geralmente uma | Ilimitadas pelo período |
Autenticação
Toda requisição carrega uma chave de API como token bearer:
Authorization: Bearer smsz_live_9f2a1c4d_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Criando uma chave. Entre em smsz.net, abra o menu da conta e escolha API keys. A chave completa é exibida uma única vez, na criação — armazenamos apenas um hash dela, então se você a perder, precisará criar uma nova.
Escopos. Cada chave carrega uma lista explícita de permissões. Conceda apenas o que uma integração precisa: um servidor que apenas compra números não tem motivo para ter webhooks:write.
account:readactivations:readactivations:writerentals:readrentals:writewebhooks:readwebhooks:write
Uma chamada sem o escopo necessário falha com insufficient_scope e informa o escopo ausente.
Lista de permissão de IP. Uma chave pode ser vinculada a um ou mais endereços IPv4 ou faixas CIDR. Requisições de qualquer outro lugar são recusadas com ip_not_allowed. Vale a pena para chaves que ficam em um servidor fixo.
Mantendo chaves seguras. Chaves são credenciais bearer — qualquer pessoa que as possua pode gastar seu saldo. Mantenha-as no servidor. Nunca as envie em um bundle de navegador, aplicativo móvel ou repositório público. Se uma chave vazar, revogue-a no painel; a revogação tem efeito imediato.
Verifique uma nova chave com:
curl https://www.smsz.net/api/v1/ping \
-H "Authorization: Bearer $SMSZ_API_KEY"
Início rápido
Comprar um número e ler seu código leva duas chamadas.
1. Compre o número
curl -X POST https://www.smsz.net/api/v1/activations \
-H "Authorization: Bearer $SMSZ_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"country": "US", "service": "telegram"}'
{
"id": "cmg7x2k9a0001l208hq3v7bqz",
"object": "activation",
"status": "pending",
"phone_number": "+12025550147",
"price": 0.62,
"expires_at": "2026-07-24T10:30:03.000Z",
"messages": []
}
Use phone_number onde quer que esteja se cadastrando. Seu saldo é debitado imediatamente; se o provedor não conseguir atender o pedido, você não é cobrado.
2. Obtenha o código
curl https://www.smsz.net/api/v1/activations/cmg7x2k9a0001l208hq3v7bqz/messages \
-H "Authorization: Bearer $SMSZ_API_KEY"
{
"object": "list",
"data": [
{
"id": "cmg7xb1s70006l208r9y2mnop",
"object": "message",
"sender": "Telegram",
"text": "Telegram code 51284",
"code": "51284",
"received_at": "2026-07-24T10:16:44.000Z"
}
],
"has_more": false,
"total": 1
}
Faça polling a cada 3-5 segundos até data não estar vazio, ou use um webhook e pule o polling. code são os dígitos que extraímos; text é a mensagem completa se a extração falhar.
3. Finalize
curl -X POST https://www.smsz.net/api/v1/activations/cmg7x2k9a0001l208hq3v7bqz/finish \
-H "Authorization: Bearer $SMSZ_API_KEY"
Não é obrigatório, mas libera o número antes do prazo. Se nenhum código chegou, finalizar reembolsa você — assim como deixar a ativação expirar sozinha.
Um exemplo completo
const API = "https://www.smsz.net/api/v1";
const headers = {
Authorization: `Bearer ${process.env.SMSZ_API_KEY}`,
"Content-Type": "application/json",
};
async function getVerificationCode(country, service) {
const created = await fetch(`${API}/activations`, {
method: "POST",
headers: { ...headers, "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify({ country, service }),
});
if (!created.ok) {
const { error } = await created.json();
throw new Error(`${error.code}: ${error.message}`);
}
const activation = await created.json();
console.log("Use this number:", activation.phone_number);
const deadline = Date.parse(activation.expires_at);
while (Date.now() < deadline) {
await new Promise((r) => setTimeout(r, 4000));
const res = await fetch(`${API}/activations/${activation.id}/messages`, { headers });
const { data } = await res.json();
if (data.length > 0) return data[0].code;
}
throw new Error("No SMS arrived before the activation expired");
}
import os, time, uuid, requests
API = "https://www.smsz.net/api/v1"
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['SMSZ_API_KEY']}"
def get_verification_code(country: str, service: str) -> str:
response = session.post(
f"{API}/activations",
json={"country": country, "service": service},
headers={"Idempotency-Key": str(uuid.uuid4())},
)
if not response.ok:
error = response.json()["error"]
raise RuntimeError(f"{error['code']}: {error['message']}")
activation = response.json()
print("Use this number:", activation["phone_number"])
for _ in range(60):
time.sleep(4)
messages = session.get(f"{API}/activations/{activation['id']}/messages").json()
if messages["data"]:
return messages["data"][0]["code"]
raise TimeoutError("No SMS arrived before the activation expired")
Ativações
Uma ativação é um número alugado para uma única verificação. Ela dura aproximadamente 15-20 minutos dependendo do provedor, e expires_at informa exatamente quando.
Escolhendo o que comprar. country aceita um código ISO, nosso slug ou o nome do país — US, united-states e United States funcionam. service é um slug de GET /services. Verifique preço e estoque primeiro com GET /pricing/activations?country=US&service=telegram.
Omita operator e escolhemos o mais barato com estoque. Omita provider também — fixar um provedor apenas limita de onde podemos atender o pedido.
Status.
| Status | Significado |
|---|---|
| pending | Ativa e aguardando um SMS |
| completed | Uma mensagem chegou, ou você finalizou |
| expired | A janela fechou sem mensagem — reembolsado |
| cancelled | Você cancelou |
| refunded | A cobrança foi devolvida |
Reembolsos são automáticos. Você nunca é cobrado por uma ativação que não recebeu nada. Se a janela fechar vazia, o saldo volta sozinho. Cancelar antes faz o mesmo mais cedo. Quando uma mensagem chega, a ativação cumpriu seu papel e não é reembolsável.
Erros que valem tratamento. insufficient_balance (402) significa recarregar. number_unavailable (409) significa que o par país/serviço não tem estoque no momento — tente outro país ou consulte GET /pricing/activations para o que está disponível.
Aluguéis
Um aluguel mantém um número por dias ou meses e recebe mensagens ilimitadas pelo período.
Pedido. Aluguéis são comprados contra uma *oferta* de GET /pricing/rentals, porque disponibilidade e preço variam por país e duração:
curl "https://www.smsz.net/api/v1/pricing/rentals?country=GB&days=30" \
-H "Authorization: Bearer $SMSZ_API_KEY"
{
"object": "list",
"data": [
{
"offer_id": "o1.Xn9pQ2s.7Kd1fA.k3mZq0vR8tYw",
"country": "GB",
"country_name": "United Kingdom",
"duration_days": 30,
"price": 14.5,
"currency": "USD",
"available": 62
}
]
}
Passe o offer_id dessa linha de volta — ele já fixa o país, a duração e o preço:
curl -X POST https://www.smsz.net/api/v1/rentals \
-H "Authorization: Bearer $SMSZ_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"offer_id": "o1.Xn9pQ2s.7Kd1fA.k3mZq0vR8tYw"}'
offer_id é opaco e de curta duração: trate-o como um token para ida e volta, não como um valor para analisar ou armazenar. Ele expira após 30 minutos, então busque ofertas imediatamente antes de pedir, em vez de armazená-las em cache. Um token expirado ou alterado é rejeitado com invalid_parameter — busque um novo e tente novamente.
Aluguéis por serviço. Adicionar service aluga um serviço no número em vez do número inteiro. Mais barato quando você precisa de apenas uma plataforma.
Estendendo. POST /rentals/{id}/extend com {"days": 30} adiciona tempo e cobra do seu saldo. Estenda antes de expires_at — um aluguel expirado não pode ser revivido, apenas substituído.
Cancelando. Aluguéis são reembolsáveis dentro de 120 minutos da compra e apenas se nenhuma mensagem foi recebida — essa é a janela que nossos provedores nos dão, então é a janela que podemos oferecer. Fora dela, a chamada retorna not_cancellable.
Mensagens. Use GET /rentals/{id}/messages para o histórico completo, ou assine rental.message.received e receba cada uma. Aluguéis costumam durar semanas, então webhooks são fortemente preferidos em vez de polling aqui.
Webhooks
Webhooks enviam eventos ao seu servidor conforme acontecem, para você não precisar fazer polling. Esta é a forma recomendada de consumir a API.
Registre um endpoint
curl -X POST https://www.smsz.net/api/v1/webhooks/endpoints \
-H "Authorization: Bearer $SMSZ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/smsz",
"events": ["activation.message.received", "rental.message.received"]
}'
A resposta contém um secret começando com whsec_. Esta é a única vez que ele é retornado. Guarde-o — é o que prova que uma entrega veio de nós.
Assine ["*"] para tudo, ou use prefixos como ["rental.*"] para uma família de eventos.
Formato do payload
{
"id": "cmg7xh2k4000cl208a1b2c3d4",
"object": "event",
"type": "activation.message.received",
"api_version": "2026-07-01",
"created": 1784889404,
"data": {
"id": "cmg7x2k9a0001l208hq3v7bqz",
"object": "activation",
"status": "completed",
"phone_number": "+12025550147",
"messages": [
{ "id": "cmg7xb1s70006l208r9y2mnop", "object": "message", "sender": "Telegram", "text": "Telegram code 51284", "code": "51284", "received_at": "2026-07-24T10:16:44.000Z" }
]
}
}
data é o mesmo objeto que os endpoints REST retornam, então um único desserializador lida com ambos.
Verificando assinaturas
Cada entrega carrega um cabeçalho SMSZ-Signature:
SMSZ-Signature: t=1784889404,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
v1 é HMAC-SHA256 de {timestamp}.{raw request body}, usando seu segredo do endpoint. Verifique-o no corpo bruto, antes de qualquer parsing JSON — re-serializar muda os bytes e a assinatura não vai bater.
import crypto from "node:crypto";
function verifySmszWebhook(rawBody, signatureHeader, secret, toleranceSeconds = 300) {
const parts = Object.fromEntries(
signatureHeader.split(",").map((p) => p.split("=").map((s) => s.trim()))
);
// Reject old deliveries so a captured payload cannot be replayed later.
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > toleranceSeconds) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
// Express — note express.raw(), not express.json()
app.post("/hooks/smsz", express.raw({ type: "application/json" }), (req, res) => {
if (!verifySmszWebhook(req.body.toString(), req.get("SMSZ-Signature"), process.env.SMSZ_WEBHOOK_SECRET)) {
return res.status(400).send("bad signature");
}
const event = JSON.parse(req.body.toString());
// Acknowledge first, work afterwards: we retry anything that is not a 2xx.
res.status(200).send("ok");
handleEvent(event).catch(console.error);
});
import hmac, hashlib, time
from flask import Flask, request, abort
def verify_smsz_webhook(raw_body: bytes, signature_header: str, secret: str, tolerance: int = 300) -> bool:
parts = dict(p.strip().split("=", 1) for p in signature_header.split(","))
# Reject old deliveries so a captured payload cannot be replayed later.
if abs(time.time() - int(parts["t"])) > tolerance:
return False
expected = hmac.new(
secret.encode(), f"{parts['t']}.{raw_body.decode()}".encode(), hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, parts["v1"])
@app.post("/hooks/smsz")
def smsz_webhook():
if not verify_smsz_webhook(request.get_data(), request.headers["SMSZ-Signature"], SECRET):
abort(400)
event = request.get_json()
enqueue(event) # acknowledge fast, process out of band
return "", 200
Regras de entrega
- Qualquer 2xx é um reconhecimento. Qualquer outra coisa é reenviada.
- Reenvios: 8 tentativas em 10s → 30s → 2m → 10m → 30m → 2h → 6h → 12h — pouco mais de 24 horas no total.
- Entregas expiram após 10 segundos, então reconheça imediatamente e faça o trabalho de forma assíncrona.
- Redirecionamentos não são seguidos. Se sua URL mudar, atualize o endpoint.
- Após 20 falhas consecutivas, um endpoint é desativado. Reative-o com
PATCH /webhooks/endpoints/{id}e{"status": "active"}. - A entrega é pelo menos uma vez e a ordem não é garantida. Deduplique pelo evento
id, e prefira o estado emdataem vez de inferi-lo pela sequência de eventos.
Depuração. POST /webhooks/endpoints/{id}/test envia um evento real assinado com dados obviamente falsos e reporta o que seu servidor respondeu. GET /webhooks/deliveries é o log de entrega: status, código de resposta, contagem de tentativas e próximo reenvio.
Sem endpoint público? Todo evento também pode ser lido de GET /events. Faça polling com after definido como o último id de evento que você tratou. Eventos são retidos por 30 dias.
Tipos de evento
activation.created— Uma ativação foi comprada e seu número está pronto para receber SMS.activation.message.received— Um SMS chegou em uma ativação. O código de verificação extraído está emdata.messages[0].codequando pôde ser parseado.activation.completed— Uma ativação foi marcada como finalizada e não receberá mais mensagens.activation.cancelled— Uma ativação foi cancelada antes do uso e o saldo foi reembolsado.activation.expired— Uma ativação atingiu sua janela de expiração sem receber SMS.activation.refunded— O saldo de uma ativação foi devolvido à conta.rental.created— Um aluguel de longo prazo foi pedido. Ele pode ainda estar em provisionamento.rental.activated— Um aluguel terminou o provisionamento e agora está ativo.rental.message.received— Um SMS chegou em um número alugado.rental.extended— Um aluguel foi estendido e sua expiração foi adiada.rental.expiring— Um aluguel expira dentro de 24 horas.rental.expired— Um aluguel atingiu o fim do período e parou de receber mensagens.rental.cancelled— Um aluguel foi cancelado.balance.updated— O saldo da conta mudou.
Erros
Toda falha retorna o mesmo envelope com um status HTTP convencional:
{
"error": {
"type": "invalid_request_error",
"code": "insufficient_balance",
"message": "Insufficient balance. Required: 0.62, Available: 0.10",
"doc_url": "https://www.smsz.net/api#errors",
"request_id": "req_4f1c8a90b2d34e5f6a7b8c9d"
}
}
Ramifique em code, não em message. Códigos são estáveis; a redação não é. param nomeia o campo problemático quando o erro é sobre um.
Toda resposta — sucesso ou falha — carrega um cabeçalho SMSZ-Request-Id. Registre-o. Citá-lo permite que o suporte encontre a requisição exata em segundos.
Quais erros reenviar
| Status | Reenviar? |
|---|---|
| 400, 401, 402, 403, 404, 422 | Não. Corrija a requisição, a chave ou seu saldo. |
| 409 | Apenas idempotency_request_in_progress. O resto são conflitos de estado. |
| 429 | Sim, após Retry-After. |
| 5xx | Sim, com backoff exponencial — e reutilize a mesma Idempotency-Key. |
Limites de taxa
Os limites são por chave de API, por minuto:
| Bucket | Limite | Aplica-se a |
|---|---|---|
| Geral | 120/min | Leituras e chamadas de catálogo |
| Compra | 20/min | Criar, cancelar e estender |
| Teste de webhook | 10/min | POST /webhooks/endpoints/{id}/test |
Toda resposta carrega sua situação atual:
RateLimit-Limit: 120
RateLimit-Remaining: 117
RateLimit-Reset: 1784889460
Exceder um limite retorna 429 com Retry-After em segundos. Espere esse tempo em vez de tentar mais rápido — martelar um 429 só o estende.
Precisa de mais? Envie um e-mail para support@smsz.net com o nome da sua chave e o volume esperado; o limite geral é ajustável por chave.
Idempotência
Falhas de rede são ambíguas: uma requisição que expira pode ou não ter comprado um número. Envie um Idempotency-Key em qualquer coisa que gaste dinheiro e reenviar se torna seguro.
curl -X POST https://www.smsz.net/api/v1/activations \
-H "Authorization: Bearer $SMSZ_API_KEY" \
-H "Idempotency-Key: 3f9a1b7c-5d2e-4a8f-9c1b-2e7d4a6f8b3c" \
-H "Content-Type: application/json" \
-d '{"country": "US", "service": "telegram"}'
Reenvie com a mesma chave e você recebe a resposta original reproduzida, marcada como Idempotent-Replayed: true. Sem segunda compra, sem segunda cobrança.
- Use um UUID novo por operação lógica. Chaves são lembradas por 24 horas.
- Reutilizar uma chave com um corpo *diferente* retorna
idempotency_key_reused(422) — isso é quase sempre um bug onde uma constante foi usada em vez de um valor por requisição. - Reenviar enquanto a primeira tentativa ainda está em andamento retorna
idempotency_request_in_progress(409). Espere um momento e tente novamente. - Apenas respostas bem-sucedidas são armazenadas. Uma requisição falha pode ser reenviada com a mesma chave.
Suportado em POST /activations, POST /rentals e POST /rentals/{id}/extend.
Paginação
Os endpoints de listagem retornam um envelope consistente:
{
"object": "list",
"data": [],
"has_more": true,
"total": 214
}
Paginação com limit (1-100, padrão 25) e offset:
curl "https://www.smsz.net/api/v1/activations?limit=50&offset=50" \
-H "Authorization: Bearer $SMSZ_API_KEY"
As listagens são sempre das mais recentes para as mais antigas. GET /events também aceita after=<event id>, que é a forma correta de consumi-lo como um fluxo — deslocamentos mudam conforme novos eventos chegam, mas um cursor não.
Servidor MCP
Tudo nesta página também está disponível como um servidor Model Context Protocol, para que um assistente de IA possa comprar números e ler códigos de verificação em conversa, em vez de por código.
https://www.smsz.net/api/mcp
É um servidor MCP remoto via Streamable HTTP, autenticado com a mesma chave de API desta API — mesmos escopos, mesmos limites de taxa, mesmo saldo. Não há nada para instalar nem para executar localmente.
A maioria dos clientes precisa apenas da URL acima e de um cabeçalho Authorization: Bearer:
A referência completa — cada ferramenta, instruções de conexão para cada cliente e as regras de segurança que importam quando um modelo de linguagem é quem gasta seu saldo — está em /mcp.
Antes de conectar uma chave que pode comprar qualquer coisa, leia Gastando com segurança. A versão resumida: restrinja a chave ao menor conjunto que cubra a tarefa, porque uma ferramenta para a qual a chave não tem escopo nunca é sequer mostrada ao assistente, e essa é a única salvaguarda que não depende de um modelo se comportar bem.
Para agentes de IA
Se você está conectando um assistente em vez de escrever um cliente, use o servidor MCP — ele expõe tudo isso como ferramentas, com as regras de segurança já escritas nas descrições das ferramentas.
Descrições legíveis por máquina desta API:
| Recurso | URL |
|---|---|
| Servidor MCP | /mcp — https://www.smsz.net/api/mcp |
| Especificação OpenAPI 3.1 | /api/v1/openapi.json |
| Estes documentos como um arquivo Markdown | /api/llms-full.txt |
| Índice curto para contexto de modelo | /llms.txt |
O documento OpenAPI não é autenticado, então geradores de clientes e agentes podem lê-lo antes de existir uma chave.
Notas para chamadores autônomos
- Leia
GET /pricing/activationsantes de comprar. Preços e estoque mudam constantemente; não presuma que um par de país e serviço esteja disponível. - Sempre envie um
Idempotency-Keyem compras. Se uma chamada falhar de forma ambígua, tente novamente com a *mesma* chave em vez de emitir uma nova compra. - Trate 402
insufficient_balancecomo terminal — um humano precisa fazer uma recarga. Não tente novamente. - Respeite
Retry-Afterem 429. Não tente novamente erros 4xx além de 429. - Uma ativação custa dinheiro real em cada
POST /activationsbem-sucedido. Não há modo de teste; não chame para "verificar se funciona" — useGET /pingpara isso.
Endpoints de conta
GET/ping
Verifique sua chave de API — Confirma que uma chave é válida e informa qual conta e escopos ela carrega. Faça desta a sua primeira chamada ao configurar uma integração.
Escopo: account:read
Resposta:
{
"object": "ping",
"ok": true,
"api_version": "2026-07-01",
"account_email": "you@example.com",
"key_name": "Production server",
"scopes": [
"account:read",
"activations:write"
]
}
GET/account
Recupere sua conta — Retorna seu saldo atual e quantas ativações e aluguéis estão ativos.
Resposta:
{
"object": "account",
"id": "cmg7w1a2b0000l208ff11aaaa",
"email": "you@example.com",
"username": null,
"balance": 42.75,
"currency": "USD",
"created_at": "2026-01-04T08:00:00.000Z",
"active_activations": 1,
"active_rentals": 2
}
GET/transactions
Liste transações — Seu extrato: compras, reembolsos e depósitos, das mais recentes para as mais antigas.
| Parâmetro | Em | Obrigatório | Descrição |
|---|---|---|---|
| type | query | não | Filtrar por tipo de transação. |
| status | query | não | Filtrar por status. |
| limit | query | não | Tamanho da página, 1-100. |
| offset | query | não | Linhas a pular. |
Resposta:
{
"object": "list",
"data": [
{
"id": "cmg7xd4u90008l208p7q1rstu",
"object": "transaction",
"type": "sms_purchase",
"status": "completed",
"amount": -0.62,
"currency": "USD",
"description": "SMS purchase for telegram (US)",
"created_at": "2026-07-24T10:15:03.000Z"
}
],
"has_more": false,
"total": 1
}
Endpoints de catálogo
GET/countries
Liste países — Todos os países em que vendemos números. Use code ao criar uma ativação.
Escopo: activations:read
Resposta:
{
"object": "list",
"data": [
{
"code": "US",
"name": "United States",
"full_name": "United States of America",
"slug": "united-states",
"phone_code": "+1",
"continent": "north_america"
}
],
"has_more": false,
"total": 1
}
GET/services
Liste serviços — Todos os serviços que você pode verificar. Use slug ao criar uma ativação.
Resposta:
{
"object": "list",
"data": [
{
"slug": "telegram",
"name": "Telegram",
"full_name": "Telegram Messenger",
"popular": true
}
],
"has_more": false,
"total": 1
}
GET/pricing/activations
Preços de ativação ao vivo — Preços e estoque atuais, consultados ao vivo de nossos provedores. Você deve passar country, service ou ambos — uma varredura sem filtro precificaria todos os países contra todos os serviços.
| Parâmetro | Em | Obrigatório | Descrição |
|---|---|---|---|
| country | query | não | Código do país, slug ou nome, ex.: US. |
| service | query | não | Slug do serviço, ex.: telegram. |
Resposta:
{
"object": "list",
"data": [
{
"country": "US",
"country_name": "United States",
"service": "telegram",
"service_name": "Telegram",
"price": 0.62,
"currency": "USD",
"available": 418,
"success_rate": 92
}
],
"has_more": false,
"total": 1
}
GET/pricing/rentals
Ofertas de aluguel ao vivo — Ofertas de aluguel de longo prazo compráveis. Passe o offer_id de uma oferta diretamente para POST /rentals — é um token opaco e de curta duração que carrega tudo o que é necessário para preencher o pedido.
Escopo: rentals:read
| Parâmetro | Em | Obrigatório | Descrição |
|---|---|---|---|
| country | query | não | Filtrar por código ISO do país. |
| days | query | não | Filtrar por duração do aluguel em dias. |
Resposta:
{
"object": "list",
"data": [
{
"offer_id": "o1.Xn9pQ2s.7Kd1fA.k3mZq0vR8tYw",
"country": "GB",
"country_name": "United Kingdom",
"duration_days": 30,
"price": 14.5,
"currency": "USD",
"available": 62
}
],
"has_more": false,
"total": 1
}
Endpoints de ativações
POST/activationsidempotente
Compre uma ativação — Compra um número para uma verificação e debita seu saldo. Se o provedor não puder preencher o pedido, nada é cobrado. Consulte /activations/{id}/messages para o código, ou assine activation.message.received.
Escopo: activations:write · Suporta Idempotency-Key · Limite de taxa de compra
| Campo do corpo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| country | string | sim | Código do país, slug ou nome, ex.: US. |
| service | string | sim | Slug do serviço, ex.: telegram. |
| operator | string | não | Operadora opcional. Omita para deixarmos escolher a mais barata disponível. |
Solicitação:
{
"country": "US",
"service": "telegram"
}
Resposta:
{
"id": "cmg7x2k9a0001l208hq3v7bqz",
"object": "activation",
"status": "pending",
"phone_number": "+12025550147",
"country": "US",
"country_name": "United States",
"service": "telegram",
"service_name": "Telegram",
"operator": "any",
"price": 0.62,
"currency": "USD",
"created_at": "2026-07-24T10:15:03.000Z",
"expires_at": "2026-07-24T10:30:03.000Z",
"messages": []
}
GET/activations
Liste ativações — Suas ativações, das mais recentes para as mais antigas, cada uma com quaisquer mensagens recebidas.
| Parâmetro | Em | Obrigatório | Descrição |
|---|---|---|---|
| status | query | não | Filtrar por status. |
| limit | query | não | Tamanho da página, 1-100. |
| offset | query | não | Linhas a pular. |
Resposta:
{
"object": "list",
"data": [
{
"id": "cmg7x2k9a0001l208hq3v7bqz",
"object": "activation",
"status": "pending",
"phone_number": "+12025550147",
"country": "US",
"country_name": "United States",
"service": "telegram",
"service_name": "Telegram",
"operator": "any",
"price": 0.62,
"currency": "USD",
"created_at": "2026-07-24T10:15:03.000Z",
"expires_at": "2026-07-24T10:30:03.000Z",
"messages": []
}
],
"has_more": false,
"total": 1
}
GET/activations/{id}
Recupere uma ativação — Uma ativação e suas mensagens.
| Parâmetro | Em | Obrigatório | Descrição |
|---|---|---|---|
| id | path | sim | ID da ativação. |
Resposta:
GET/activations/{id}/messages
Consulte o código — Pergunta diretamente ao provedor, então uma mensagem que ainda não chegou até nós por webhook ainda aparece. Consulte a cada 3-5 segundos; webhooks são a melhor integração se você puder hospedar um endpoint.
Resposta:
POST/activations/{id}/cancel
Cancele uma ativação — Cancela uma ativação não utilizada e a reembolsa. Quando uma mensagem chega, a ativação já entregou o que foi comprada para fazer, então o cancelamento é bem-sucedido com refund_amount: 0.
Escopo: activations:write · Limite de taxa de compra
Resposta:
{
"id": "cmg7x2k9a0001l208hq3v7bqz",
"object": "activation",
"status": "refunded",
"phone_number": "+12025550147",
"country": "US",
"country_name": "United States",
"service": "telegram",
"service_name": "Telegram",
"operator": "any",
"price": 0.62,
"currency": "USD",
"created_at": "2026-07-24T10:15:03.000Z",
"expires_at": "2026-07-24T10:30:03.000Z",
"messages": [],
"refund_amount": 0.62,
"refund_reason": "Full refund - No SMS received"
}
POST/activations/{id}/finish
Finalize uma ativação — Fecha uma ativação depois que você usou o código, devolvendo o número ao provedor. Se nenhuma mensagem chegou, finalizar também reembolsa a compra.
Escopo: activations:write
Resposta:
{
"id": "cmg7x2k9a0001l208hq3v7bqz",
"object": "activation",
"status": "completed",
"phone_number": "+12025550147",
"country": "US",
"country_name": "United States",
"service": "telegram",
"service_name": "Telegram",
"operator": "any",
"price": 0.62,
"currency": "USD",
"created_at": "2026-07-24T10:15:03.000Z",
"expires_at": "2026-07-24T10:30:03.000Z",
"messages": [],
"refund_amount": 0
}
Endpoints de aluguéis
POST/rentalsidempotente
Peça um aluguel — Aluga um número por dias ou meses. Pegue um offer_id de GET /pricing/rentals e devolva-o — a oferta já fixa o país, a duração e o preço.
Escopo: rentals:write · Suporta Idempotency-Key · Limite de taxa de compra
| Campo do corpo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| offer_id | string | sim | O offer_id de GET /pricing/rentals. As ofertas expiram após 30 minutos — busque uma nova se a sua for rejeitada. |
| service | string | não | Opcional. Alugue um serviço no número em vez do número inteiro, o que é mais barato. |
| auto_renew | boolean | não | Opcional. Renovar automaticamente no vencimento, quando a oferta suportar. |
Solicitação:
{
"offer_id": "o1.Xn9pQ2s.7Kd1fA.k3mZq0vR8tYw"
}
Resposta:
{
"id": "cmg7x9p2r0004l208d1w4kzab",
"object": "rental",
"status": "active",
"phone_number": "+447700900123",
"country": "GB",
"country_name": "United Kingdom",
"service": "full",
"service_name": "Full Rent",
"nickname": null,
"auto_renew": false,
"price": 14.5,
"currency": "USD",
"created_at": "2026-07-24T10:20:11.000Z",
"expires_at": "2026-08-23T10:20:11.000Z",
"messages": []
}
GET/rentals
Liste aluguéis — Seus aluguéis de longo prazo, dos mais recentes para os mais antigos.
Resposta:
{
"object": "list",
"data": [
{
"id": "cmg7x9p2r0004l208d1w4kzab",
"object": "rental",
"status": "active",
"phone_number": "+447700900123",
"country": "GB",
"country_name": "United Kingdom",
"service": "full",
"service_name": "Full Rent",
"nickname": null,
"auto_renew": false,
"price": 14.5,
"currency": "USD",
"created_at": "2026-07-24T10:20:11.000Z",
"expires_at": "2026-08-23T10:20:11.000Z",
"messages": []
}
],
"has_more": false,
"total": 1
}
GET/rentals/{id}
Recupere um aluguel — Um aluguel e suas mensagens.
| Parâmetro | Em | Obrigatório | Descrição |
|---|---|---|---|
| id | path | sim | ID do aluguel. |
Resposta:
GET/rentals/{id}/messages
Liste mensagens de aluguel — Todas as mensagens recebidas no aluguel, das mais recentes para as mais antigas. Consulta o provedor antes de responder.
Resposta:
POST/rentals/{id}/extendidempotente
Estenda um aluguel — Adiciona tempo a um aluguel ativo e cobra do seu saldo. Aluguéis expirados não podem ser estendidos — peça um novo.
| Campo do corpo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| days | integer | sim | Dias a adicionar, 1-365. |
| auto_renew | boolean | não | Opcional. Renovar automaticamente no vencimento, quando o aluguel suportar. |
Solicitação:
{
"days": 30
}
Resposta:
{
"id": "cmg7x9p2r0004l208d1w4kzab",
"object": "rental",
"status": "active",
"phone_number": "+447700900123",
"country": "GB",
"country_name": "United Kingdom",
"service": "full",
"service_name": "Full Rent",
"nickname": null,
"auto_renew": false,
"price": 14.5,
"currency": "USD",
"created_at": "2026-07-24T10:20:11.000Z",
"expires_at": "2026-08-23T10:20:11.000Z",
"messages": [],
"extended_hours": 720,
"amount_charged": 14.5
}
POST/rentals/{id}/cancel
Cancele um aluguel — Cancela e reembolsa um aluguel. Só é possível dentro de 120 minutos da compra e apenas se nenhuma mensagem foi recebida — essa é a janela que nossos provedores nos dão.
Escopo: rentals:write · Limite de taxa de compra
Resposta:
{
"id": "cmg7x9p2r0004l208d1w4kzab",
"object": "rental",
"status": "refunded",
"phone_number": "+447700900123",
"country": "GB",
"country_name": "United Kingdom",
"service": "full",
"service_name": "Full Rent",
"nickname": null,
"auto_renew": false,
"price": 14.5,
"currency": "USD",
"created_at": "2026-07-24T10:20:11.000Z",
"expires_at": "2026-08-23T10:20:11.000Z",
"messages": [],
"refund_amount": 14.5,
"refund_reason": "Full refund - No SMS received"
}
Endpoints de webhooks
POST/webhooks/endpoints
Crie um endpoint de webhook — Registra uma URL HTTPS para receber eventos. A resposta contém o secret de assinatura — esta é a única vez que ele é retornado, então armazene-o agora.
Escopo: webhooks:write
| Campo do corpo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| url | string | sim | URL HTTPS para entrega. Deve ser publicamente acessível. |
| events | array | não | Tipos de evento para assinar. Padrão é ["*"] (tudo). |
| description | string | não | Rótulo opcional, até 160 caracteres. |
Solicitação:
{
"url": "https://example.com/hooks/smsz",
"events": [
"activation.message.received",
"rental.message.received"
],
"description": "Production listener"
}
Resposta:
{
"id": "cmg7xf7w1000al208z3a5vwxy",
"object": "webhook_endpoint",
"url": "https://example.com/hooks/smsz",
"description": "Production listener",
"events": [
"activation.message.received",
"rental.message.received"
],
"status": "active",
"api_version": "2026-07-01",
"secret": "whsec_p9Qk…",
"created_at": "2026-07-24T10:30:00.000Z",
"last_success_at": null,
"last_error_at": null,
"last_error": null
}
GET/webhooks/endpoints
Liste endpoints de webhook — Seus endpoints configurados. Segredos nunca são incluídos.
Escopo: webhooks:read
Resposta:
{
"object": "list",
"data": [],
"has_more": false,
"total": 0
}
GET/webhooks/endpoints/{id}
Recupere um endpoint de webhook — Um endpoint, incluindo quando ele teve sucesso ou falhou pela última vez.
| Parâmetro | Em | Obrigatório | Descrição |
|---|---|---|---|
| id | path | sim | ID do endpoint. |
PATCH/webhooks/endpoints/{id}
Atualize um endpoint de webhook — Altere a URL, as assinaturas ou a descrição. Envie status: "active" para reativar um endpoint que desativamos após falhas repetidas — isso também redefine o contador de falhas.
| Campo do corpo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| url | string | não | Nova URL HTTPS. |
| events | array | não | Lista de assinatura substituta. |
| description | string | não | Novo rótulo. |
| status | string | não | Ativa ou desativa o endpoint. Um de: active, disabled. |
Request:
{
"events": [
"*"
]
}
DELETE/webhooks/endpoints/{id}
Excluir um endpoint de webhook — Remove o endpoint e quaisquer entregas ainda na fila para ele.
Response:
{
"id": "cmg7xf7w1000al208z3a5vwxy",
"object": "webhook_endpoint",
"deleted": true
}
POST/webhooks/endpoints/{id}/test
Enviar um evento de teste — Entrega um evento real, assinado corretamente, com dados obviamente falsos, e relata exatamente o que seu endpoint respondeu. Use-o para verificar a verificação de assinatura antes de entrar em produção.
Response:
{
"object": "webhook_test",
"endpoint_id": "cmg7xf7w1000al208z3a5vwxy",
"delivered": true,
"response_status": 200,
"duration_ms": 143,
"error": null
}
GET/webhooks/deliveries
Listar entregas — O que foi enviado, o que seu endpoint respondeu, quantas tentativas foram necessárias e quando a próxima tentativa está prevista. Comece aqui quando os eventos não estiverem chegando.
| Parâmetro | Em | Obrigatório | Descrição |
|---|---|---|---|
| endpoint_id | query | não | Filtrar por um endpoint. |
| status | query | não | Filtrar por status de entrega. |
| limit | query | não | Tamanho da página, 1-100. |
| offset | query | não | Linhas a pular. |
GET/events
Listar eventos — Todos os eventos da sua conta, independentemente de você ter um endpoint de webhook. Consulte isso com after definido como o último id de evento que você processou se não puder hospedar um endpoint. Retidos por 30 dias.
| Parâmetro | Em | Obrigatório | Descrição |
|---|---|---|---|
| type | query | não | Filtrar por tipo de evento. |
| object_id | query | não | Filtrar por uma ativação ou aluguel. |
| after | query | não | Retornar apenas eventos após este id de evento. |
| limit | query | não | Tamanho da página, 1-100. |
| offset | query | não | Linhas a pular. |
Códigos de erro
| Código | HTTP | Significado |
|---|---|---|
| missing_api_key | 401 | Nenhum cabeçalho Authorization foi enviado. |
| invalid_api_key | 401 | A chave não é reconhecida. |
| expired_api_key | 401 | A chave passou da data de validade. |
| revoked_api_key | 401 | A chave foi revogada no painel. |
| insufficient_scope | 403 | A chave não tem o escopo que este endpoint precisa. |
| ip_not_allowed | 403 | O IP de chamada não está na lista de permissões da chave. |
| account_blocked | 403 | A conta não pode usar a API. |
| invalid_body | 400 | O corpo da solicitação não era JSON válido. |
| missing_parameter | 400 | Um campo obrigatório estava ausente. Veja param\. |
| invalid_parameter | 400 | Um campo era inutilizável. Veja param\. |
| insufficient_balance | 402 | Seu saldo não cobre a compra. |
| resource_not_found | 404 | Nenhum objeto desse tipo nesta conta. |
| number_unavailable | 409 | Sem estoque para esse país e serviço no momento. |
| not_cancellable | 409 | Fora da janela de cancelamento, ou já usado. |
| not_extendable | 409 | Essa duração de extensão não é oferecida para este aluguel. |
| resource_conflict | 409 | O objeto não está em um estado que permita isso. |
| idempotency_request_in_progress | 409 | A mesma Idempotency-Key ainda está em execução. Tente novamente em breve. |
| idempotency_key_reused | 422 | Essa Idempotency-Key foi usada com um corpo diferente. |
| rate_limit_exceeded | 429 | Muitas solicitações. Veja Retry-After\. |
| internal_error | 500 | Nossa culpa. Cite o request\_id\ ao suporte. |
| provider_rejected | 502 | Um provedor upstream recusou o pedido. |
| provider_unavailable | 503 | Um provedor upstream está temporariamente fora do ar. |
Algo faltando?
Envie um e-mail para support@smsz.net com o seu id de solicitação e daremos uma olhada. Inclua o cabeçalho SMSZ-Request-Id da resposta com falha — ele aponta diretamente para a solicitação em nossos logs.