URL de base
Toutes les routes ci-dessous utilisent cette URL et renvoient du JSON UTF-8.
https://master-sms.shop/api/v1
Master sms API
Intégrez des numéros virtuels et la réception de SMS avec une API sûre et prévisible.
Toutes les routes ci-dessous utilisent cette URL et renvoient du JSON UTF-8.
https://master-sms.shop/api/v1
Créez une clé dans le tableau de bord, gardez le secret côté serveur et lancez une première consultation du solde.
Gérer les clésEnvoyez les deux identifiants sur chaque route protégée.
Accept: application/json Content-Type: application/json X-API-Key: your_api_key X-API-Secret: your_api_secret
Les succès renvoient success=true et data. Les erreurs renvoient success=false, error et le statut HTTP correspondant.
{
"success": true,
"data": {
"example": "value"
},
"timestamp": 1785078000
}{
"success": false,
"error": "Description de l’erreur",
"code": 400
}Les routes documentées correspondent au contrôleur public de l’API v1.
/health
Route publique
Confirme que l’API fonctionne et renvoie sa version.
{
"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
Authentification requise
Renvoie le solde total, bloqué, disponible et la devise.
{
"success": true,
"data": {
"balance": 1250.5,
"blocked": 50,
"available": 1200.5,
"currency": "BRL",
"limit": 0
},
"timestamp": 1785078000
}/services
Authentification requise
Liste pays, services, opérateurs, fournisseurs, prix calculés et stock.
| Paramètre | Type | Description | Exemple |
|---|---|---|---|
country | string | Code numérique du pays. | 73 |
service | string | Code du service, par exemple wa. | wa |
operator | string | Opérateur précis ou liste acceptée par le fournisseur. | claro |
available | boolean | Si true, renvoie uniquement les éléments en stock. | true |
provider | string | Nom ou identifiant du fournisseur. | Hero SMS |
search | string | Recherche textuelle par service. | 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
Authentification requise
Achète un numéro virtuel et crée une activation SMS.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
service | string | Oui | Code du service, par exemple wa. |
country | string | Oui | Code numérique du pays. |
request_id | string | Oui | Identifiant unique de tentative d’achat empêchant les doublons. |
operator | string | Non | Opérateur précis ou liste acceptée par le fournisseur. |
provider | string | Non | Nom ou identifiant du fournisseur. |
max_price | number | Non | Prix maximal accepté dans la devise renvoyée par l’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}
Authentification requise
Actualise et renvoie le statut, le numéro et le code SMS.
| Paramètre | Obligatoire | Description |
|---|---|---|
activation_id | Oui | ID renvoyé par l’achat. |
| Status | Description |
|---|---|
pending | En attente du SMS. |
received | SMS reçu ; code contient le code. |
canceled | Activation annulée. |
expired | Activation expirée. |
{
"success": true,
"data": {
"activation_id": "ACT17850780001234",
"status": "received",
"phone": "5511999999999",
"created_at": 1785078000,
"code": "123456",
"received_at": 1785078060
},
"timestamp": 1785078060
}/cancel
Authentification requise
Annule une activation éligible et indique le remboursement.
{ "activation_id": "ACT17850780001234" }{
"success": true,
"data": {
"activation_id": "ACT17850780001234",
"status": "canceled",
"refunded": true,
"refund_amount": 2.5
},
"timestamp": 1785078300
}/webhook
Authentification requise
Enregistre, liste et supprime les destinations des événements asynchrones.
| Événement | Description |
|---|---|
sms.received | SMS reçu. |
sms.purchased | Numéro acheté. |
sms.status | Statut d’activation modifié. |
balance.low | Solde sous le seuil configuré. |
| Champ | Obligatoire | Description |
|---|---|---|
event | Oui | Nom de l’événement signé. |
url | Oui | URL HTTPS publique recevant un POST JSON. |
secret | Non | Secret utilisé pour la signature HMAC SHA-256. |
{
"event": "sms.received",
"url": "https://example.com/webhooks/master-sms",
"secret": "replace_with_a_random_secret"
}La liste ne renvoie jamais le secret enregistré.
{ "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
Authentification requise
Renvoie les totaux d’achats, SMS reçus, annulations, dépenses et remboursements.
{
"success": true,
"data": {
"total_compras": 42,
"total_recebidos": 31,
"total_cancelados": 11,
"total_gasto": 79.5,
"total_estornado": 21
},
"timestamp": 1785078000
}/commissions
Authentification requise
Renvoie les commissions en attente, payées et l’historique du revendeur authentifié.
{
"success": true,
"data": {
"pending_total": 15.3,
"paid_total": 120,
"commissions": []
},
"timestamp": 1785078000
}Le corps brut est signé en HMAC SHA-256. Comparez X-Webhook-Signature en temps constant avant de traiter le 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);
Clients backend minimaux. Adaptez timeouts, logs et stockage des secrets.
<?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"}'
Copiez ce prompt, indiquez votre stack et envoyez-le à une IA de programmation. Ne collez jamais votre API Secret.
| Code | Signification | Traitement recommandé |
|---|---|---|
400 | Requête invalide | Corrigez JSON, champs obligatoires ou règles. |
401 | Non authentifié | Vérifiez X-API-Key et X-API-Secret. |
402 | Solde insuffisant | Rechargez le compte avant l’achat. |
403 | Accès refusé | Activez la permission ou vérifiez la liste d’IP. |
404 | Introuvable | Vérifiez route, service, stock ou activation_id. |
405 | Méthode invalide | Utilisez la méthode HTTP documentée. |
409 | Conflit d’idempotence | Ne réutilisez pas request_id pour un autre achat. |
429 | Limite dépassée | Attendez et réessayez avec backoff. |
500 | Erreur interne | Conservez request_id et réessayez sans dupliquer l’achat. |
La limite par minute dépend de la clé et figure dans X-RateLimit-Limit. Sur HTTP 429, utilisez un backoff exponentiel avec jitter.