Call EngageLab OTP REST APIs to send one-time passwords (OTP), verify codes, send custom messages, and manage OTP templates across SMS, WhatsApp, Email, and Voice channels...
This skill enables interaction with the EngageLab OTP REST API. The OTP service handles one-time password generation, multi-channel delivery (SMS, WhatsApp, Email, Voice), verification, and fraud monitoring.
It covers six areas:
otp_client.py — Python client class (EngageLabOTP) wrapping all API endpoints: send_otp(), send_custom_otp(), verify(), send_custom_message(), and template CRUD. Handles authentication, request construction, and typed error handling. Use this as a ready-to-run helper or import it into the user's project.verify_callback.py — HMAC-SHA256 signature verifier for incoming OTP callback webhooks. Parses the X-CALLBACK-ID header and validates authenticity. Drop into any web framework (Flask, FastAPI, Django) to secure callback endpoints.error-codes.md — Complete error code tables for all OTP APIstemplate-api.md — Full template CRUD specs with all channel configurationscallback-config.md — Webhook setup, security, and all event typessmpp-guide.md — SMPP protocol connection, messaging, and delivery reportsAll EngageLab OTP API calls use HTTP Basic Authentication.
https://otp.api.engagelab.ccAuthorization: Basic <base64(dev_key:dev_secret)>application/jsonThe user must provide their dev_key and dev_secret. Encode them as base64("dev_key:dev_secret") and set the Authorization header.
Example (using curl):
curl -X POST https://otp.api.engagelab.cc/v1/messages \
-H "Content-Type: application/json" \
-H "Authorization: Basic $(echo -n 'YOUR_DEV_KEY:YOUR_DEV_SECRET' | base64)" \
-d '{ ... }'
If the user hasn't provided credentials, ask them for their dev_key and dev_secret before generating API calls.
| Operation | Method | Path |
|---|---|---|
| Send OTP (platform-generated) | POST |
/v1/messages |
| Send OTP (custom code) | POST |
/v1/codes |
| Verify OTP | POST |
/v1/verifications |
| Send custom message | POST |
/v1/custom-messages |
| List templates | GET |
/v1/template-configs |
| Get template details | GET |
/v1/template-configs/:templateId |
| Create template | POST |
/v1/template-configs |
| Delete template | DELETE |
/v1/template-configs/:templateId |
Use this when you want EngageLab to generate the verification code and deliver it according to the template's channel strategy (SMS, WhatsApp, Email, Voice).
Endpoint: POST /v1/messages
{
"to": "+6591234567",
"template": {
"id": "test-template-1",
"language": "default",
"params": {
"key1": "value1"
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
to |
string |
Yes | Phone number (with country code, e.g., +6581234567) or email address |
template.id |
string |
Yes | Template ID |
template.language |
string |
No | Language: default, zh_CN, zh_HK, en, ja, th, es. Defaults to default |
template.params |
object |
No | Custom template variable values as key-value pairs |
params{{brand_name}}, {{ttl}}, {{pwa_url}} are auto-filled from template settings — no need to pass them.Hi {{name}}, your code is {{code}}), pass values via params: {"name": "Bob"}.from_id field is preset and you pass {"from_id": "12345"}, the preset value is overridden.Success:
{
"message_id": "1725407449772531712",
"send_channel": "sms"
}
| Field | Type | Description |
|---|---|---|
message_id |
string |
Unique message ID, used for verification and tracking |
send_channel |
string |
Current delivery channel: whatsapp, sms, email, or voice |
The send_channel indicates the initial channel — if fallback is configured (e.g., WhatsApp → SMS), the final delivery channel may differ.
For error codes, read references/error-codes.md.
Use this when you want to generate the verification code yourself and have EngageLab deliver it. This API does not generate codes and does not require calling the Verify API afterward.
Endpoint: POST /v1/codes
{
"to": "+6591234567",
"code": "398210",
"template": {
"id": "test-template-1",
"language": "default",
"params": {
"key1": "value1"
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
to |
string |
Yes | Phone number or email address |
code |
string |
Yes | Your custom verification code |
template.id |
string |
Yes | Template ID |
template.language |
string |
No | Language (same options as OTP Send). Defaults to default |
template.params |
object |
No | Custom template variable values |
Same format as OTP Send — returns message_id and send_channel.
Validate a verification code that was sent via the OTP Send API (/v1/messages). Only applicable to platform-generated codes — not needed for Custom OTP Send.
Endpoint: POST /v1/verifications
{
"message_id": "1725407449772531712",
"verify_code": "667090"
}
| Field | Type | Required | Description |
|---|---|---|---|
message_id |
string |
Yes | The message_id returned by /v1/messages |
verify_code |
string |
Yes | The code the user entered |
Success:
{
"message_id": "1725407449772531712",
"verify_code": "667090",
"verified": true
}
| Field | Type | Description |
|---|---|---|
message_id |
string |
Message ID |
verify_code |
string |
The submitted code |
verified |
boolean |
true = valid, false = invalid |
Important: Successfully verified codes cannot be verified again — subsequent attempts will fail. Expired codes return error 3003.
Send custom template content (verification codes, notifications, or marketing messages) using templates created on the OTP platform.
Endpoint: POST /v1/custom-messages
{
"to": "+6591234567",
"template": {
"id": "test-template-1",
"params": {
"code": "123456",
"var1": "value1"
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
to |
string or string[] |
Yes | Single recipient (string) or multiple (array). Phone number or email |
template.id |
string |
Yes | Template ID |
template.params |
object |
No | Template variable values |
template.params.code |
string |
Conditional | Required if template type is verification code |
params{{brand_name}}, {{ttl}}, {{pwa_url}}) are auto-replaced from template settings.{{code}} or an error will occur.{"name": "Bob"} for Hi {{name}}.Same format as OTP Send — returns message_id and send_channel.
Verification code:
{
"to": "+6591234567",
"template": { "id": "code-template", "params": { "code": "123456" } }
}
Notification:
{
"to": ["+6591234567"],
"template": { "id": "notification-template", "params": { "order": "123456" } }
}
Marketing:
{
"to": ["+6591234567"],
"template": { "id": "marketing-template", "params": { "name": "EngageLab", "promotion": "30%" } }
}
OTP templates define the message content, channel strategy, and verification code settings. Templates support multi-channel delivery with fallback (e.g., WhatsApp → SMS).
For full request/response details including all channel configurations (WhatsApp, SMS, Voice, Email, PWA), read references/template-api.md.
Create — POST /v1/template-configs
{
"template_id": "my-template",
"description": "Login verification",
"send_channel_strategy": "whatsapp|sms",
"brand_name": "MyApp",
"verify_code_config": {
"verify_code_type": 1,
"verify_code_len": 6,
"verify_code_ttl": 5
},
"sms_config": {
"template_type": 1,
"template_default_config": {
"contain_security": false,
"contain_expire": false
}
}
}
List all — GET /v1/template-configs (returns array of templates without detailed content)
Get details — GET /v1/template-configs/:templateId (returns full template with channel configs)
Delete — DELETE /v1/template-configs/:templateId
| Value | Status |
|---|---|
| 1 | Pending Review |
| 2 | Approved |
| 3 | Rejected |
Use | to define fallback chains. Examples:
"sms" — SMS only"whatsapp|sms" — Try WhatsApp first, fall back to SMS"whatsapp|sms|email" — WhatsApp → SMS → EmailSupported channels: whatsapp, sms, voice, email
| Field | Range | Description |
|---|---|---|
verify_code_type |
1–7 | 1=Numeric, 2=Lowercase, 4=Uppercase. Combine: 3=Numeric+Lowercase |
verify_code_len |
4–10 | Code length |
verify_code_ttl |
1–10 | Validity in minutes. With WhatsApp: only 1, 5, or 10 |
Configure webhook URLs to receive real-time delivery status, notification events, message responses, and system events.
For the full callback data structures, security mechanisms, and event types, read references/callback-config.md.
For TCP-based SMPP protocol integration (used in carrier-level SMS delivery), read references/smpp-guide.md.
When the user asks to send OTPs or manage templates, generate working code. Default to curl unless the user specifies a language. Supported patterns:
requests libraryfetch or axiosHttpClientnet/httpAlways include the authentication header and proper error handling. Use placeholder values like YOUR_DEV_KEY and YOUR_DEV_SECRET if the user hasn't provided credentials.
import requests
import base64
DEV_KEY = "YOUR_DEV_KEY"
DEV_SECRET = "YOUR_DEV_SECRET"
BASE_URL = "https://otp.api.engagelab.cc"
auth_string = base64.b64encode(f"{DEV_KEY}:{DEV_SECRET}".encode()).decode()
headers = {
"Content-Type": "application/json",
"Authorization": f"Basic {auth_string}"
}
# Step 1: Send OTP
send_resp = requests.post(f"{BASE_URL}/v1/messages", headers=headers, json={
"to": "+6591234567",
"template": {"id": "my-template", "language": "default"}
})
result = send_resp.json()
message_id = result["message_id"]
# Step 2: Verify OTP (after user enters the code)
verify_resp = requests.post(f"{BASE_URL}/v1/verifications", headers=headers, json={
"message_id": message_id,
"verify_code": "123456"
})
verification = verify_resp.json()
print(f"Verified: {verification['verified']}")