The SysSecure API is organized around REST. All requests must be made over HTTPS. The base URL for all API calls is:
https://api.syssecure.me/v2Send your first OTP in under 5 minutes. Install the SDK, grab your API key from the dashboard, and run the example below.
# Install the Python SDK pip install syssecure-sdk # Or via npm for Node.js npm install @syssecure/sdk
import syssecure # Initialize with your API key client = syssecure.Client(api_key="sk_live_your_key_here") # Send OTP via WhatsApp with SMS fallback otp = client.otp.send( to="+32470123456", channels=["whatsapp", "sms"], expires_in=300 ) # Verify the code entered by the user result = client.otp.verify(otp_id=otp.id, code="847291") print(result.valid) # True
All API requests require an API key passed in the Authorization header. Keys are prefixed with sk_live_ for production or sk_test_ for sandbox.
Authorization: Bearer sk_live_your_api_key_here Content-Type: application/json
Generates a secure one-time password and delivers it to the specified phone number. Supports automatic fallback across channels.
| Parameter | Type | Required | Description |
|---|---|---|---|
| to | string | Required | Phone number in E.164 format (e.g. +32470123456) |
| channels | array | Required | Ordered list of delivery channels: whatsapp, sms, telegram, voice |
| expires_in | integer | Optional | OTP validity in seconds (default: 300, max: 3600) |
| length | integer | Optional | OTP length (default: 6, range: 4–10) |
| template | string | Optional | Template ID for the OTP message body |
| locale | string | Optional | BCP 47 locale tag for message language (e.g. en, fr, es) |
| metadata | object | Optional | Arbitrary key-value pairs attached to the OTP for your own tracking |
{
"to": "+32470123456",
"channels": ["whatsapp", "sms"],
"expires_in": 300,
"length": 6,
"locale": "en",
"metadata": {
"user_id": "usr_abc123",
"action": "login"
}
}{
"otp_id": "otp_01HWXYZABC123DEF456",
"status": "sent",
"channel": "whatsapp",
"to": "+32470123456",
"expires_at": "2026-04-25T15:32:00Z",
"created_at": "2026-04-25T15:27:00Z"
}
Validates a code submitted by the user against the original OTP. Codes are single-use — once verified, the OTP is invalidated.
| Parameter | Type | Required | Description |
|---|---|---|---|
| otp_id | string | Required | The OTP ID returned by the Send OTP endpoint |
| code | string | Required | The code entered by the user |
{
"valid": true,
"otp_id": "otp_01HWXYZABC123DEF456",
"verified_at": "2026-04-25T15:28:14Z"
}
Send a standard or unicode SMS to any phone number in 195+ countries.
| Parameter | Type | Required | Description |
|---|---|---|---|
| to | string | Required | Recipient phone number in E.164 format |
| body | string | Required | Message content (max 1600 characters) |
| from | string | Optional | Sender ID (alphanumeric or phone number) |
| callback_url | string | Optional | Webhook URL to receive delivery status updates |
| scheduled_at | string | Optional | ISO 8601 datetime to schedule the message |
SysSecure sends HTTP POST requests to your configured URL whenever a message event occurs. All requests include an X-SysSecure-Signature header for verification.
| Event | Description |
|---|---|
| message.sent | Message has been submitted to the carrier |
| message.delivered | Delivery confirmed by carrier or device |
| message.failed | Delivery failed — includes failure reason code |
| message.read | Message read by recipient (WhatsApp/Telegram only) |
| otp.verified | OTP successfully verified by end user |
| otp.expired | OTP expired before verification |
| contact.opted_out | Recipient replied STOP or equivalent |
{
"event": "message.delivered",
"message_id": "msg_01HWXYZ789",
"channel": "sms",
"to": "+32470123456",
"status": "delivered",
"delivered_at": "2026-04-25T15:28:02Z",
"latency_ms": 1241
}SysSecure uses standard HTTP status codes. All error responses include a JSON body with a machine-readable code and human-readable message.
| HTTP code | Error code | Description |
|---|---|---|
| 400 | invalid_params | Missing or malformed request parameters |
| 401 | unauthorized | Missing or invalid API key |
| 402 | insufficient_credits | Account has insufficient credits |
| 404 | not_found | Resource not found |
| 422 | invalid_phone | Phone number is invalid or not reachable |
| 429 | rate_limit_exceeded | Too many requests — back off and retry |
| 500 | internal_error | Unexpected server error — retry with exponential backoff |