{"skill":{"slug":"engagelab-otp","displayName":"EngageLab OTP","summary":"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...","description":"---\nname: engagelab-otp\ndescription: >\n  Call EngageLab OTP REST APIs to send one-time passwords (OTP), verify codes,\n  send custom messages, and manage OTP templates across SMS, WhatsApp, Email,\n  and Voice channels. Use this skill whenever the user wants to send an OTP or\n  verification code via EngageLab, verify an OTP code, send custom messages\n  through the OTP platform, manage OTP templates, configure callback webhooks,\n  or integrate via SMPP. Also trigger when the user mentions \"engagelab otp\",\n  \"otp api\", \"send otp\", \"verify otp\", \"one-time password\", \"verification code\",\n  \"engagelab verification\", \"otp template\", \"multi-channel otp\", \"whatsapp otp\",\n  \"sms otp\", \"voice otp\", \"email otp\", or asks to integrate with the EngageLab\n  OTP platform. This skill covers OTP generation, delivery, verification,\n  custom messaging, template management, callback configuration, and SMPP\n  integration — use it even if the user only needs one of these capabilities.\n---\n\n# EngageLab OTP API Skill\n\nThis 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.\n\nIt covers six areas:\n\n1. **OTP Send** — Platform-generated OTP code delivery\n2. **Custom OTP Send** — User-generated OTP code delivery\n3. **OTP Verify** — Validate OTP codes\n4. **Custom Messages Send** — Send custom template messages (notifications, marketing)\n5. **Template Management** — Create, list, get, and delete OTP templates\n6. **Callback & SMPP** — Webhook configuration and SMPP protocol integration\n\n## Resources\n\n### scripts/\n\n- **`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.\n- **`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.\n\n### references/\n\n- **`error-codes.md`** — Complete error code tables for all OTP APIs\n- **`template-api.md`** — Full template CRUD specs with all channel configurations\n- **`callback-config.md`** — Webhook setup, security, and all event types\n- **`smpp-guide.md`** — SMPP protocol connection, messaging, and delivery reports\n\n## Authentication\n\nAll EngageLab OTP API calls use **HTTP Basic Authentication**.\n\n- **Base URL**: `https://otp.api.engagelab.cc`\n- **Header**: `Authorization: Basic <base64(dev_key:dev_secret)>`\n- **Content-Type**: `application/json`\n\nThe user must provide their `dev_key` and `dev_secret`. Encode them as `base64(\"dev_key:dev_secret\")` and set the `Authorization` header.\n\n**Example** (using curl):\n\n```bash\ncurl -X POST https://otp.api.engagelab.cc/v1/messages \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Authorization: Basic $(echo -n 'YOUR_DEV_KEY:YOUR_DEV_SECRET' | base64)\" \\\n  -d '{ ... }'\n```\n\nIf the user hasn't provided credentials, ask them for their `dev_key` and `dev_secret` before generating API calls.\n\n## Quick Reference — All Endpoints\n\n| Operation | Method | Path |\n|-----------|--------|------|\n| Send OTP (platform-generated) | `POST` | `/v1/messages` |\n| Send OTP (custom code) | `POST` | `/v1/codes` |\n| Verify OTP | `POST` | `/v1/verifications` |\n| Send custom message | `POST` | `/v1/custom-messages` |\n| List templates | `GET` | `/v1/template-configs` |\n| Get template details | `GET` | `/v1/template-configs/:templateId` |\n| Create template | `POST` | `/v1/template-configs` |\n| Delete template | `DELETE` | `/v1/template-configs/:templateId` |\n\n## OTP Send (Platform-Generated Code)\n\nUse this when you want **EngageLab to generate** the verification code and deliver it according to the template's channel strategy (SMS, WhatsApp, Email, Voice).\n\n**Endpoint**: `POST /v1/messages`\n\n### Request Body\n\n```json\n{\n  \"to\": \"+6591234567\",\n  \"template\": {\n    \"id\": \"test-template-1\",\n    \"language\": \"default\",\n    \"params\": {\n      \"key1\": \"value1\"\n    }\n  }\n}\n```\n\n### Parameters\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `to` | `string` | Yes | Phone number (with country code, e.g., `+6581234567`) or email address |\n| `template.id` | `string` | Yes | Template ID |\n| `template.language` | `string` | No | Language: `default`, `zh_CN`, `zh_HK`, `en`, `ja`, `th`, `es`. Defaults to `default` |\n| `template.params` | `object` | No | Custom template variable values as key-value pairs |\n\n### Notes on `params`\n\n- Preset variables like `{{brand_name}}`, `{{ttl}}`, `{{pwa_url}}` are auto-filled from template settings — no need to pass them.\n- For custom variables in the template (e.g., `Hi {{name}}, your code is {{code}}`), pass values via params: `{\"name\": \"Bob\"}`.\n- If the template's `from_id` field is preset and you pass `{\"from_id\": \"12345\"}`, the preset value is overridden.\n\n### Response\n\n**Success**:\n\n```json\n{\n  \"message_id\": \"1725407449772531712\",\n  \"send_channel\": \"sms\"\n}\n```\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `message_id` | `string` | Unique message ID, used for verification and tracking |\n| `send_channel` | `string` | Current delivery channel: `whatsapp`, `sms`, `email`, or `voice` |\n\nThe `send_channel` indicates the initial channel — if fallback is configured (e.g., WhatsApp → SMS), the final delivery channel may differ.\n\nFor error codes, read `references/error-codes.md`.\n\n## Custom OTP Send (User-Generated Code)\n\nUse 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.\n\n**Endpoint**: `POST /v1/codes`\n\n### Request Body\n\n```json\n{\n  \"to\": \"+6591234567\",\n  \"code\": \"398210\",\n  \"template\": {\n    \"id\": \"test-template-1\",\n    \"language\": \"default\",\n    \"params\": {\n      \"key1\": \"value1\"\n    }\n  }\n}\n```\n\n### Parameters\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `to` | `string` | Yes | Phone number or email address |\n| `code` | `string` | Yes | Your custom verification code |\n| `template.id` | `string` | Yes | Template ID |\n| `template.language` | `string` | No | Language (same options as OTP Send). Defaults to `default` |\n| `template.params` | `object` | No | Custom template variable values |\n\n### Response\n\nSame format as OTP Send — returns `message_id` and `send_channel`.\n\n## OTP Verify\n\nValidate 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.\n\n**Endpoint**: `POST /v1/verifications`\n\n### Request Body\n\n```json\n{\n  \"message_id\": \"1725407449772531712\",\n  \"verify_code\": \"667090\"\n}\n```\n\n### Parameters\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `message_id` | `string` | Yes | The `message_id` returned by `/v1/messages` |\n| `verify_code` | `string` | Yes | The code the user entered |\n\n### Response\n\n**Success**:\n\n```json\n{\n  \"message_id\": \"1725407449772531712\",\n  \"verify_code\": \"667090\",\n  \"verified\": true\n}\n```\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `message_id` | `string` | Message ID |\n| `verify_code` | `string` | The submitted code |\n| `verified` | `boolean` | `true` = valid, `false` = invalid |\n\n**Important**: Successfully verified codes cannot be verified again — subsequent attempts will fail. Expired codes return error `3003`.\n\n## Custom Messages Send\n\nSend custom template content (verification codes, notifications, or marketing messages) using templates created on the OTP platform.\n\n**Endpoint**: `POST /v1/custom-messages`\n\n### Request Body\n\n```json\n{\n  \"to\": \"+6591234567\",\n  \"template\": {\n    \"id\": \"test-template-1\",\n    \"params\": {\n      \"code\": \"123456\",\n      \"var1\": \"value1\"\n    }\n  }\n}\n```\n\n### Parameters\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `to` | `string` or `string[]` | Yes | Single recipient (string) or multiple (array). Phone number or email |\n| `template.id` | `string` | Yes | Template ID |\n| `template.params` | `object` | No | Template variable values |\n| `template.params.code` | `string` | Conditional | Required if template type is verification code |\n\n### Notes on `params`\n\n- Preset variables (`{{brand_name}}`, `{{ttl}}`, `{{pwa_url}}`) are auto-replaced from template settings.\n- For verification code templates, you **must** pass `{{code}}` or an error will occur.\n- Custom variables need values via params, e.g., `{\"name\": \"Bob\"}` for `Hi {{name}}`.\n\n### Response\n\nSame format as OTP Send — returns `message_id` and `send_channel`.\n\n### Use Case Examples\n\n**Verification code**:\n```json\n{\n  \"to\": \"+6591234567\",\n  \"template\": { \"id\": \"code-template\", \"params\": { \"code\": \"123456\" } }\n}\n```\n\n**Notification**:\n```json\n{\n  \"to\": [\"+6591234567\"],\n  \"template\": { \"id\": \"notification-template\", \"params\": { \"order\": \"123456\" } }\n}\n```\n\n**Marketing**:\n```json\n{\n  \"to\": [\"+6591234567\"],\n  \"template\": { \"id\": \"marketing-template\", \"params\": { \"name\": \"EngageLab\", \"promotion\": \"30%\" } }\n}\n```\n\n## Template Management\n\nOTP templates define the message content, channel strategy, and verification code settings. Templates support multi-channel delivery with fallback (e.g., WhatsApp → SMS).\n\nFor full request/response details including all channel configurations (WhatsApp, SMS, Voice, Email, PWA), read `references/template-api.md`.\n\n### Quick Summary\n\n**Create** — `POST /v1/template-configs`\n\n```json\n{\n  \"template_id\": \"my-template\",\n  \"description\": \"Login verification\",\n  \"send_channel_strategy\": \"whatsapp|sms\",\n  \"brand_name\": \"MyApp\",\n  \"verify_code_config\": {\n    \"verify_code_type\": 1,\n    \"verify_code_len\": 6,\n    \"verify_code_ttl\": 5\n  },\n  \"sms_config\": {\n    \"template_type\": 1,\n    \"template_default_config\": {\n      \"contain_security\": false,\n      \"contain_expire\": false\n    }\n  }\n}\n```\n\n**List all** — `GET /v1/template-configs` (returns array of templates without detailed content)\n\n**Get details** — `GET /v1/template-configs/:templateId` (returns full template with channel configs)\n\n**Delete** — `DELETE /v1/template-configs/:templateId`\n\n### Template Status\n\n| Value | Status |\n|-------|--------|\n| 1 | Pending Review |\n| 2 | Approved |\n| 3 | Rejected |\n\n### Channel Strategy\n\nUse `|` to define fallback chains. Examples:\n- `\"sms\"` — SMS only\n- `\"whatsapp|sms\"` — Try WhatsApp first, fall back to SMS\n- `\"whatsapp|sms|email\"` — WhatsApp → SMS → Email\n\nSupported channels: `whatsapp`, `sms`, `voice`, `email`\n\n### Verification Code Config\n\n| Field | Range | Description |\n|-------|-------|-------------|\n| `verify_code_type` | 1–7 | 1=Numeric, 2=Lowercase, 4=Uppercase. Combine: 3=Numeric+Lowercase |\n| `verify_code_len` | 4–10 | Code length |\n| `verify_code_ttl` | 1–10 | Validity in minutes. With WhatsApp: only 1, 5, or 10 |\n\n## Callback Configuration\n\nConfigure webhook URLs to receive real-time delivery status, notification events, message responses, and system events.\n\nFor the full callback data structures, security mechanisms, and event types, read `references/callback-config.md`.\n\n## SMPP Integration\n\nFor TCP-based SMPP protocol integration (used in carrier-level SMS delivery), read `references/smpp-guide.md`.\n\n## Generating Code\n\nWhen the user asks to send OTPs or manage templates, generate working code. Default to `curl` unless the user specifies a language. Supported patterns:\n\n- **curl** — Shell commands with proper auth header\n- **Python** — Using `requests` library\n- **Node.js** — Using `fetch` or `axios`\n- **Java** — Using `HttpClient`\n- **Go** — Using `net/http`\n\nAlways 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.\n\n### Python Example — Send OTP and Verify\n\n```python\nimport requests\nimport base64\n\nDEV_KEY = \"YOUR_DEV_KEY\"\nDEV_SECRET = \"YOUR_DEV_SECRET\"\nBASE_URL = \"https://otp.api.engagelab.cc\"\n\nauth_string = base64.b64encode(f\"{DEV_KEY}:{DEV_SECRET}\".encode()).decode()\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"Authorization\": f\"Basic {auth_string}\"\n}\n\n# Step 1: Send OTP\nsend_resp = requests.post(f\"{BASE_URL}/v1/messages\", headers=headers, json={\n    \"to\": \"+6591234567\",\n    \"template\": {\"id\": \"my-template\", \"language\": \"default\"}\n})\nresult = send_resp.json()\nmessage_id = result[\"message_id\"]\n\n# Step 2: Verify OTP (after user enters the code)\nverify_resp = requests.post(f\"{BASE_URL}/v1/verifications\", headers=headers, json={\n    \"message_id\": message_id,\n    \"verify_code\": \"123456\"\n})\nverification = verify_resp.json()\nprint(f\"Verified: {verification['verified']}\")\n```\n","tags":{"latest":"1.0.1"},"stats":{"comments":0,"downloads":648,"installsAllTime":24,"installsCurrent":0,"stars":0,"versions":2},"createdAt":1773196563372,"updatedAt":1778491820342},"latestVersion":{"version":"1.0.1","createdAt":1774592507395,"changelog":"No functional changes in this release.\n\n- Version updated to 1.0.1 with no file modifications.\n- No new features, bug fixes, or documentation updates detected.","license":"MIT-0"},"metadata":null,"owner":{"handle":"devengagelab","userId":"s17145xn9q0rxevzd3kmwce18s83pakw","displayName":"DevEngageLab","image":"https://avatars.githubusercontent.com/u/113164142?v=4"},"moderation":null}