SDKs
Python SDK
One client for every endpoint. Tokens, idempotency keys and error types are handled for you.
The ens_sdk package wraps the API in one client: OAuth tokens,
idempotency keys and clear errors are handled inside, so your code sends
notifications instead of HTTP requests.
Install
Terminalpip install ens_sdkConfigure
Credentials and tenant come from the environment, or from constructor arguments, which take precedence:
TerminalENS_SERVER_URL=https://nofy.encipher.co.tz ENS_CLIENT_ID=<oauth application client id> ENS_CLIENT_SECRET=<oauth application client secret> ENS_TENANT=<carrier tenant external id> ENS_TIMEOUT=10Pythonfrom ens_sdk import ENS ens = ENS() # reads the environment above # or: ENS(server_url=..., client_id=..., client_secret=..., tenant=...)Tokens are minted with client credentials and cached until they expire. Calls without configuration raise
ENSRefusedstraight away instead of failing obscurely later.Send
Pythonens.send_email("ops@acme.co.tz", "Shift closed", "Shift 7 closed.") ens.send_whatsapp_template("+255700000000", "otp_login", "en", ["482916"]) ens.send_sms("+255700000000", "Your code is 482916") ens.send_push("user-uuid-1", "Shift closed", "Tap for the summary.")
Email and WhatsApp accept html and inline_images (email),
callback_url, event_type, reference and idempotency_key. These
default to sensible unique values when omitted, so plain calls are already
retry-safe. Push needs a tenant and addresses your user ids, so register
devices first.
send_sms uses the legacy path
send_sms posts to /v1/notification/send/, which sends exactly like
the carrier channel but skips idempotency keys, and attributes quotas
to a tenant only when you pass tenant=. New SMS integrations that need
those guarantees should call POST /v2/messages directly (see
Sending on v2). The Quickstart shows the
same send in Node.js, PHP, Go, Rust and cURL.
Devices & tenants
ens.register_device("user-uuid-1", "fcm-device-token", platform="android")
ens.deregister_device(external_user_id="user-uuid-1") # logout: whole fleet
ens.provision_tenant("company-uuid-1", name="Acme Fuel") # idempotent
Errors
| Exception | Meaning |
|---|---|
ENSRefused |
Not configured, missing tenant for the call, or the service answered 400. |
ENSQuotaExceeded |
Daily quota reached (429). Back off until tomorrow. |
ENSUnreachable |
Network fault or unexpected status. Safe to retry. |
All three subclass ENSError, so one except ENSError covers the client.