Envoyer des SMS depuis vos applications
Une requête HTTP, une clé d'API, et le SMS part par une vraie ligne mobile. Pensé pour les notifications de nos sites et services : confirmations, rappels, alertes.
Démarrage rapide
Demandez une clé d'API à l'équipe Oktopod, puis envoyez votre premier SMS :
curl https://sms.oktocloud.app/sms \
-H "Authorization: Bearer $SMS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to": "06 12 34 56 78", "text": "Votre rendez-vous de demain 10 h est confirmé."}'Réponse, renvoyée dès que le réseau mobile a accepté le message (environ 1 seconde par SMS) :
{ "status": "sent", "to": "+33612345678", "encoding": "ucs2", "parts": 1, "references": [12] }Référence de l'API
Adresse de base : https://sms.oktocloud.app. Toutes les réponses sont en JSON.
Authentification
Chaque requête (sauf /health) doit porter la clé, au choix dans l'un de ces en-têtes :
Authorization: Bearer <clé> X-Api-Key: <clé>
Chaque application reçoit sa propre clé : on peut ainsi en révoquer une sans toucher aux autres.
POST /sms — envoyer un SMS
Corps en JSON (application/json) ou en formulaire (application/x-www-form-urlencoded).
| Champ | Type | Description |
|---|---|---|
to | texte | Numéro du destinataire. Formats acceptés : 06 12 34 56 78, 0612345678, +33612345678, 0033612345678. Espaces, points et tirets sont ignorés. |
text | texte | Contenu du message. Accents et emojis acceptés ; un message long est découpé automatiquement (voir Longueur). |
Paramètre d'URL facultatif : ?dryRun=1 vérifie la requête et calcule l'encodage et le nombre de SMS
sans rien envoyer.
| Champ de réponse | Description |
|---|---|
status | sent (accepté par le réseau) ou dry-run. |
to | Numéro normalisé au format international. |
encoding | gsm7 ou ucs2 (voir Longueur). |
parts | Nombre de SMS utilisés. |
references | Référence attribuée par l'opérateur à chaque SMS. |
GET /health — disponibilité
Sans clé. Renvoie 200 {"status":"up"} quand le service peut envoyer, 503 sinon
(modem éteint, pas de réseau). Utile pour une supervision.
GET /status — état détaillé
Avec clé. État de la carte SIM, du réseau et du signal, nombre de SMS envoyés dans l'heure et limites en vigueur.
{
"modem": { "connected": true, "ready": true, "sim": "READY", "registered": true,
"roaming": false, "operator": "20815", "signal": { "csq": 19, "dbm": -75 } },
"limits": { "perHour": 60, "usedLastHour": 3, "maxParts": 6 },
"allowedPrefixes": ["+336", "+337"]
}Exemples
La clé est lue depuis une variable d'environnement, jamais écrite dans le code.
<?php
// Dans un thème ou une extension WordPress ; définir SMS_API_KEY dans wp-config.php.
$response = wp_remote_post('https://sms.oktocloud.app/sms', [
'timeout' => 30,
'headers' => [
'Authorization' => 'Bearer ' . SMS_API_KEY,
'Content-Type' => 'application/json',
],
'body' => wp_json_encode([
'to' => '06 12 34 56 78',
'text' => 'Votre commande est prête.',
]),
]);
if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) {
error_log('SMS non envoyé : ' . wp_remote_retrieve_body($response));
}const res = await fetch("https://sms.oktocloud.app/sms", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SMS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ to: "06 12 34 56 78", text: "Votre commande est prête." }),
signal: AbortSignal.timeout(30_000),
});
const data = await res.json();
if (!res.ok) throw new Error(`SMS non envoyé (${res.status}) : ${data.error}`);import os, requests
r = requests.post(
"https://sms.oktocloud.app/sms",
headers={"Authorization": f"Bearer {os.environ['SMS_API_KEY']}"},
json={"to": "06 12 34 56 78", "text": "Votre commande est prête."},
timeout=30,
)
r.raise_for_status()
print(r.json())curl https://sms.oktocloud.app/sms \ -H "X-Api-Key: $SMS_API_KEY" \ --data-urlencode to=0612345678 \ --data-urlencode text="Alerte : le serveur ne répond plus"
Prévoyez un délai d'attente d'au moins 30 secondes : un message long envoie plusieurs SMS à la suite, et les envois de toutes les applications passent un par un.
Longueur et caractères
Un SMS n'a pas une longueur fixe : elle dépend des caractères utilisés. Le service choisit automatiquement l'encodage le plus économique.
| Encodage | Quand | 1 SMS | Ensuite |
|---|---|---|---|
| gsm7 | Alphabet GSM seul | 160 car. | 153 par SMS |
| ucs2 | Un caractère hors GSM | 70 car. | 67 par SMS |
Acceptés en GSM
- é
- è
- à
- ù
- É
- Ç
- €
- @
- £
- '
- "
€, [ ] { } ~ ^ | \ comptent pour 2 caractères.
Passent le message en UCS-2
- ç
- ê
- â
- î
- ô
- û
- ë
- œ
- ’
- « »
- …
- 😀
Un seul de ces caractères suffit à réduire la limite à 70.
’ (insérée automatiquement par
WordPress ou un traitement de texte) n'est pas dans l'alphabet GSM, contrairement à l'apostrophe droite
'. Une seule suffit à diviser par deux la place disponible.Un message découpé arrive en un seul bloc sur le téléphone, mais compte pour plusieurs SMS dans les limites.
Au-delà de 6 SMS, l'envoi est refusé (413).
Codes de réponse
En cas d'erreur, le corps contient {"error": "explication en français"}.
| Code | Signification | Que faire |
|---|---|---|
| 200 | SMS accepté par le réseau (ou simulation réussie) | — |
| 400 | Numéro ou texte invalide, JSON mal formé | Corriger la requête |
| 401 | Clé absente ou invalide | Vérifier l'en-tête et la clé |
| 403 | Destinataire non autorisé (seuls les mobiles français sont acceptés) | Demander l'ouverture d'un préfixe |
| 413 | Message trop long (plus de 6 SMS) ou requête trop lourde | Raccourcir le texte |
| 415 | Type de contenu non pris en charge | Envoyer du JSON ou un formulaire |
| 429 | Limite de 60 SMS par heure atteinte | Réessayer après le délai de l'en-tête Retry-After |
| 502 | Le réseau mobile a refusé le SMS | Réessayer plus tard, vérifier le numéro |
| 503 | Service momentanément indisponible (modem redémarré, pas de réseau) | Réessayer dans une minute |
Réessais : on peut relancer sans risque après un 429 ou un 503.
Après un 502 sur un message long, une partie a pu être remise : évitez de renvoyer
automatiquement en boucle.
Comment ça marche
Pas de passerelle SMS tierce : les messages partent d'une carte SIM installée dans un boîtier Oktopod équipé d'un modem 4G.
- Votre applicationenvoie une requête HTTPS avec sa clé
- Proxy sécuriséchiffrement TLS, filtrage des IP malveillantes
- Service SMScontrôle la clé, le numéro et les limites, encode le message
- Modem 4Gtransmet le SMS au réseau mobile, un à la fois
- Téléphonereçoit le message, recomposé s'il était long
Garde-fous
Sécurité
Une clé d'API par application, comparée sans fuite d'information. Le service n'est joignable qu'à travers le proxy, qui bloque automatiquement les adresses malveillantes. Les journaux ne contiennent ni le texte des messages ni le numéro complet.
Limites
60 SMS par heure toutes applications confondues, 6 SMS maximum par message, uniquement vers les mobiles français (06 et 07). Ces valeurs évitent qu'une application défaillante n'envoie des milliers de messages.
Ce que le service ne fait pas (encore)
- Recevoir des SMS ou des réponses.
- Confirmer la remise :
sentsignifie « accepté par l'opérateur », pas « lu ». - Programmer un envoi différé : appelez l'API au moment voulu.
Essayer
Testez avec votre clé. « Simuler » ne fait que calculer ; « Envoyer » envoie un vrai SMS.
La réponse de l'API s'affichera ici.