Authevo documentation
Verify your users on WhatsApp in two API calls, or with any authenticator app via TOTP. Raw REST endpoints for both methods — no SDK required (an official Node.js/TypeScript SDK is also available).
Introduction
Authevo is a WhatsApp OTP + TOTP verification API for Egypt and the wider MENA region. Send a one-time code to a phone number over WhatsApp and verify what your user typed back, or enroll a phone for TOTP two-factor and verify codes from any authenticator app — two independent methods, one account.
Every request is a plain HTTPS call against a single base URL. Responses come back as JSON, wrapped in a predictable envelope, so the same two calls work in any language your backend already speaks.
https://api.authevo.devThe two-call model
POST /v1/otp/send- Send a one-time code to a phone number.
POST /v1/otp/verify- Check the code the user entered.
Codes are delivered over WhatsApp, with Telegram as a fallback if WhatsApp can't be reached. Link each recipient's Telegram once — a one-tap step, ideally right after they sign up — and every fallback after that is automatic; your integration code never changes.
Quickstart
Integrate the two-call flow in a couple of minutes. WhatsApp sending activates once your Meta Business Verification clears; link Telegram once per recipient (see below) and it covers you in the meantime.
Get an API key
Create an account and copy your secret key from the dashboard. Secret keys are prefixed with sk_ and authenticate every request. Your first 50 verifications are free — after that, a $2 minimum balance is required before you can send.
Get your API keySend and verify a code
Call the send endpoint with a phone number, then the verify endpoint with the code your user received. Pick your stack:
# 1. Send a one-time code over WhatsApp
curl -X POST https://api.authevo.dev/v1/otp/send \
-H "Authorization: Bearer sk_…" \
-H "Content-Type: application/json" \
-d '{ "phone": "+201234567890" }'
# 2. Verify the code your user entered
curl -X POST https://api.authevo.dev/v1/otp/verify \
-H "Authorization: Bearer sk_…" \
-H "Content-Type: application/json" \
-d '{ "phone": "+201234567890", "code": "123456" }'Authentication
Authevo uses bearer authentication. Pass your secret key in the Authorization header on every request.
Authorization: Bearer sk_…There are no other auth schemes — no OAuth, no sessions, no logins. A valid secret key is all a request needs.
Keep your secret key on the server
API reference
Two endpoints for the core flow — send and verify — plus one optional endpoint to pre-link Telegram. All POST, all JSON, all authenticated.
Send OTP
/v1/otp/sendGenerates a one-time code and delivers it to the phone number over WhatsApp. The code expires after the number of seconds returned in expires_in.
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Required | Recipient phone number in E.164 format, including the country code. |
curl -X POST https://api.authevo.dev/v1/otp/send \
-H "Authorization: Bearer sk_…" \
-H "Content-Type: application/json" \
-d '{ "phone": "+201234567890" }'{
"data": {
"message_id": "msg_9k2m4n8x",
"status": "sent",
"expires_in": 300
}
}A successful call returns the message identifier and a sent status.
Verify OTP
/v1/otp/verifyChecks the code your user entered against the one that was sent to their phone. Returns whether the code is valid.
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Required | The same phone number the code was sent to, in E.164 format. |
code | string | Required | The 6-digit code the user received over WhatsApp. |
curl -X POST https://api.authevo.dev/v1/otp/verify \
-H "Authorization: Bearer sk_…" \
-d '{ "phone": "+201234567890", "code": "123456" }'{ "data": { "verified": true } }When the code matches and is still valid, verified is true. Otherwise the request fails with an error envelope.
Link Telegram (optional)
/v1/otp/telegram-linkGenerates a one-tap Telegram link for a phone number, so Telegram fallback works from a recipient's very first code — not just after WhatsApp has already failed once. Call it right after the recipient signs up in your product, then send them the link once (email, SMS, in-app). The link expires in 15 minutes and can only be used once — calling this again for the same phone is safe and just issues a fresh one.
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Required | The recipient's phone number in E.164 format, including the country code. |
curl -X POST https://api.authevo.dev/v1/otp/telegram-link \
-H "Authorization: Bearer sk_…" \
-H "Content-Type: application/json" \
-d '{ "phone": "+201234567890" }'{
"data": {
"telegram_bot_url": "https://t.me/authevo_otp_bot?start=aBc123XyZ...",
"expires_in": 900
}
}A successful call returns the one-tap Telegram link and how many seconds it stays valid.
Two-Factor (TOTP)
A second, independent verification method — any authenticator app (Google Authenticator, Authy, 1Password), no message ever sent, just $0.002 per verification. Enroll once, then verify a rotating 6-digit code forever after.
Enroll
/v1/totp/enrollIssues a shared secret for a phone number and returns a ready-to-display QR code alongside the raw otpauth:// URL and secret — show the QR to your user, or let them type the secret in manually.
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Required | The phone number to enroll, in E.164 format. |
replace | boolean | Optional | Pass true to replace an existing confirmed enrollment (e.g. the user lost their device). A confirmed enrollment already in place returns a 409 rather than silently overwriting it. |
curl -X POST https://api.authevo.dev/v1/totp/enroll \
-H "Authorization: Bearer sk_…" \
-H "Content-Type: application/json" \
-d '{ "phone": "+201234567890" }'{
"data": {
"secret": "JBSWY3DPEHPK3PXP",
"otpauth_url": "otpauth://totp/Authevo:+201234567890?secret=JBSWY3DPEHPK3PXP&issuer=Authevo&algorithm=SHA1&digits=6&period=30",
"qr_code": "data:image/png;base64,iVBORw0KGgo...",
"already_enrolled": false
}
}qr_code is a ready-to-use PNG data URI — set it directly as an image source, no QR library needed on your end. already_enrolled is true only when a previous confirmed secret existed for this phone.
Verify
/v1/totp/verifyChecks a 6-digit code from the user's authenticator app against their enrolled secret.
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Required | The enrolled phone number, in E.164 format. |
code | string | Required | The 6-digit code currently shown in the user's authenticator app. |
curl -X POST https://api.authevo.dev/v1/totp/verify \
-H "Authorization: Bearer sk_…" \
-H "Content-Type: application/json" \
-d '{ "phone": "+201234567890", "code": "123456" }'{
"data": {
"verified": true,
"first_confirm": true
}
}first_confirm is true only on the exact call that confirms a brand-new enrollment — a good moment to show a one-time "you're all set" message.
Disable
/v1/totp/disableTurns off TOTP for a phone number. Safe to call more than once — disabling an already-disabled (or never-enrolled) phone still returns disabled: true.
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Required | The phone number to disable, in E.164 format. |
curl -X POST https://api.authevo.dev/v1/totp/disable \
-H "Authorization: Bearer sk_…" \
-H "Content-Type: application/json" \
-d '{ "phone": "+201234567890" }'{
"data": {
"disabled": true
}
}Re-enrolling the same phone afterward does not require replace: true — a disabled enrollment is treated as a fresh start.
Errors
Authevo uses standard HTTP status codes. Successful responses are wrapped in a data object; failures return an error object with a machine-readable code and a human-readable message.
{
"error": {
"code": "VALIDATION_ERROR",
"message": "body/phone must match pattern \"^\\+[1-9]\\d{6,14}$\""
}
}| Status | Code | Meaning |
|---|---|---|
400 | VALIDATION_ERROR | The request body was malformed, missing a required field, or the phone number isn't a valid E.164 number. |
401 | INVALID_API_KEY | The Authorization header is missing or the secret key is invalid. |
402 | INSUFFICIENT_CREDITS | Your account balance is below the amount required to send — add prepaid credit to continue (a $2 minimum balance applies). |
429 | RATE_LIMIT_EXCEEDED | Too many requests. Slow down and retry after a short delay. |
503 | TELEGRAM_UNAVAILABLE | Telegram fallback isn't available right now. |
Rate limits
Requests are rate limited per account. When you exceed the limit, the API responds with 429 RATE_LIMIT_EXCEEDED — back off and retry after a short delay.
Safety Floor