Para desenvolvedores
Documentação da API
Leia seu saldo e o preço em tempo real de qualquer serviço em qualquer país a partir do seu próprio código. Uma chave bearer, JSON sobre HTTPS, sem SDK para instalar.
Primeiros passos #
Tudo é JSON sobre HTTPS, autenticado com uma única chave que você mesmo cria. Não há SDK para instalar, contrato para assinar, nem sandbox para solicitar — uma chave e o curl bastam.
- 1 Criar chave Abra o menu da conta, depois Chave de API, depois Criar chave. Ela é exibida uma única vez: armazenamos apenas sua impressão digital, portanto não é possível consultá-la depois.
- 2 Envie como token bearer Toda requisição carrega um cabeçalho Authorization. Não há outra forma de entrada — nada de chave na query string, cookie ou sessão.
- 3 Leia a resposta Toda resposta é um objeto JSON com um campo ok. Quando ok é false, um campo error explica o motivo em uma string estável e legível por máquina.
Autenticação #
Uma chave por conta. Enviá-la de qualquer forma diferente do cabeçalho abaixo não é aceito — uma chave na query string acaba nos logs do servidor, no histórico do navegador e nos cabeçalhos referrer, por isso é recusada em vez de aceita silenciosamente.
Authorization: Bearer sk_your_key_here
A chave gasta dinheiro Ela consulta o saldo hoje, e é a mesma chave que vai pedir números quando a função de pedidos existir. Trate-a como uma senha: fora do controle de versão, fora de capturas de tela, substituída em vez de compartilhada. Substituir uma chave encerra a anterior imediatamente.
Convenções #
| Endereço base | https://simsms.com/api/v1 |
|---|---|
| Transporte | Somente HTTPS. HTTP simples é redirecionado, e o redirecionamento não carrega seu cabeçalho. |
| Formato | JSON na entrada, JSON na saída. Toda resposta é um objeto, nunca um array solto. |
| Sucesso | HTTP 200 com “ok”: true. |
| Falha | Um código 4xx ou 5xx com “ok”: false e uma string “error” estável. |
| Moeda | Números em dólares americanos, nunca como strings, nunca em centavos. 0.84 significa 84 centavos. |
| Campos novos | Novos campos podem ser adicionados a qualquer resposta. Ignore o que você não conhece, em vez de falhar por causa disso. |
Erros #
A string do campo error é a parte usada para decidir o fluxo do seu código. A frase ao lado é para você, não para o seu código — ela pode ser reformulada; a string, não.
| HTTP | erro | Quando |
|---|---|---|
| 401 | missing_key |
Nenhum cabeçalho Authorization, ou ele não é um token bearer. |
| 401 | bad_key |
A chave é desconhecida, ou foi encerrada ou substituída. |
| 400 | unknown_service |
Nenhum serviço com esse código. Os códigos vêm do catálogo, não do nome de exibição. |
| 404 | no_stock |
Esse par de serviço e país não tem número em estoque agora. É um valor em tempo real — o estoque pode voltar. |
| 404 | unknown_country |
Nenhum país com esse código nesse produto. Os catálogos de proxy e de aluguel têm cada um sua própria lista — chame a rota sem informar um país para obtê-la. |
| 400 | unknown_tech |
Não existe essa geração de rede nesse país. Somente os Estados Unidos vendem 4g e 5g. |
| 429 | rate_limited |
Requisições demais. Um cabeçalho Retry-After informa quantos segundos esperar. |
Limites #
600 requisições por minuto, contadas por conta, e não por endereço. Uma chave deve rodar a partir de um servidor — um único endereço — então um limite por endereço penalizaria o uso normal e deixaria uma chave roubada rodar livremente em outro lugar. Acima do limite, você recebe 429 e um cabeçalho Retry-After em segundos.
Rotas #
Leituras de conta e catálogo. Cada rota lista todos os parâmetros que aceita, todos os campos que retorna e todos os erros com que pode responder — sem comportamento não documentado.
Consultar seu saldo #
GET
/api/v1/balance
O que a conta tem agora, e quantos códigos isso compra pelo preço mais barato disponível no catálogo no momento.
Campos de resposta
| Campo | Tipo | Descrição |
|---|---|---|
ok |
boolean | Sempre true em um 200. |
balance |
number | Dólares disponíveis, arredondados ao centavo. |
currency |
string | Sempre “USD”. Presente para que você nunca precise supor isso. |
codes_at_cheapest |
integer | Quantos códigos o saldo compra pelo preço mais barato do catálogo. Uma estimativa aproximada, não uma cotação — null se o catálogo estiver vazio. |
cheapest_code |
number | Esse preço mais barato, para que você possa calcular a estimativa por conta própria com outro valor. |
Requisição
curl -s "https://simsms.com/api/v1/balance" \
-H "Authorization: Bearer $SIMSMS_KEY"
Resposta
{
"ok": true,
"balance": 42.5,
"currency": "USD",
"codes_at_cheapest": 425,
"cheapest_code": 0.1
}
Pode responder com missing_key bad_key rate_limited
Preço de um serviço em um país #
GET
/api/v1/pricing?service={service}&country={country}
O preço e o estoque em tempo real para um único par. Os dois valores mudam — o preço segue a rede mais barata que oferece esse serviço nesse país, e o estoque é o que a rede informa agora.
Parâmetros
| Parâmetro | Descrição | |
|---|---|---|
service |
obrigatório | Código do serviço, por exemplo telegram. Em minúsculas, do catálogo. |
country |
opcional | Código do país, por exemplo england. Deixe de fora para obter todos os países de uma vez — veja abaixo. |
Campos de resposta
| Campo | Tipo | Descrição |
|---|---|---|
ok |
boolean | Sempre true em um 200. |
service |
string | O código do serviço que você informou, repetido na resposta. |
country |
string | O código do país que você informou, repetido na resposta. |
price |
number | Dólares para um código, na rede mais barata que o tem disponível. |
stock |
integer | Números informados como disponíveis agora. É um valor em tempo real e ele muda. |
Requisição
curl -s "https://simsms.com/api/v1/pricing?service=telegram&country=england" \
-H "Authorization: Bearer $SIMSMS_KEY"
Resposta
{
"ok": true,
"service": "telegram",
"country": "england",
"price": 0.84,
"stock": 61213
}
Pode responder com missing_key bad_key unknown_service no_stock rate_limited
Preço de um serviço em todos os países #
GET
/api/v1/pricing?service={service}
Omita o país e você recebe todos os países que oferecem o serviço. A ordem é a própria do site: o que realmente entrega primeiro e, dentro disso, o mais barato — não o preço bruto, que colocaria no topo um valor de dois centavos do qual ninguém recebe código.
Parâmetros
| Parâmetro | Descrição | |
|---|---|---|
service |
obrigatório | Código do serviço, por exemplo telegram. |
Campos de resposta
| Campo | Tipo | Descrição |
|---|---|---|
ok |
boolean | Sempre true em um 200. |
service |
string | O código do serviço que você informou. |
name |
string | O nome de exibição, por exemplo “Telegram”. |
countries |
array | Um objeto por país, na ordem descrita acima. |
countries[].country |
string | Código do país, para usar na chamada correspondente. |
countries[].name |
string | Seu nome em inglês. |
countries[].price |
number | Dólares por um código. |
countries[].stock |
integer | Linhas disponíveis agora. |
Requisição
curl -s "https://simsms.com/api/v1/pricing?service=telegram" \
-H "Authorization: Bearer $SIMSMS_KEY"
Resposta
{
"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 }
]
}
Pode responder com missing_key bad_key unknown_service rate_limited
Preço do proxy móvel #
GET
/api/v1/proxy-pricing?country={country}&tech={tech}
Sem informar um país, você recebe os quatro países onde operamos modems, com o número de operadoras e o preço de entrada de cada um. Informando um país, você recebe todas as operadoras desse país e o preço de cada prazo. Os prazos são em dias: 1, 7, 30, 365.
Parâmetros
| Parâmetro | Descrição | |
|---|---|---|
country |
opcional | Código do país, por exemplo us. Omita para listar os países. |
tech |
opcional | Geração de rede, 4g ou 5g. Só os Estados Unidos vendem as duas; nos demais países o campo é ignorado e é retornada a única faixa. |
Campos de resposta
| Campo | Tipo | Descrição |
|---|---|---|
ok |
boolean | Sempre true em 200. |
country |
string | O país que você pediu. |
tech |
string | A geração realmente precificada, depois de aplicado o padrão. |
techs |
array | Todas as gerações vendidas nesse país. |
terms |
array | Os prazos à venda, em dias. |
carriers |
array | Um objeto por operadora. |
carriers[].carrier |
string | Código da operadora, para usar no pedido. |
carriers[].name |
string | O nome de exibição, por exemplo “T-Mobile”. |
carriers[].prices |
object | Dólares por prazo, indexados pelo número de dias. |
Requisição
curl -s "https://simsms.com/api/v1/proxy-pricing?country=us" \
-H "Authorization: Bearer $SIMSMS_KEY"
Resposta
{
"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 } }
]
}
Pode responder com missing_key bad_key unknown_country unknown_tech rate_limited
Preço do aluguel #
GET
/api/v1/rental-pricing?country={country}&days={days}
Sem informar um país, você recebe todos os países onde é possível manter um número, com o preço de entrada de cada um. Informando um país, você recebe todas as operadoras desse país e o custo do prazo que você pediu.
Parâmetros
| Parâmetro | Descrição | |
|---|---|---|
country |
opcional | Código do país, por exemplo fr. Omita para listar os países. |
days |
opcional | Prazo em dias: 7, 14 ou 30. Qualquer outro valor usa o menor prazo. |
Campos de resposta
| Campo | Tipo | Descrição |
|---|---|---|
ok |
boolean | Sempre true em 200. |
country |
string | O país que você pediu. |
days |
integer | O prazo realmente precificado. |
terms |
array | Todos os prazos à venda, em dias. |
operators |
array | Um objeto por operadora, começando pela mais barata. |
operators[].operator |
string | Código da operadora, para usar no pedido. |
operators[].name |
string | O nome de exibição. |
operators[].type |
string | physical, virtual ou premium. |
operators[].price |
number | Dólares pelo prazo todo. |
Requisição
curl -s "https://simsms.com/api/v1/rental-pricing?country=fr&days=30" \
-H "Authorization: Bearer $SIMSMS_KEY"
Resposta
{
"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 }
]
}
Pode responder com missing_key bad_key unknown_country rate_limited
Exemplos completos #
Programas completos e executáveis, em vez de fragmentos de uma linha — incluindo as duas coisas que os fragmentos sempre deixam de fora: tratar o formato do erro e aplicar backoff no 429.
Shell #
Encontra o país mais barato para um serviço e depois verifica se o saldo cobre o valor.
#!/usr/bin/env bash
set -euo pipefail
: "${SIMSMS_KEY:?export your key first}"
API="https://simsms.com/api/v1"
auth=(-H "Authorization: Bearer $SIMSMS_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 #
A mesma coisa em Node, tratando corretamente o formato do erro.
const API = "https://simsms.com/api/v1";
const key = process.env.SIMSMS_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 automaticamente em caso de 429.
import os, time, requests
API = "https://simsms.com/api/v1"
S = requests.Session()
S.headers["Authorization"] = f"Bearer {os.environ['SIMSMS_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")
Roteiro #
Hoje a API cobre leituras de conta e catálogo. A superfície de pedidos vem a seguir, e vai ficar sob o mesmo endereço base e usar a mesma chave — nada do que você construir agora vai precisar ser reescrito.
| Pedir um número | Previsto Planejado. Hoje os pedidos são feitos pelo site. |
|---|---|
| Consultar o código | Previsto Planejado, junto com os pedidos. |
| Liberar um número | Previsto Planejado, junto com os pedidos. |
| Aluguel pela API | Previsto Previsto. |
| Webhooks | Previsto Planejado, assim que houver eventos de pedido para entregar. |
Esta página cresce com eles: as seções abaixo permanecem onde estão, e novas são adicionadas em Endpoints.
Alterações #
- Primeira versão pública: chaves, GET /balance, GET /pricing.