API de ativação SMS

Duas opções: um endpoint compatível com o protocolo sms-activate, para que o software existente mude alterando o URL e a chave, e uma API REST JSON para novas integrações. Ambas usam a mesma chave API do seu painel.

Obtenha a sua chave API

Crie uma conta, abra o painel e gere uma chave em Acesso API. Mantenha-a secreta: quem tiver a chave pode gastar o seu saldo.

Registar

Fluxo típico

  1. Chame getNumber com um serviço e um país.
  2. Use o número na app de destino.
  3. Consulte getStatus a cada poucos segundos até receber STATUS_OK.
  4. Chame setStatus com 6 para concluir, ou 8 para cancelar se não chegou código.

Endpoint compatível com sms-activate

Envie pedidos GET ou POST com os parâmetros api_key e action. As respostas são texto simples, exatamente como no sms-activate.

https://smsrota.com/stubs/handler_api.php?api_key=KEY&action=getNumber&service=wa&country=187

Ações

AçãoParâmetrosResposta
getBalance—ACCESS_BALANCE:12.5000
getPricesservice?, country?{"187":{"wa":{"cost":0.4,"count":1563}}}
getNumberservice, country, maxPrice?ACCESS_NUMBER:48151623:15550123456
getStatusidSTATUS_WAIT_CODE · STATUS_WAIT_RETRY:code · STATUS_OK:code · STATUS_CANCEL
setStatusid, statusACCESS_RETRY_GET · ACCESS_ACTIVATION · ACCESS_CANCEL
getRentNumberservice, country, rent_time (4/24/72/168/720){"status":"success","phone":{"id":31,"endDate":"…","number":"447700900001"}}
getRentStatusid{"status":"success","quantity":"1","values":{"0":{"phoneFrom":"WhatsApp","text":"…"}}}
setRentStatusid, status (1 = finish, 2 = cancel){"status":"success"}
continueRentNumberid, rent_time{"status":"success","phone":{…}}

Valores de setStatus

3
Pedir outro código no mesmo número
6
Concluir a ativação
8
Cancelar e reembolsar (possível dois minutos após a compra)

API REST JSON

Envie a chave no cabeçalho Authorization como "Bearer KEY". Os valores são strings em dólares americanos com quatro casas decimais.

GET   https://smsrota.com/v1/balance
GET   https://smsrota.com/v1/prices?service=wa
POST  https://smsrota.com/v1/activations  {"service":"wa","country":"187"}
GET   https://smsrota.com/v1/activations/:id
POST  https://smsrota.com/v1/activations/:id/retry
POST  https://smsrota.com/v1/activations/:id/complete
POST  https://smsrota.com/v1/activations/:id/cancel
GET   https://smsrota.com/v1/rent/prices?service=wa&hours=24
POST  https://smsrota.com/v1/rentals  {"service":"full","country":"16","hours":24}
GET   https://smsrota.com/v1/rentals/:id
POST  https://smsrota.com/v1/rentals/:id/extend  {"hours":24}
POST  https://smsrota.com/v1/rentals/:id/finish
POST  https://smsrota.com/v1/rentals/:id/cancel
POST  https://smsrota.com/v1/rentals/:id/dispute  {"reason":"no_sms"}
PUT   https://smsrota.com/v1/webhook  {"url":"https://example.com/sms-webhook"}
POST  https://smsrota.com/v1/webhook/test
GET   https://smsrota.com/v1/webhook/events

Webhooks

Defina um URL em Acesso API no seu painel. Enviamos um POST com corpo JSON para cada evento. Responda com qualquer estado 2xx em 10 segundos; caso contrário, tentamos de novo após 1, 5, 30, 120, 360 e 720 minutos.

activation.sms_received
Chegou um código para um número que comprou.
activation.cancelled
Um número foi cancelado ou expirou e o dinheiro voltou ao seu saldo.
rental.sms_received
Chegou um SMS a um número alugado.
rental.ended
Um aluguer terminou ou foi cancelado.

Corpo de exemplo

{
  "id": "evt_1042",
  "type": "activation.sms_received",
  "createdAt": "2026-11-01T10:00:00.000Z",
  "data": {
    "activationId": 48151623,
    "service": "wa",
    "country": "187",
    "phone": "15550123456",
    "code": "123456"
  }
}

Verificar a assinatura

Cada pedido tem um cabeçalho X-Webhook-Signature como t=1730000000,v1=…, em que v1 é o HMAC-SHA256 hexadecimal de "t.body" calculado com o seu segredo de assinatura. Rejeite o pedido se a assinatura não corresponder ou se t tiver mais de 5 minutos.

import { createHmac, timingSafeEqual } from "node:crypto";

// rawBody: the request body exactly as received, before JSON parsing.
function verify(rawBody, header, secret) {
  const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;
  return fresh && v1.length === expected.length && timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}

Erros

BAD_KEY
A chave API está errada ou foi substituída.
NO_NUMBERS
De momento não há stock para este serviço e país.
NO_BALANCE
O seu saldo é insuficiente para este número.
EARLY_CANCEL_DENIED
Pode cancelar dois minutos após a compra.
NO_ACTIVATION
O id de ativação não existe ou não é seu.