1 Escolha uma plataforma 1.304 serviços respondendo

Selecione um serviço

2 Escolha um país 145 países

Selecione um país

3 Operadora e tarifa

Informe uma plataforma e um país, em qualquer ordem. A operadora e a tarifa aparecem aqui.

Para desenvolvedores

Referência da API

Leia o saldo e a tarifa vigente de qualquer serviço em qualquer país direto do seu próprio código. Uma chave, levada em um cabeçalho, e JSON como resposta.

Endereço base

https://smsactivate.io/api/v1
Emitir uma chave

Primeira requisição #

JSON sobre HTTPS do começo ao fim, autenticado por uma chave que você mesmo gera. Nada para instalar, nada para assinar, nenhum ambiente de testes a ser liberado — bastam uma chave e o curl.

  1. 1 Gere uma chave Menu da conta, depois chave de API, depois criar. Ela aparece uma única vez e só o hash dela é guardado, então depois não há onde consultá-la.
  2. 2 Apresente-a como token bearer Cada chamada leva um cabeçalho Authorization. Não existe uma segunda porta de entrada: nem parâmetro de consulta, nem cookie, nem sessão.
  3. 3 Leia a resposta Toda resposta é um objeto JSON com um campo ok. Quando ok é false, um campo error nomeia a causa com uma string estável, feita para o seu código.

Como apresentar a chave #

Uma chave por conta. Qualquer caminho que não seja o cabeçalho abaixo não é suportado, e isso é proposital: uma chave na query string acaba nos logs de acesso, no histórico do navegador e nos cabeçalhos de referência, então ela é recusada de saída em vez de ser aceita e vazada em silêncio.

request
Authorization: Bearer sk_your_key_here

Esta chave gasta dinheiro Hoje ela lê um saldo; a mesma chave fará pedidos assim que pedidos existirem. Trate-a como uma senha: nunca num repositório, nunca numa captura de tela, substituída em vez de repassada. Gerar uma substituta aposenta a anterior na hora.

Formatos e convenções #

Formatos e convenções
Endereço base https://smsactivate.io/api/v1
Transporte Só por HTTPS: uma chamada em HTTP simples recebe um redirecionamento, e esse redirecionamento perde o seu cabeçalho Authorization.
Formato JSON nos dois sentidos. O que volta é sempre um objeto — um array solto nunca é uma resposta válida.
Sucesso HTTP 200, com "ok" em true.
Falha Um status 4xx ou 5xx, "ok" em false e uma string "error" cuja grafia nunca muda.
Valores Os valores são números em dólares americanos — nem strings, nem centavos: 0.84 são oitenta e quatro centavos.
Campos desconhecidos Qualquer resposta pode ganhar campos com o tempo. Pule os que você não reconhecer em vez de tratá-los como erro.

Quando algo falha #

Ramifique pela string error e por mais nada. A frase ao lado existe para você, não para o seu código, e pode ser reescrita a qualquer momento; a string não.

Quando algo falha
Status error Causa
401 missing_key Nenhum cabeçalho Authorization chegou, ou o que chegou não era um token bearer.
401 bad_key A chave não é uma que conhecemos, ou já foi aposentada ou substituída.
400 unknown_service Nenhum serviço responde a esse código. Os códigos saem do catálogo, nunca do nome exibido na tela.
404 no_stock Não há nada livre para essa combinação de serviço e país neste momento.
404 unknown_country Nenhum país responde a esse código para este produto. Os catálogos não cobrem o mesmo terreno.
400 unknown_tech Essa geração de rede não é oferecida neste país. Só os Estados Unidos são vendidos por região.
429 rate_limited Chamadas demais. O cabeçalho Retry-After indica a espera, em segundos.

Até onde dá para forçar #

600 chamadas por minuto, contadas por conta e não por endereço. Uma chave é feita para viver num único servidor — um único endereço — então contar por endereço puniria o uso normal e deixaria uma chave roubada livre para trabalhar de qualquer outro lugar. Passado o teto, você recebe um 429 com Retry-After em segundos.

Rotas #

Leituras de conta e de catálogo. Cada rota lista todos os parâmetros que aceita, todos os campos que devolve, e todas as formas como pode recusar.

O que a conta tem #

GET /api/v1/balance

O crédito disponível agora, e quantas ativações isso cobre ao menor preço do catálogo.

O que volta

O que a conta tem — O que volta
Campo Tipo Significado
ok boolean Presente e true sempre que o status for 200.
balance number Os dólares do saldo, até o centavo.
currency string Fixo em "USD"; é enviado para que nada precise ser presumido.
codes_at_cheapest integer Quantos códigos o saldo cobriria ao menor preço do catálogo. Uma estimativa para dar noção de escala, não uma cotação; null quando o catálogo está vazio.
cheapest_code number Esse menor preço em si, caso você queira refazer a estimativa contra outro número.

Chamada

request
curl -s "https://smsactivate.io/api/v1/balance" \
  -H "Authorization: Bearer $SMSACTIVATE_KEY"

Resposta

200 OK
{
  "ok": true,
  "balance": 42.5,
  "currency": "USD",
  "codes_at_cheapest": 425,
  "cheapest_code": 0.1
}

Como ela recusa missing_key bad_key rate_limited

Um serviço num país #

GET /api/v1/pricing?service={service}&country={country}

Preço e contagem de linhas livres ao vivo para uma única combinação. Os dois oscilam: o preço acompanha a operadora mais barata que tem aquele serviço ali, e a contagem é o que a operadora informa naquele instante.

O que recebe

Um serviço num país — O que recebe
Nome Significado
service obrigatório O código do serviço, telegram por exemplo — em minúsculas, como está escrito no catálogo.
country pode ser omitido O código do país, england por exemplo. Omita-o e todos os países voltam numa única chamada — veja abaixo.

O que volta

Um serviço num país — O que volta
Campo Tipo Significado
ok boolean Presente e true sempre que o status for 200.
service string O código do serviço, devolvido sem alteração.
country string O código do país, devolvido sem alteração.
price number O preço em dólares de um código na operadora mais barata que o tenha.
stock integer A quantidade de números que as operadoras informam como livres agora — uma leitura ao vivo, que muda de minuto a minuto.

Chamada

request
curl -s "https://smsactivate.io/api/v1/pricing?service=telegram&country=england" \
  -H "Authorization: Bearer $SMSACTIVATE_KEY"

Resposta

200 OK
{
  "ok": true,
  "service": "telegram",
  "country": "england",
  "price": 0.84,
  "stock": 61213
}

Como ela recusa missing_key bad_key unknown_service no_stock rate_limited

Um serviço, todos os países #

GET /api/v1/pricing?service={service}

Omita o país e voltam todos os países que levam aquele serviço. A ordenação é a do próprio site — primeiro o que de fato entrega, e dentro disso o mais barato — e não o preço puro, que jogaria para o topo um número de dois centavos em que ninguém recebe nada.

O que recebe

Um serviço, todos os países — O que recebe
Nome Significado
service obrigatório O código do serviço, telegram por exemplo.

O que volta

Um serviço, todos os países — O que volta
Campo Tipo Significado
ok boolean Presente e true sempre que o status for 200.
service string O código do serviço que você enviou.
name string O nome exibido no site, "Telegram" por exemplo.
countries array Um objeto por país, na ordem explicada acima.
countries[].country string O código do país, pronto para passar à chamada do par.
countries[].name string O nome dele em inglês.
countries[].price number O preço em dólares de um código.
countries[].stock integer Números livres neste momento.

Chamada

request
curl -s "https://smsactivate.io/api/v1/pricing?service=telegram" \
  -H "Authorization: Bearer $SMSACTIVATE_KEY"

Resposta

200 OK
{
  "ok": true,
  "service": "telegram",
  "name": "Telegram",
  "countries": [
    { "country": "england", "name": "United Kingdom", "price": 0.84, "stock": 61213 },
    { "country": "poland",  "name": "Poland",         "price": 0.91, "stock": 22140 }
  ]
}

Como ela recusa missing_key bad_key unknown_service rate_limited

Preços das sessões móveis #

GET /api/v1/proxy-pricing?country={country}&tech={tech}

Sem país indicado você recebe os quatro onde mantemos modems, cada um com uma contagem de operadoras e um preço inicial. Indique um e você recebe todas as operadoras de lá com o custo de cada prazo. Os prazos vêm em dias: 1, 7, 30, 365.

O que recebe

Preços das sessões móveis — O que recebe
Nome Significado
country pode ser omitido O código do país, us por exemplo. Omita-o e, em vez disso, os países são listados.
tech pode ser omitido A geração, 4g ou 5g. Só os Estados Unidos oferecem as duas; em qualquer outro lugar o campo é desconsiderado e a única faixa disponível é devolvida.

O que volta

Preços das sessões móveis — O que volta
Campo Tipo Significado
ok boolean Presente e true sempre que o status for 200.
country string O código do país que você enviou.
tech string A geração a que o preço se aplica, depois de escolhido o padrão.
techs array Cada geração à venda naquele país.
terms array Os prazos oferecidos, em dias.
carriers array Um objeto por operadora.
carriers[].carrier string O código da operadora, para passar na hora do pedido.
carriers[].name string O nome de exibição da operadora, "T-Mobile" por exemplo.
carriers[].prices object O preço em dólares de cada prazo, indexado pela duração em dias.

Chamada

request
curl -s "https://smsactivate.io/api/v1/proxy-pricing?country=us" \
  -H "Authorization: Bearer $SMSACTIVATE_KEY"

Resposta

200 OK
{
  "ok": true,
  "country": "us",
  "tech": "4g",
  "techs": ["4g", "5g"],
  "terms": [1, 7, 30, 365],
  "carriers": [
    { "carrier": "us-t-mobile", "name": "T-Mobile", "prices": { "1": 8.67, "7": 52, "30": 130, "365": 1300 } },
    { "carrier": "us-verizon",  "name": "Verizon",  "prices": { "1": 8.67, "7": 52, "30": 130, "365": 1300 } }
  ]
}

Como ela recusa missing_key bad_key unknown_country unknown_tech rate_limited

Preços dos prazos #

GET /api/v1/rental-pricing?country={country}&days={days}

Sem país indicado você recebe todos os países onde é possível manter um número, cada um com seu preço inicial. Indique um e você recebe todas as operadoras de lá e quanto custa nelas o prazo sobre o qual você perguntou.

O que recebe

Preços dos prazos — O que recebe
Nome Significado
country pode ser omitido O código do país, fr por exemplo. Omita-o e, em vez disso, os países são listados.
days pode ser omitido A duração em dias — 7, 14 ou 30. Qualquer outro valor é tratado como o prazo mais curto.

O que volta

Preços dos prazos — O que volta
Campo Tipo Significado
ok boolean Presente e true sempre que o status for 200.
country string O código do país que você enviou.
days integer O prazo a que o preço se aplica.
terms array Cada prazo à venda, em dias.
operators array Um objeto por operadora, o menor preço primeiro.
operators[].operator string O código da operadora, para passar na hora do pedido.
operators[].name string O nome exibido.
operators[].type string Um destes valores: physical, virtual ou premium.
operators[].price number O preço em dólares do prazo inteiro.

Chamada

request
curl -s "https://smsactivate.io/api/v1/rental-pricing?country=fr&days=30" \
  -H "Authorization: Bearer $SMSACTIVATE_KEY"

Resposta

200 OK
{
  "ok": true,
  "country": "fr",
  "days": 30,
  "terms": [7, 14, 30],
  "operators": [
    { "operator": "fr-lycamobile", "name": "Lycamobile", "type": "virtual",  "price": 14.32 },
    { "operator": "fr-orange",     "name": "Orange",     "type": "physical", "price": 20.76 }
  ]
}

Como ela recusa missing_key bad_key unknown_country rate_limited

Exemplos completos #

Programas que funcionam do jeito que estão, e não fragmentos de uma linha só — incluindo as duas partes que mais confundem.

Shell #

Encontra o país mais barato para um serviço e confirma que o saldo dá.

cheapest.sh
#!/usr/bin/env bash
set -euo pipefail
: "${SMSACTIVATE_KEY:?export your key first}"
API="https://smsactivate.io/api/v1"

auth=(-H "Authorization: Bearer $SMSACTIVATE_KEY")

# The catalogue is already ordered: the first country is the one to take.
best=$(curl -sf "${API}/pricing?service=telegram" "${auth[@]}" \
        | jq -r ".countries[0] | \"\(.country) \(.price)\"")
country=${best% *}
price=${best#* }

balance=$(curl -sf "${API}/balance" "${auth[@]}" | jq -r .balance)

# ⚠️ Compare as numbers, not as strings: "9.5" > "10" is true in a string sort.
if awk "BEGIN{exit !($balance >= $price)}"; then
  echo "ok: $country at \$$price, balance \$$balance"
else
  echo "top up first: need \$$price, have \$$balance" >&2
  exit 1
fi

JavaScript #

O mesmo em Node, tratando direito o formato do erro.

pricing.mjs
const API = "https://smsactivate.io/api/v1";
const key = process.env.SMSACTIVATE_KEY;

async function call(path) {
  const r = await fetch(API + path, {
    headers: { Authorization: `Bearer ${key}` },
  });
  const body = await r.json();
  // A non-2xx always carries { ok:false, error }. Branch on `error`, never on
  // the sentence — the string is stable, the wording is not.
  if (!r.ok || !body.ok) {
    if (body.error === "rate_limited") {
      const wait = Number(r.headers.get("Retry-After") || 60);
      await new Promise((s) => setTimeout(s, wait * 1000));
      return call(path);
    }
    throw new Error(body.error ?? `http_${r.status}`);
  }
  return body;
}

const { countries } = await call("/pricing?service=telegram");
const { balance }   = await call("/balance");

const best = countries[0];
console.log(`${best.name}: $${best.price} (${best.stock} in stock)`);
console.log(balance >= best.price ? "balance covers it" : "top up first");

Python #

E em Python, repetindo a chamada diante de um 429 do mesmo jeito.

pricing.py
import os, time, requests

API = "https://smsactivate.io/api/v1"
S = requests.Session()
S.headers["Authorization"] = f"Bearer {os.environ['SMSACTIVATE_KEY']}"

def call(path):
    r = S.get(API + path, timeout=20)
    body = r.json()
    if not r.ok or not body.get("ok"):
        if body.get("error") == "rate_limited":
            time.sleep(int(r.headers.get("Retry-After", 60)))
            return call(path)
        raise RuntimeError(body.get("error", f"http_{r.status_code}"))
    return body

countries = call("/pricing?service=telegram")["countries"]
balance   = call("/balance")["balance"]

best = countries[0]
print(f"{best['name']}: ${best['price']} ({best['stock']} in stock)")
print("balance covers it" if balance >= best["price"] else "top up first")

O que ainda não está aqui #

Hoje a chave lê a conta e o catálogo. Fazer pedidos é o próximo passo, e vai responder no mesmo endereço base com a mesma chave — então nada do que você escrever contra estas rotas precisará ser desfeito quando chegar.

Pedir um número Ainda não Ainda não. Por enquanto, o pedido é feito no site.
Consultar o código em loop Ainda não Previsto, junto com os pedidos.
Liberar um número Ainda não Previsto, junto com os pedidos.
Aluguel pela API Ainda não Previsto.
Webhooks Ainda não Ainda não — chega junto com os eventos de pedido, quando houver algum a entregar.

Esta página cresce junto: o que já está aqui fica onde está, e o que for novo aparece em Endpoints.

O que mudou #

  • Primeira versão pública: chaves de API, GET /balance, GET /pricing.