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çõesAluguéis
FinalidadeUm código de verificaçãoUso contínuo de um número
Duração~15-20 minutos1 dia a 12 meses
EndpointPOST /activationsPOST /rentals
MensagensGeralmente umaIlimitadas 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:read
  • activations:read
  • activations:write
  • rentals:read
  • rentals:write
  • webhooks:read
  • webhooks: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.

StatusSignificado
pendingAtiva e aguardando um SMS
completedUma mensagem chegou, ou você finalizou
expiredA janela fechou sem mensagem — reembolsado
cancelledVocê cancelou
refundedA 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 em data em 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á em data.messages[0].code quando 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

StatusReenviar?
400, 401, 402, 403, 404, 422Não. Corrija a requisição, a chave ou seu saldo.
409Apenas idempotency_request_in_progress. O resto são conflitos de estado.
429Sim, após Retry-After.
5xxSim, com backoff exponencial — e reutilize a mesma Idempotency-Key.

Limites de taxa

Os limites são por chave de API, por minuto:

BucketLimiteAplica-se a
Geral120/minLeituras e chamadas de catálogo
Compra20/minCriar, cancelar e estender
Teste de webhook10/minPOST /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:

RecursoURL
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/activations antes 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-Key em 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_balance como terminal — um humano precisa fazer uma recarga. Não tente novamente.
  • Respeite Retry-After em 429. Não tente novamente erros 4xx além de 429.
  • Uma ativação custa dinheiro real em cada POST /activations bem-sucedido. Não há modo de teste; não chame para "verificar se funciona" — use GET /ping para 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âmetroEmObrigatórioDescrição
typequerynãoFiltrar por tipo de transação.
statusquerynãoFiltrar por status.
limitquerynãoTamanho da página, 1-100.
offsetquerynãoLinhas 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âmetroEmObrigatórioDescrição
countryquerynãoCódigo do país, slug ou nome, ex.: US.
servicequerynãoSlug 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âmetroEmObrigatórioDescrição
countryquerynãoFiltrar por código ISO do país.
daysquerynãoFiltrar 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 corpoTipoObrigatórioDescrição
countrystringsimCódigo do país, slug ou nome, ex.: US.
servicestringsimSlug do serviço, ex.: telegram.
operatorstringnãoOperadora 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âmetroEmObrigatórioDescrição
statusquerynãoFiltrar por status.
limitquerynãoTamanho da página, 1-100.
offsetquerynãoLinhas 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âmetroEmObrigatórioDescrição
idpathsimID 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 corpoTipoObrigatórioDescrição
offer_idstringsimO offer_id de GET /pricing/rentals. As ofertas expiram após 30 minutos — busque uma nova se a sua for rejeitada.
servicestringnãoOpcional. Alugue um serviço no número em vez do número inteiro, o que é mais barato.
auto_renewbooleannãoOpcional. 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âmetroEmObrigatórioDescrição
idpathsimID 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 corpoTipoObrigatórioDescrição
daysintegersimDias a adicionar, 1-365.
auto_renewbooleannãoOpcional. 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 corpoTipoObrigatórioDescrição
urlstringsimURL HTTPS para entrega. Deve ser publicamente acessível.
eventsarraynãoTipos de evento para assinar. Padrão é ["*"] (tudo).
descriptionstringnãoRó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âmetroEmObrigatórioDescrição
idpathsimID 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 corpoTipoObrigatórioDescrição
urlstringnãoNova URL HTTPS.
eventsarraynãoLista de assinatura substituta.
descriptionstringnãoNovo rótulo.
statusstringnãoAtiva 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âmetroEmObrigatórioDescrição
endpoint_idquerynãoFiltrar por um endpoint.
statusquerynãoFiltrar por status de entrega.
limitquerynãoTamanho da página, 1-100.
offsetquerynãoLinhas 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âmetroEmObrigatórioDescrição
typequerynãoFiltrar por tipo de evento.
object_idquerynãoFiltrar por uma ativação ou aluguel.
afterquerynãoRetornar apenas eventos após este id de evento.
limitquerynãoTamanho da página, 1-100.
offsetquerynãoLinhas a pular.

Códigos de erro

CódigoHTTPSignificado
missing_api_key401Nenhum cabeçalho Authorization foi enviado.
invalid_api_key401A chave não é reconhecida.
expired_api_key401A chave passou da data de validade.
revoked_api_key401A chave foi revogada no painel.
insufficient_scope403A chave não tem o escopo que este endpoint precisa.
ip_not_allowed403O IP de chamada não está na lista de permissões da chave.
account_blocked403A conta não pode usar a API.
invalid_body400O corpo da solicitação não era JSON válido.
missing_parameter400Um campo obrigatório estava ausente. Veja param\.
invalid_parameter400Um campo era inutilizável. Veja param\.
insufficient_balance402Seu saldo não cobre a compra.
resource_not_found404Nenhum objeto desse tipo nesta conta.
number_unavailable409Sem estoque para esse país e serviço no momento.
not_cancellable409Fora da janela de cancelamento, ou já usado.
not_extendable409Essa duração de extensão não é oferecida para este aluguel.
resource_conflict409O objeto não está em um estado que permita isso.
idempotency_request_in_progress409A mesma Idempotency-Key ainda está em execução. Tente novamente em breve.
idempotency_key_reused422Essa Idempotency-Key foi usada com um corpo diferente.
rate_limit_exceeded429Muitas solicitações. Veja Retry-After\.
internal_error500Nossa culpa. Cite o request\_id\ ao suporte.
provider_rejected502Um provedor upstream recusou o pedido.
provider_unavailable503Um 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.