Python SDK

Send SMS, WhatsApp and OTP from Python with the official SDK

envoisms is EnvoiSMS.ma's official Python SDK. pip install envoisms, create an EnvoiSMSClient with your API key, and send SMS, WhatsApp messages and one-time codes from a script, a Django view or a FastAPI service.

send.py (SDK envoisms, Python)
# pip install envoisms import os from envoisms import EnvoiSMSClient, EnvoiSMSError client = EnvoiSMSClient(api_key=os.getenv("ENVOISMS_API_KEY"), max_retries=3, timeout=20) try: response = client.send( to="+212600000000", message="Votre commande #1042 est confirmée.", from_sender="MonBusiness", # Sender ID validé, ou omis ) # Idempotency-Key ajouté : un nouvel essai ne facture jamais deux fois print(f"Message ID: {response['id']}") except EnvoiSMSError as e: print(f"Échec ({e.status_code} {e.code}): {e}") # OTP géré : envoi puis vérification otp = client.send_otp(to="+212600000000", brand="MonBusiness", code_length=6, expiry=600) check = client.check_otp(session_id=otp["session_id"], code="492018") print(check.get("verified"))
● Routes locales MarocIAM • Inwi • Orange
https://api.envoisms.ma/v1
Local Routes
Maroc Telecom (IAM) • Inwi • Orange
Verified DLR Receipts
HMAC-SHA256 Signed
Clear MAD Pricing
dès 0,60 MAD/SMS • 5 MAD offerts

Install and send your first SMS

pip install envoisms, then client = EnvoiSMSClient(api_key=os.getenv("ENVOISMS_API_KEY")). client.send(to="+212600000000", message="…", from_sender="MyBusiness") returns the message id, which you poll with get_message() and match in your webhooks.

  • from envoisms import EnvoiSMSClient
  • from_sender: your validated Sender ID, or omit it for your default
  • send_bulk(messages=[...], from_sender=...) for a bulk send; list_messages(limit=50, offset=0) for recent sends

Retry-safe sends and errors

Every send() and send_bulk() carries an Idempotency-Key — generated, or pass idempotency_key= — so a retry after a timeout can never bill the same message twice. The client retries 5xx responses and network errors up to max_retries times (2 by default) with exponential backoff, then raises EnvoiSMSError with status_code and code attributes.

  • EnvoiSMSClient(api_key=..., max_retries=3, timeout=20)
  • except EnvoiSMSError as e: e.status_code, e.code

SMS or WhatsApp, and the cascade

Default to SMS: it reaches every Moroccan mobile with no setup beyond the API key. channel="whatsapp" sends from your own connected WhatsApp Business number — 403 WHATSAPP_NOT_CONNECTED without one, 400 OUT_OF_24H_WINDOW for free text outside the 24-hour customer window, nothing charged in either case. Outside the window, pass an approved template. cascade=True drops back to SMS when the number is unreachable or has no WhatsApp.

  • template={"name": "order_shipped", "language": "fr", "variables": ["89240"]}
  • Leave channel on "sms" for any ordinary text to a customer

OTP, webhooks and the account

client.send_otp(to=..., brand="MyBusiness", code_length=6, expiry=600) returns a session_id; client.check_otp(session_id=..., code=...) returns verified; get_otp_session() inspects a session without consuming an attempt. EnvoiSMSClient.verify_webhook_signature(raw_body=..., signature_header=..., secret=...) checks the X-EnvoiSMS-Signature header against the raw request body.

  • send_otp(..., channel="whatsapp"): a WhatsApp code through the shared sender, no connection needed
  • get_balance(), list_packs(), create_topup(amount_mad=200, payment_method="stripe")
  • analytics(days=30), create_api_key(), create_optout()

Everything you need to know about Python SDK.

Does it work with Django, Flask and FastAPI?
Yes. The client is a plain Python object: call it from a view, a task or a script. For webhooks, pass the raw request body (request.body in Django) to verify_webhook_signature() before trusting the payload.
How do I send a WhatsApp OTP code from Python?
client.send_otp(to=..., brand=..., channel="whatsapp"). The code goes through EnvoiSMS's shared sender: you don't need to connect your own WhatsApp number.
How do I test without sending real SMS?
Create the client with an env_test_ sandbox key: the whole sending path is replayed — validation, pricing, webhooks — without delivering or debiting anything.

Ready to integrate with Python SDK?

Create your account in under 2 minutes. Get 5 MAD of free credit instantly to test the API.