URL base
Todas as rotas abaixo usam esta URL base e retornam JSON em UTF-8.
https://master-sms.shop/api/v1
Master sms API
Integre números virtuais e recebimento de SMS ao seu sistema com uma API segura e previsível.
Todas as rotas abaixo usam esta URL base e retornam JSON em UTF-8.
https://master-sms.shop/api/v1
Crie uma chave no painel, mantenha o secret somente no servidor e faça a primeira consulta de saldo.
Gerenciar chavesEnvie as duas credenciais em todas as rotas protegidas.
Accept: application/json Content-Type: application/json X-API-Key: your_api_key X-API-Secret: your_api_secret
Sucessos retornam success=true e data. Erros retornam success=false, error e o código HTTP correspondente.
{
"success": true,
"data": {
"example": "value"
},
"timestamp": 1785078000
}{
"success": false,
"error": "Descrição do erro",
"code": 400
}As rotas documentadas abaixo correspondem ao front controller público da API v1.
/health
Rota pública
Confirma que a API está operacional e informa sua versão.
{
"success": true,
"data": {
"version": "4.2.0",
"status": "operational",
"timestamp": 1785078000,
"server_time": "2026-07-26 12:00:00",
"request_id": "req_01K123EXAMPLE"
},
"timestamp": 1785078000
}/balance
Requer autenticação
Retorna saldo total, bloqueado, disponível e moeda da conta.
{
"success": true,
"data": {
"balance": 1250.5,
"blocked": 50,
"available": 1200.5,
"currency": "BRL",
"limit": 0
},
"timestamp": 1785078000
}/services
Requer autenticação
Lista países, serviços, operadoras, provedores, preços calculados e estoque.
| Parâmetro | Tipo | Descrição | Exemplo |
|---|---|---|---|
country | string | Código numérico do país. | 73 |
service | string | Código do serviço, por exemplo wa. | wa |
operator | string | Operadora específica. Também pode ser uma lista aceita pelo provedor. | claro |
available | boolean | Quando true, retorna somente itens com estoque. | true |
provider | string | Nome ou identificador do provedor. | Hero SMS |
search | string | Busca textual por serviço. | WhatsApp |
GET https://master-sms.shop/api/v1/services?country=73&available=true
{
"success": true,
"data": [
{
"country_id": "73",
"country_name": "Brasil",
"services": [
{
"code": "wa",
"name": "WhatsApp",
"operator": "claro",
"price": 2.5,
"stock": 150,
"provider": "Hero SMS",
"category": "messenger",
"markup": 10
}
]
}
],
"timestamp": 1785078000
}/buy
Requer autenticação
Compra um número virtual e cria uma ativação de SMS.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
service | string | Sim | Código do serviço, por exemplo wa. |
country | string | Sim | Código numérico do país. |
request_id | string | Sim | Identificador único da tentativa de compra para impedir duplicidade. |
operator | string | Não | Operadora específica. Também pode ser uma lista aceita pelo provedor. |
provider | string | Não | Nome ou identificador do provedor. |
max_price | number | Não | Preço máximo aceito na moeda retornada pela API. |
{
"service": "wa",
"country": "73",
"operator": "claro",
"provider": "Hero SMS",
"max_price": 5,
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"success": true,
"data": {
"activation_id": "ACT17850780001234",
"phone": "5511999999999",
"operator": "claro",
"price": 2.5,
"currency": "BRL",
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"service_name": "WhatsApp"
},
"timestamp": 1785078000
}/status?activation_id={id}
Requer autenticação
Atualiza e retorna o status, número e código SMS de uma ativação.
| Parâmetro | Obrigatório | Descrição |
|---|---|---|
activation_id | Sim | ID retornado pela compra. |
| Status | Descrição |
|---|---|
pending | Aguardando SMS. |
received | SMS recebido; code contém o código. |
canceled | Ativação cancelada. |
expired | Ativação expirada. |
{
"success": true,
"data": {
"activation_id": "ACT17850780001234",
"status": "received",
"phone": "5511999999999",
"created_at": 1785078000,
"code": "123456",
"received_at": 1785078060
},
"timestamp": 1785078060
}/cancel
Requer autenticação
Cancela uma ativação elegível e informa o estorno.
{ "activation_id": "ACT17850780001234" }{
"success": true,
"data": {
"activation_id": "ACT17850780001234",
"status": "canceled",
"refunded": true,
"refund_amount": 2.5
},
"timestamp": 1785078300
}/webhook
Requer autenticação
Registra, lista e remove destinos para eventos assíncronos.
| Evento | Descrição |
|---|---|
sms.received | SMS recebido. |
sms.purchased | Número comprado. |
sms.status | Status da ativação alterado. |
balance.low | Saldo abaixo do limite configurado. |
| Campo | Obrigatório | Descrição |
|---|---|---|
event | Sim | Nome do evento assinado. |
url | Sim | URL HTTPS pública que receberá POST em JSON. |
secret | Não | Secret usado para gerar a assinatura HMAC SHA-256. |
{
"event": "sms.received",
"url": "https://example.com/webhooks/master-sms",
"secret": "replace_with_a_random_secret"
}A listagem nunca devolve o secret armazenado.
{ "webhook_id": 1 }{
"event": "sms.received",
"timestamp": 1785078060,
"data": {
"activation_id": "ACT17850780001234",
"code": "123456",
"phone": "5511999999999",
"service": "wa",
"received_at": 1785078060
},
"signature": "legacy_body_signature"
}/stats
Requer autenticação
Retorna totais de compras, recebimentos, cancelamentos, gastos e estornos do usuário.
{
"success": true,
"data": {
"total_compras": 42,
"total_recebidos": 31,
"total_cancelados": 11,
"total_gasto": 79.5,
"total_estornado": 21
},
"timestamp": 1785078000
}/commissions
Requer autenticação
Retorna comissões pendentes, pagas e o histórico do revendedor autenticado.
{
"success": true,
"data": {
"pending_total": 15.3,
"paid_total": 120,
"commissions": []
},
"timestamp": 1785078000
}O corpo bruto é assinado com HMAC SHA-256. Compare X-Webhook-Signature em tempo constante antes de processar o JSON.
$rawBody = file_get_contents('php://input');
$received = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $rawBody, getenv('MASTER_SMS_WEBHOOK_SECRET'));
if ($received === '' || !hash_equals($expected, $received)) {
http_response_code(401);
exit;
}
$event = json_decode($rawBody, true, flags: JSON_THROW_ON_ERROR);
http_response_code(204);
Clientes mínimos para backend. Adapte timeouts, logs e armazenamento de secrets ao seu ambiente.
<?php
final class MasterSmsClient
{
public function __construct(
private string $apiKey,
private string $apiSecret,
private string $baseUrl = 'https://master-sms.shop/api/v1'
) {}
public function request(string $method, string $path, ?array $body = null): array
{
$ch = curl_init(rtrim($this->baseUrl, '/') . $path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Content-Type: application/json',
'X-API-Key: ' . $this->apiKey,
'X-API-Secret: ' . $this->apiSecret,
],
CURLOPT_POSTFIELDS => $body === null ? null : json_encode($body),
]);
$raw = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($raw === false) {
throw new RuntimeException(curl_error($ch));
}
curl_close($ch);
$result = json_decode($raw, true, flags: JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300 || empty($result['success'])) {
throw new RuntimeException($result['error'] ?? "HTTP {$status}", $status);
}
return $result['data'] ?? [];
}
}
$client = new MasterSmsClient(
getenv('MASTER_SMS_API_KEY'),
getenv('MASTER_SMS_API_SECRET')
);
$balance = $client->request('GET', '/balance');
$services = $client->request('GET', '/services?country=73&available=true');
$purchase = $client->request('POST', '/buy', [
'service' => 'wa',
'country' => '73',
'request_id' => bin2hex(random_bytes(16)),
]);
import os
import uuid
import requests
class MasterSmsClient:
def __init__(self):
self.base_url = "https://master-sms.shop/api/v1"
self.session = requests.Session()
self.session.headers.update({
"Accept": "application/json",
"Content-Type": "application/json",
"X-API-Key": os.environ["MASTER_SMS_API_KEY"],
"X-API-Secret": os.environ["MASTER_SMS_API_SECRET"],
})
def request(self, method, path, *, params=None, json=None):
response = self.session.request(
method, self.base_url + path, params=params, json=json, timeout=30
)
payload = response.json()
if not response.ok or not payload.get("success"):
raise RuntimeError(payload.get("error", f"HTTP {response.status_code}"))
return payload.get("data", {})
client = MasterSmsClient()
balance = client.request("GET", "/balance")
services = client.request("GET", "/services", params={
"country": "73", "available": "true"
})
purchase = client.request("POST", "/buy", json={
"service": "wa",
"country": "73",
"request_id": str(uuid.uuid4()),
})
import crypto from "node:crypto";
const baseUrl = "https://master-sms.shop/api/v1";
const headers = {
Accept: "application/json",
"Content-Type": "application/json",
"X-API-Key": process.env.MASTER_SMS_API_KEY,
"X-API-Secret": process.env.MASTER_SMS_API_SECRET,
};
async function request(method, path, body) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 30_000);
try {
const response = await fetch(baseUrl + path, {
method,
headers,
body: body ? JSON.stringify(body) : undefined,
signal: controller.signal,
});
const payload = await response.json();
if (!response.ok || !payload.success) {
throw new Error(payload.error ?? `HTTP ${response.status}`);
}
return payload.data ?? {};
} finally {
clearTimeout(timeout);
}
}
const balance = await request("GET", "/balance");
const purchase = await request("POST", "/buy", {
service: "wa",
country: "73",
request_id: crypto.randomUUID(),
});
export MASTER_SMS_API_KEY="your_api_key"
export MASTER_SMS_API_SECRET="your_api_secret"
export MASTER_SMS_BASE_URL="https://master-sms.shop/api/v1"
curl --fail-with-body --silent --show-error \
"$MASTER_SMS_BASE_URL/balance" \
-H "Accept: application/json" \
-H "X-API-Key: $MASTER_SMS_API_KEY" \
-H "X-API-Secret: $MASTER_SMS_API_SECRET"
curl --fail-with-body --silent --show-error \
"$MASTER_SMS_BASE_URL/buy" \
-X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-API-Key: $MASTER_SMS_API_KEY" \
-H "X-API-Secret: $MASTER_SMS_API_SECRET" \
--data '{"service":"wa","country":"73","request_id":"550e8400-e29b-41d4-a716-446655440000"}'
Copie este prompt, informe sua stack e envie a uma IA de programação. Substitua somente os placeholders; nunca cole sua API Secret na conversa.
| Código | Significado | Tratamento recomendado |
|---|---|---|
400 | Requisição inválida | Corrija JSON, campos obrigatórios ou regras da operação. |
401 | Não autenticado | Confira X-API-Key e X-API-Secret. |
402 | Saldo insuficiente | Recarregue a conta antes de comprar. |
403 | Sem permissão | Habilite a permissão na chave ou confira a whitelist de IP. |
404 | Não encontrado | Confira rota, serviço, estoque ou activation_id. |
405 | Método inválido | Use o método HTTP documentado. |
409 | Conflito de idempotência | Não reutilize request_id para outra compra. |
429 | Limite excedido | Aguarde e tente novamente com backoff. |
500 | Erro interno | Registre o request_id e tente novamente sem duplicar a compra. |
O limite por minuto depende da chave e é informado em X-RateLimit-Limit. Ao receber HTTP 429, use espera exponencial com jitter.