A clean, RESTful API for sending and verifying OTPs across WhatsApp, SMS, email, and voice — with SDKs for Node.js, Python, PHP, and Go.
No carrier agreements, no SMPP configuration, no WhatsApp Business setup. Just grab an API key and go.
Request access through the Narvark demo form and our team will provide the appropriate onboarding path and API access details.
POST to /v1/otp/send with a phone number and channel. OTP is dispatched in under 200ms.
When the user submits their code, POST to /v1/otp/verify. Get back a boolean valid in milliseconds.
All API requests must include your API key in the Authorization header as a Bearer token. API keys are scoped to environments (test / live).
Use nvk_test_sk_ keys for development — no OTPs are dispatched and no charges apply. Switch to nvk_live_sk_ for production.
Dispatch a one-time password to a phone number or email address via the specified channel. Returns an OTP ID for status tracking and verification.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| to | string | required | Recipient phone number in E.164 format (e.g. +447911123456) or email address. |
| channel | string | required | Delivery channel. One of: whatsapp, sms, email, voice. |
| ttl | integer | optional | Code expiry in seconds. Default: 300. Min: 60. Max: 86400. |
| fallback | string | optional | Fallback channel if primary fails. E.g. "sms" when primary is "whatsapp". |
| code_length | integer | optional | OTP code length. Default: 6. Options: 4, 6, 8. |
| template | string | optional | WhatsApp-only. Pre-approved message template name. Default: "otp_verification". |
| metadata | object | optional | Arbitrary key-value pairs attached to the OTP. Returned in webhooks and status responses. Max 10 keys. |
Response
Verify a code submitted by the user against the OTP identified by its ID. Returns whether the code is valid and whether it has been consumed.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | required | The OTP ID returned from the send endpoint. |
| code | string | required | The code submitted by the user. Accepts formatted (e.g. "492 817") or unformatted ("492817"). |
Narvark uses standard HTTP status codes. All error responses include a machine-readable error code and human-readable message.
| Code | Error | Description |
|---|---|---|
| 400 | invalid_request | Missing or malformed request parameters. |
| 401 | unauthorized | Invalid or missing API key. |
| 429 | rate_limited | Too many requests. Default: 1,000 req/min per key. Enterprise: unlimited. |
| 500 | internal_error | Narvark server error. Automatically retried internally — rare. |
Narvark sends real-time POST webhooks to your endpoint for OTP lifecycle events — dispatched, delivered, read, verified, expired, and failed.
Verify webhook authenticity using the X-Narvark-Signature header — an HMAC-SHA256 signature of the raw request body using your webhook secret.