Retour
3 min de lecture1 novembre 2026
Tutoriels

Envoyer un SMS en Python en 5 minutes (exemple complet)

Envoyez votre premier SMS vers un numéro tunisien depuis Python avec l’API Sendimo et la librairie requests : clé de test, envoi, gestion des erreurs et suivi de livraison.

L’équipe SendimoPlateforme SMS en Tunisie

Ce tutoriel envoie un SMS vers un numéro tunisien depuis un script Python, avec la librairie requests et l’API REST Sendimo. Il fonctionne aussi dans une application Django, Flask ou FastAPI : il suffit de placer l’appel dans votre vue ou votre tâche de fond.

Ce qu’il vous faut

  • Python 3.9 ou plus récent ;
  • la librairie requests : pip install requests ;
  • une clé API Sendimo. Commencez par une clé de test sk_test_ : les réponses sont réalistes, mais rien n’est envoyé ni facturé.

Gardez la clé hors du code, dans une variable d’environnement :

export SENDIMO_API_KEY="sk_test_..."

1. Envoyer le SMS

Un envoi, c’est une requête POST /v1/messages avec le numéro au format international, le nom d’expéditeur et le texte.

import os
import requests

response = requests.post(
    "https://api.sendimo.tn/v1/messages",
    headers={
        "Authorization": f"Bearer {os.environ['SENDIMO_API_KEY']}",
        "Idempotency-Key": "order-4821-otp",
    },
    json={
        "to": "+21620123456",
        "from": "SENDIMO",
        "text": "Votre code est 482913. Il expire dans 5 minutes.",
        "reference": "order-4821",
    },
    timeout=10,
)
response.raise_for_status()  # 4xx/5xx -> exception

message = response.json()
print(message["id"], message["status"])  # msg_01HF8Z3K9QX2 queued

L’API répond 202 Accepted : le message est accepté et mis en file d’envoi.

{
  "id": "msg_01HF8Z3K9QX2",
  "status": "queued",
  "to": "+21620123456",
  "from": "SENDIMO",
  "encoding": "GSM-7",
  "segments": 1,
  "network": "ooredoo",
  "cost": { "amount": "0.140", "currency": "TND" },
  "reference": "order-4821"
}

Trois champs méritent votre attention :

  • to : toujours au format E.164, avec +216 ;
  • from : un nom d’expéditeur approuvé sur votre compte ;
  • Idempotency-Key : si votre script réessaie après une coupure réseau, la même clé garantit que le SMS ne part qu’une fois.

2. Tester sans rien envoyer

Avec une clé sk_test_, deux numéros simulent les deux issues possibles :

  • +21600000001 finit toujours en delivered ;
  • +21600000002 finit toujours en failed.

Vous pouvez ainsi tester tout votre parcours, y compris les erreurs, avant de passer à une clé sk_live_.

3. Gérer les erreurs

Toutes les erreurs ont le même format, avec un code stable :

try:
    response.raise_for_status()
except requests.HTTPError:
    error = response.json()["error"]
    if error["code"] == "insufficient_balance":
        print("Solde insuffisant : rechargez votre compte.")
    elif error["code"] == "invalid_phone_number":
        print("Numéro invalide :", error["message"])
    else:
        print(error["code"], error["request_id"])

Les codes les plus fréquents :

HTTP Code Cause
400 invalid_phone_number to n’est pas un numéro valide
401 unauthorized Clé API invalide, absente ou révoquée
402 insufficient_balance Solde insuffisant pour l’envoi
403 sender_not_approved from n’est pas un nom d’expéditeur approuvé
429 rate_limited Trop de requêtes ; attendez la durée de Retry-After

En cas d’erreur 500 ou 503, réessayez avec la même Idempotency-Key.

4. Suivre la livraison

Le statut passe de queued à sent, puis à delivered ou failed. Deux façons de le suivre :

  • interroger GET /v1/messages/{id} ;
  • mieux : recevoir l’événement message.delivered ou message.failed sur votre webhook, sans interroger l’API.

Combien ça coûte ?

Ce SMS fait 48 caractères en GSM-7 : un segment, facturé au tarif de votre offre, de 0,100 DT à 0,150 DT. Le détail est dans notre article sur le prix d’un SMS en Tunisie.

Pour aller plus loin

Prêt à envoyer vos SMS ?

Lancement bientôt en Tunisie. Rejoignez l’accès anticipé.