Documentation API SMS REST
Envoi de SMS transactionnels et marketing, avec sandbox, idempotence, webhooks AR et SDK PHP.
Vous cherchez une vue d'ensemble ? Découvrez notre API SMS (fonctionnalités, tarifs, cas d'usage) .
https://sms-proxima.com/api
Authorization: Bearer VOTRE_TOKEN
application/json
🚀 Démarrage rapide
Créez un compte
Inscrivez-vous et attendez la validation de votre compte.
Générez votre clé
Depuis votre espace API, générez votre token Bearer.
Envoyez votre premier SMS
Testez en sandbox — aucun crédit débité.
curl -X POST https://sms-proxima.com/api/sms/send \
-H "Authorization: Bearer VOTRE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "33612345678",
"sender": "BOUTIQUE",
"message": "Votre commande est confirmée.",
"sandbox": 1
}'
// Avec le SDK officiel
// composer require sms-proxima/sdk
use SmsProxima\SmsProxima;
$sms = new SmsProxima('VOTRE_TOKEN');
$result = $sms->send('33612345678', 'BOUTIQUE', 'Votre commande est confirmée.', ['sandbox' => 1]);
echo $result['ticket']; // api-42-1712345678
const res = await fetch('https://sms-proxima.com/api/sms/send', {
method: 'POST',
headers: {
'Authorization': 'Bearer VOTRE_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
to: '33612345678',
sender: 'BOUTIQUE',
message: 'Votre commande est confirmée.',
sandbox: 1,
}),
});
const data = await res.json();
console.log(data.ticket); // api-42-1712345678
import requests
response = requests.post(
'https://sms-proxima.com/api/sms/send',
headers={'Authorization': 'Bearer VOTRE_TOKEN'},
json={
'to': '33612345678',
'sender': 'BOUTIQUE',
'message': 'Votre commande est confirmée.',
'sandbox': 1,
}
)
data = response.json()
print(data['ticket']) # api-42-1712345678
📐 Formats & validation
Numéros de téléphone
Plusieurs formats sont acceptés — l'API normalise automatiquement.
Expéditeur (sender)
- Entre 4 et 11 caractères
- Lettres A-Z, a-z et chiffres 0-9 uniquement
- Pas d'accents, espaces, tirets ou caractères spéciaux
- Pas que des chiffres
- Pas 5 chiffres consécutifs
Longueur des messages & segments
| Segments | Caractères max (sans sender) | Caractères max (avec sender + STOP) |
|---|---|---|
| 1 | 160 | 148 |
| 2 | 306 | 294 |
| 3 | 459 | 447 |
| 6 (max) | 918 | 906 |
Les caractères accentués courants (à, é, è, ù, €) sont acceptés en GSM-7. Pour envoyer des emojis ou des caractères non latins (arabe, cyrillique…), utilisez le paramètre ucs2=1 — la capacité passe alors à 70 caractères par segment (67 en multi-segments).
🔑 Authentification
Toutes les requêtes doivent inclure ces headers :
Authorization: Bearer VOTRE_TOKEN Accept: application/json Content-Type: application/json
Test de connexion :
curl https://sms-proxima.com/api/ping \ -H "Authorization: Bearer VOTRE_TOKEN"
$sms = new SmsProxima('VOTRE_TOKEN');
$result = $sms->ping();
// ["message" => "Authentifié avec succès", "user" => [...]]
const res = await fetch('https://sms-proxima.com/api/ping', {
headers: { 'Authorization': 'Bearer VOTRE_TOKEN' },
});
const data = await res.json();
console.log(data.message); // Authentifié avec succès
import requests
res = requests.get('https://sms-proxima.com/api/ping',
headers={'Authorization': 'Bearer VOTRE_TOKEN'})
print(res.json()['message']) # Authentifié avec succès
/sms/send
📤 Envoi SMS
| Champ | Type | Requis | Description |
|---|---|---|---|
to | string|array | Oui | Un numéro ou un tableau de numéros au format international |
sender | string | Non | Expéditeur alphanumérique (4–11 caractères) — voir Formats & validation. Si omis, un numéro court (36xxx) est assigné automatiquement — nécessaire pour recevoir des réponses SMS. |
message | string|array | Oui | Contenu du SMS — max 6 segments. Accepte une chaîne unique (même message pour tous) ou un tableau aligné sur to[] pour des messages personnalisés (un message par destinataire). |
stop | int | Non | 0 ou 1 — défaut 1 (mention STOP ajoutée) |
timeToSend | string | Non | Envoi différé — YYYY/MM/DD HH:MM ou YYYY-MM-DD HH:MM, obligatoirement dans le futur |
sandbox | int | Non | 1 = simulation (SMS non envoyé, aucun crédit débité, même structure de réponse) |
ucs2 | int | Non | 1 = encodage Unicode (UCS-2). Requis pour les emojis et caractères non latins (arabe, cyrillique…). La capacité par segment passe de 160 à 70 caractères (67 en multi-segments). S'applique à l'ensemble des messages de la requête. |
curl -X POST https://sms-proxima.com/api/sms/send \
-H "Authorization: Bearer VOTRE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"to":"33612345678","sender":"BOUTIQUE","message":"Votre commande #1234 est confirmée."}'
$result = $sms->send('33612345678', 'BOUTIQUE', 'Votre commande #1234 est confirmée.');
const res = await fetch('https://sms-proxima.com/api/sms/send', {
method: 'POST',
headers: { 'Authorization': 'Bearer VOTRE_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({ to: '33612345678', sender: 'BOUTIQUE', message: 'Votre commande #1234 est confirmée.' }),
});
const data = await res.json();
import requests
res = requests.post('https://sms-proxima.com/api/sms/send',
headers={'Authorization': 'Bearer VOTRE_TOKEN'},
json={'to': '33612345678', 'sender': 'BOUTIQUE', 'message': 'Votre commande #1234 est confirmée.'})
data = res.json()
curl -X POST https://sms-proxima.com/api/sms/send \
-H "Authorization: Bearer VOTRE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"to":["33612345678","33687654321","33698765432"],"sender":"BOUTIQUE","message":"Vos soldes commencent demain !"}'
$result = $sms->send(
['33612345678', '33687654321', '33698765432'],
'BOUTIQUE',
'Vos soldes commencent demain !'
);
const res = await fetch('https://sms-proxima.com/api/sms/send', {
method: 'POST',
headers: { 'Authorization': 'Bearer VOTRE_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({
to: ['33612345678', '33687654321', '33698765432'],
sender: 'BOUTIQUE',
message: 'Vos soldes commencent demain !',
}),
});
res = requests.post('https://sms-proxima.com/api/sms/send',
headers={'Authorization': 'Bearer VOTRE_TOKEN'},
json={'to': ['33612345678', '33687654321'], 'sender': 'BOUTIQUE', 'message': 'Vos soldes commencent demain !'})
curl -X POST https://sms-proxima.com/api/sms/send \
-H "Authorization: Bearer VOTRE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"to":"33612345678","sender":"BOUTIQUE","message":"N oubliez pas votre RDV demain a 14h.","timeToSend":"2026-04-15 09:00"}'
$result = $sms->send('33612345678', 'BOUTIQUE', 'N oubliez pas votre RDV demain a 14h.',
['timeToSend' => '2026-04-15 09:00']);
const res = await fetch('https://sms-proxima.com/api/sms/send', {
method: 'POST',
headers: { 'Authorization': 'Bearer VOTRE_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({
to: '33612345678', sender: 'BOUTIQUE',
message: 'N oubliez pas votre RDV demain a 14h.',
timeToSend: '2026-04-15 09:00',
}),
});
res = requests.post('https://sms-proxima.com/api/sms/send',
headers={'Authorization': 'Bearer VOTRE_TOKEN'},
json={'to': '33612345678', 'sender': 'BOUTIQUE',
'message': 'N oubliez pas votre RDV demain a 14h.', 'timeToSend': '2026-04-15 09:00'})
curl -X POST https://sms-proxima.com/api/sms/send \
-H "Authorization: Bearer VOTRE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"to":"33612345678","sender":"TEST","message":"Test integration.","sandbox":1}'
# SMS non envoyé, crédits non débités, réponse identique à un vrai envoi
$result = $sms->send('33612345678', 'TEST', 'Test integration.', ['sandbox' => 1]);
const res = await fetch('https://sms-proxima.com/api/sms/send', {
method: 'POST',
headers: { 'Authorization': 'Bearer VOTRE_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({ to: '33612345678', sender: 'TEST', message: 'Test integration.', sandbox: 1 }),
});
res = requests.post('https://sms-proxima.com/api/sms/send',
headers={'Authorization': 'Bearer VOTRE_TOKEN'},
json={'to': '33612345678', 'sender': 'TEST', 'message': 'Test integration.', 'sandbox': 1})
curl -X POST https://sms-proxima.com/api/sms/send -H "Authorization: Bearer VOTRE_TOKEN" -H "Content-Type: application/json" -d '{
"to": ["33612345678", "33687654321"],
"sender": "BOUTIQUE",
"message": ["Bonjour Marie, votre commande est prete.", "Bonjour Nicolas, votre commande est prete."]
}'
$result = $sms->send(
['33612345678', '33687654321'],
'BOUTIQUE',
['Bonjour Marie, votre commande est prete.', 'Bonjour Nicolas, votre commande est prete.']
);
const res = await fetch('https://sms-proxima.com/api/sms/send', {
method: 'POST',
headers: { 'Authorization': 'Bearer VOTRE_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({
to: ['33612345678', '33687654321'],
sender: 'BOUTIQUE',
message: ['Bonjour Marie, votre commande est prete.', 'Bonjour Nicolas, votre commande est prete.'],
}),
});
res = requests.post('https://sms-proxima.com/api/sms/send',
headers={'Authorization': 'Bearer VOTRE_TOKEN'},
json={
'to': ['33612345678', '33687654321'],
'sender': 'BOUTIQUE',
'message': ['Bonjour Marie, votre commande est prete.', 'Bonjour Nicolas, votre commande est prete.'],
})
curl -X POST https://sms-proxima.com/api/sms/send -H "Authorization: Bearer VOTRE_TOKEN" -H "Content-Type: application/json" -d '{"to":"33612345678","sender":"BOUTIQUE","message":"Merci pour votre commande 🎉","ucs2":1}'
$result = $sms->send('33612345678', 'BOUTIQUE', 'Merci pour votre commande 🎉', ['ucs2' => 1]);
const res = await fetch('https://sms-proxima.com/api/sms/send', {
method: 'POST',
headers: { 'Authorization': 'Bearer VOTRE_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({ to: '33612345678', sender: 'BOUTIQUE', message: 'Merci pour votre commande 🎉', ucs2: 1 }),
});
res = requests.post('https://sms-proxima.com/api/sms/send',
headers={'Authorization': 'Bearer VOTRE_TOKEN'},
json={'to': '33612345678', 'sender': 'BOUTIQUE', 'message': 'Merci pour votre commande 🎉', 'ucs2': 1})
ucs2=1, un message contenant des emojis retournera une erreur INVALID_ENCODING.
Réponse succès
Réponse erreur
Codes machine possibles
| Code | HTTP | Description |
|---|---|---|
ACCOUNT_NOT_VALIDATED | 403 | Compte en attente de validation |
INSUFFICIENT_CREDITS | 402 | Crédits insuffisants |
INVALID_TIME_FORMAT | 422 | Format de timeToSend invalide |
INVALID_TIME_PAST | 422 | La date d'envoi est dans le passé |
MESSAGE_COUNT_MISMATCH | 422 | Le nombre de messages ne correspond pas au nombre de destinataires (mode message[]) |
EMPTY_MESSAGE | 422 | Un message du tableau est vide |
INVALID_ENCODING | 422 | Le message contient des caractères Unicode — ajouter ucs2=1 |
UCS2_NOT_ALLOWED | 422 | L'encodage UCS-2 n'est pas autorisé pour cette destination |
MOBILE_BLACKLISTED | 422 | Numéro en liste noire (STOP) |
SENDER_NOT_ALLOWED | 422 | Expéditeur non autorisé |
SUPPLIER_ERROR | 502 | Erreur fournisseur — contacter le support |
🔁 Idempotence (anti double-envoi)
Le endpoint POST /sms/send supporte l'idempotence pour éviter les doubles envois en cas de retry réseau.
curl -X POST https://sms-proxima.com/api/sms/send \
-H "Authorization: Bearer VOTRE_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{"to":"33612345678","sender":"BOUTIQUE","message":"..."}'
$result = $sms->send('33612345678', 'BOUTIQUE', '...', [
'idempotencyKey' => '550e8400-e29b-41d4-a716-446655440000',
]);
const res = await fetch('https://sms-proxima.com/api/sms/send', {
method: 'POST',
headers: {
'Authorization': 'Bearer VOTRE_TOKEN',
'Content-Type': 'application/json',
'Idempotency-Key': '550e8400-e29b-41d4-a716-446655440000',
},
body: JSON.stringify({ to: '33612345678', sender: 'BOUTIQUE', message: '...' }),
});
res = requests.post('https://sms-proxima.com/api/sms/send',
headers={
'Authorization': 'Bearer VOTRE_TOKEN',
'Idempotency-Key': '550e8400-e29b-41d4-a716-446655440000',
},
json={'to': '33612345678', 'sender': 'BOUTIQUE', 'message': '...'})
- Maximum 255 caractères — valide 24 heures
- Scope : par utilisateur et par endpoint
- Si rejouée dans les 24h → réponse originale avec header
Idempotency-Replayed: true - Seules les réponses HTTP 2xx sont mises en cache
/credits
💳 Crédits disponibles
curl https://sms-proxima.com/api/credits \ -H "Authorization: Bearer VOTRE_TOKEN"
$credits = $sms->credits(); // int
const res = await fetch('https://sms-proxima.com/api/credits', {
headers: { 'Authorization': 'Bearer VOTRE_TOKEN' },
});
const { credits } = await res.json();
res = requests.get('https://sms-proxima.com/api/credits',
headers={'Authorization': 'Bearer VOTRE_TOKEN'})
credits = res.json()['credits']
/sms/count
🔢 Comptage de caractères
Calculez le nombre de segments SMS avant envoi.
curl -X POST https://sms-proxima.com/api/sms/count \
-H "Authorization: Bearer VOTRE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"message":"Votre code : 1234"}'
$result = $sms->count('Votre code : 1234');
// ["nb_sms" => 1, "nb_caracteres" => 18]
const res = await fetch('https://sms-proxima.com/api/sms/count', {
method: 'POST',
headers: { 'Authorization': 'Bearer VOTRE_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({ message: 'Votre code : 1234' }),
});
const { nb_sms, nb_caracteres } = await res.json();
res = requests.post('https://sms-proxima.com/api/sms/count',
headers={'Authorization': 'Bearer VOTRE_TOKEN'},
json={'message': 'Votre code : 1234'})
data = res.json() # {"nb_sms": 1, "nb_caracteres": 18}
/sms/{tracker}/deliveries
📬 Accusés de réception
Liste paginée des AR reçus pour une campagne. Seuls les destinataires ayant généré un retour opérateur apparaissent. Pour les autres, consultez GET /campaigns (champ pending).
Paramètre de pagination : ?page=1 — 100 résultats par page.
curl "https://sms-proxima.com/api/sms/api-1-1712345678/deliveries?page=1" \ -H "Authorization: Bearer VOTRE_TOKEN"
$deliveries = $sms->deliveries('api-1-1712345678');
const res = await fetch('https://sms-proxima.com/api/sms/api-1-1712345678/deliveries?page=1', {
headers: { 'Authorization': 'Bearer VOTRE_TOKEN' },
});
const data = await res.json();
res = requests.get('https://sms-proxima.com/api/sms/api-1-1712345678/deliveries',
headers={'Authorization': 'Bearer VOTRE_TOKEN'},
params={'page': 1})
data = res.json()
| status | Description |
|---|---|
delivered | SMS remis au destinataire |
failed | Échec de remise (numéro invalide, hors service…) |
pending | En attente de retour opérateur |
/campaigns
📋 Historique campagnes
Retour paginé (50/page) avec statistiques d'envoi par campagne. Paramètre : ?page=1.
pending indique le nombre de destinataires pour lesquels aucun AR n'a encore été reçu. Pour les détails par destinataire, utilisez GET /sms/{ticket}/deliveries.
🚫 Blacklist
| Méthode | Endpoint | Description |
|---|---|---|
| GET | /blacklist | Liste des numéros blacklistés |
| POST | /blacklist | Ajouter — body : {"mobile": "33612345678"} |
| DELETE | /blacklist/{mobile} | Retirer un numéro |
Ajout
curl -X POST https://sms-proxima.com/api/blacklist \
-H "Authorization: Bearer VOTRE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"mobile":"33612345678"}'
$sms->addToBlacklist('33612345678');
await fetch('https://sms-proxima.com/api/blacklist', {
method: 'POST',
headers: { 'Authorization': 'Bearer VOTRE_TOKEN', 'Content-Type': 'application/json' },
body: JSON.stringify({ mobile: '33612345678' }),
});
requests.post('https://sms-proxima.com/api/blacklist',
headers={'Authorization': 'Bearer VOTRE_TOKEN'},
json={'mobile': '33612345678'})
Réponse
🔔 Webhooks
Configurez une URL HTTPS par type d'événement depuis votre espace API. SMS Proxima envoie un POST JSON signé (HMAC SHA-256) pour chaque événement.
| Event | Déclencheur |
|---|---|
delivery.receipt | Accusé de réception opérateur (livré ou échec) |
sms.stop | Le destinataire a répondu STOP |
sms.inbound | Réponse SMS d'un destinataire (hors STOP) |
delivery.receipt — Accusés de réception
Envoyé à chaque retour opérateur (livraison ou échec). L'event peut arriver plusieurs secondes après l'envoi.
| Header envoyé | Valeur |
|---|---|
X-SMSP-Event | Nom de l'événement (delivery.receipt, sms.stop, sms.inbound) |
X-SMSP-Id | Identifiant unique de l'événement |
X-SMSP-Timestamp | Timestamp Unix de l'envoi |
X-SMSP-Signature | t={ts}, v1={hmac_sha256} — présent si un secret est configuré |
Idempotency-Key | Identifiant de l'événement (anti-doublon) |
delivery.receipt — Accusés de réception
Envoyé à chaque retour opérateur (livraison ou échec).
Exemple PHP
// webhook.php — votre endpoint $payload = json_decode(file_get_contents('php://input'), true); $eventId = $payload['event_id'] ?? null; // Anti-doublon if (alreadyProcessed($eventId)) { http_response_code(200); exit; } $status = $payload['delivery']['status']; // "delivered", "failed" $mobile = $payload['message']['to']; markDelivered($mobile, $status); http_response_code(200);
sms.stop — STOP reçus
Envoyé quand un destinataire répond STOP. Le numéro est automatiquement ajouté à votre blacklist SMS Proxima.
$payload = json_decode(file_get_contents('php://input'), true);
if (alreadyProcessed($payload['event_id'] ?? null)) { http_response_code(200); exit; }
$mobile = $payload['message']['from']; // numéro qui a envoyé STOP
// Déjà blacklisté chez SMS Proxima — mettez à jour votre propre base
markUnsubscribed($mobile);
http_response_code(200);
sms.inbound — Réponses SMS
Envoyé quand un destinataire répond à votre SMS (hors STOP). Nécessite un expéditeur vide (numéro court).
$payload = json_decode(file_get_contents('php://input'), true);
if (alreadyProcessed($payload['event_id'] ?? null)) { http_response_code(200); exit; }
$from = $payload['message']['from']; // numéro expéditeur
$text = $payload['message']['text']; // contenu du SMS reçu
handleInboundSms($from, $text);
http_response_code(200);
event_id ou le header Idempotency-Key pour détecter les doublons.
📦 SDK PHP officiel
Compatible PHP 7.4+, zéro dépendance, open source.
// Installation composer require sms-proxima/sdk // Envoi simple use SmsProxima\SmsProxima; $sms = new SmsProxima('VOTRE_TOKEN'); $result = $sms->send('33612345678', 'BOUTIQUE', 'Commande confirmée'); // Gestion des erreurs use SmsProxima\Exceptions\InvalidSenderException; use SmsProxima\Exceptions\MobileBlacklistedException; use SmsProxima\Exceptions\InsufficientCreditsException; use SmsProxima\Exceptions\SmsProximaException; try { $sms->send(...); } catch (InvalidSenderException $e) { // expéditeur invalide } catch (MobileBlacklistedException $e) { // numéro STOP } catch (InsufficientCreditsException $e) { // crédits insuffisants } catch (SmsProximaException $e) { // autre erreur — $e->getApiCode() }
🔒 Bonnes pratiques
-
Ne jamais exposer votre token côté client — l'appel API doit toujours venir de votre serveur, jamais depuis du JavaScript public ou une app mobile.
-
Utilisez l'idempotence sur vos retries — en cas d'erreur réseau, rejouez la requête avec le même
Idempotency-Keypour éviter les doubles envois. -
Testez toujours en sandbox d'abord — paramètre
sandbox: 1, réponse identique à un vrai envoi, aucun crédit débité. -
Stockez les événements webhook pour traitement asynchrone — enregistrez le payload en base à la réception, traitez-le dans un job. Évite les timeouts et garantit la cohérence.
-
Régénérez votre token en cas de compromission — depuis votre espace API, la régénération est immédiate et invalide l'ancien token.
⚠️ Codes HTTP
Les codes HTTP indiquent le résultat au niveau transport. Les codes machine (code dans le body) précisent la raison métier.
| Code | Description |
|---|---|
| 200 | Succès |
| 201 | Ressource créée (ex : ajout blacklist) |
| 400 | Requête malformée (ex : clé d'idempotence trop longue) |
| 402 | Crédits insuffisants |
| 403 | Accès refusé (compte non validé, tracker invalide, numéro STOP protégé) |
| 404 | Ressource introuvable |
| 409 | Conflit (ex : numéro déjà en blacklist) |
| 422 | Paramètres invalides — voir le champ code dans la réponse |
| 502 | Erreur fournisseur — contacter le support |
Prêt à intégrer l'API ?
Créez un compte, générez votre clé et envoyez votre premier SMS en quelques minutes.