engagelab-otp · Python
Official Python SDK for EngageLab OTP.
Zero dependencies. Python 3.8+.
Install
pip install engagelab-otp
Quick start
import os
from engagelab_otp import OTPClient
otp = OTPClient(
os.environ["ENGAGELAB_DEV_KEY"],
os.environ["ENGAGELAB_DEV_SECRET"],
)
# Platform-generated OTP — easiest path
result = otp.send("+6591234567", "your-template-id", {"name": "Alice"}, language="en")
check = otp.verify(result["message_id"], user_typed_code)
if check["verified"]:
...
Two send modes
| Mode | Method | When to use |
|---|---|---|
| Platform-generated | otp.send() |
EngageLab generates and stores the code. You only call verify() later. |
| Caller-generated | otp.send_custom() |
You generate the code yourself. EngageLab is just the carrier. |
# Platform-generated
r = otp.send("+6591234567", "tpl-id", {"name": "Alice"}, language="en")
v = otp.verify(r["message_id"], "123456")
# Caller-generated
otp.send_custom("+6591234567", "custom-tpl", {"code": "482910", "name": "Alice"})
Webhook callbacks
EngageLab signs callbacks with X-CALLBACK-ID (HMAC-SHA256). The SDK verifies signatures and parses events for you.
Whitelist source IPs in your firewall:
119.8.170.74,114.119.180.30
from flask import Flask
from engagelab_otp import WebhookVerifier, MessageStatusEvent
app = Flask(__name__)
verifier = WebhookVerifier(
username=os.environ["ENGAGELAB_WEBHOOK_USERNAME"],
secret=os.environ["ENGAGELAB_WEBHOOK_SECRET"],
)
def handle(events):
for e in events:
if not isinstance(e, MessageStatusEvent):
continue
if not e.is_terminal:
continue # mid-flight, wait
if e.status == "delivered":
mark_delivered(e.message_id)
elif e.status == "verified":
mark_verified(e.message_id)
app.add_url_rule(
"/webhook",
"engagelab_webhook",
verifier.flask_view(handle),
methods=["POST"],
)
Event types
parse_events() returns instances of four dataclasses:
| Class | When | Key fields |
|---|---|---|
MessageStatusEvent |
per-message lifecycle | message_id, status, is_terminal, current_send_channel, error_code |
NotificationEvent |
account-level alert | event, data |
UplinkEvent |
inbound user reply | data["from"], data["body"] |
SystemEvent |
console action audit | event, data |
Message status enum
plan · target_valid · target_invalid
sent · sent_failed
delivered · delivered_failed
verified · verified_failed · verified_timeout
is_terminal == True for: delivered, delivered_failed, sent_failed, verified*, target_invalid.
Error handling
from engagelab_otp import EngagelabError
try:
otp.send("+6591234567", "tpl", {})
except EngagelabError as e:
if e.retryable:
# HTTP 429/5xx, or API codes 1000/5001/5016
# → exponential backoff
...
else:
# Permanent failure — fix call or notify user
print(e.code, e.http_status, str(e))
Examples
See examples/ for runnable code:
01_send_and_verify.py— platform-generated OTP, full flow02_send_custom.py— caller-generated code, single + bulk03_webhook_flask.py— receive callbacks via Flask04_error_handling.py— retry strategy and error categorization
Run tests
python tests/test_sdk.py
License
MIT
Metadata
Release files for engagelab-otp 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| engagelab_otp-1.0.1.tar.gz | 8.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| engagelab_otp-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 15.1 kB
Release files / engagelab_otp-1.0.1.tar.gz
| Download URL | engagelab_otp-1.0.1.tar.gz |
|---|---|
| Size | 8.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
df467aca6ca2e31fe0ec1786c43257915474510527f25ab94a5db43735119503
|
|
BLAKE2b-256 checksum How to use checksums |
c88358dfb602ae894c2e30a1056a937fb57f7da8521d3c4da56c9661045ac5dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|
Release files / engagelab_otp-1.0.1-py3-none-any.whl
| Download URL | engagelab_otp-1.0.1-py3-none-any.whl |
|---|---|
| Size | 6.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f33c57ed7fd775bf4c18cbe1c3b76932ed2bc37bf520d2bba5d2f3a8154beb54
|
|
BLAKE2b-256 checksum How to use checksums |
241471cf9983ceac389ba217462d9ac159411dfaec573f00c22cc0573a33ed49
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|