Skip to content

API reference

Two endpoints for the core flow — send and verify — plus one optional endpoint to pre-link Telegram, and TOTP's own enroll/verify/disable trio. All POST, all JSON, all authenticated.

Browse the full schema reference — every endpoint →

Send OTP

POST/v1/otp/send

Generates 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.

ParameterTypeRequiredDescription
phonestringRequiredRecipient phone number in E.164 format, including the country code.
Request
cURL
curl -X POST https://api.authevo.dev/v1/otp/send \
  -H "Authorization: Bearer sk_…" \
  -H "Content-Type: application/json" \
  -d '{ "phone": "+201234567890" }'
Response
200 OK
{
  "data": {
    "message_id": "msg_9k2m4n8x",
    "status": "sent",
    "expires_in": 300
  }
}

A successful call returns the message identifier and a sent status.

Verify OTP

POST/v1/otp/verify

Checks the code your user entered against the one that was sent to their phone. Returns whether the code is valid.

ParameterTypeRequiredDescription
phonestringRequiredThe same phone number the code was sent to, in E.164 format.
codestringRequiredThe 6-digit code the user received over WhatsApp.
Request
cURL
curl -X POST https://api.authevo.dev/v1/otp/verify \
  -H "Authorization: Bearer sk_…" \
  -d '{ "phone": "+201234567890", "code": "123456" }'
Response
200 OK
{ "data": { "verified": true } }

When the code matches and is still valid, verified is true. Otherwise the request fails with an error envelope.

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.

In sandbox mode, enroll returns a fixed, public demo secret — add it to any authenticator app to get a genuinely valid, rotating test code. Unlike OTP's sandbox, TOTP test codes are NOT always 123456 — they rotate every 30 seconds like the real thing. Full sandbox details →

Enroll

POST/v1/totp/enroll

Issues 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.

ParameterTypeRequiredDescription
phonestringRequiredThe phone number to enroll, in E.164 format.
replacebooleanOptionalPass 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.
Request
cURL
curl -X POST https://api.authevo.dev/v1/totp/enroll \
  -H "Authorization: Bearer sk_…" \
  -H "Content-Type: application/json" \
  -d '{ "phone": "+201234567890" }'
Response
200 OK
{
  "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

POST/v1/totp/verify

Checks a 6-digit code from the user's authenticator app against their enrolled secret.

ParameterTypeRequiredDescription
phonestringRequiredThe enrolled phone number, in E.164 format.
codestringRequiredThe 6-digit code currently shown in the user's authenticator app.
Request
cURL
curl -X POST https://api.authevo.dev/v1/totp/verify \
  -H "Authorization: Bearer sk_…" \
  -H "Content-Type: application/json" \
  -d '{ "phone": "+201234567890", "code": "123456" }'
Response
200 OK
{
  "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

POST/v1/totp/disable

Turns off TOTP for a phone number. Safe to call more than once — disabling an already-disabled (or never-enrolled) phone still returns disabled: true.

ParameterTypeRequiredDescription
phonestringRequiredThe phone number to disable, in E.164 format.
Request
cURL
curl -X POST https://api.authevo.dev/v1/totp/disable \
  -H "Authorization: Bearer sk_…" \
  -H "Content-Type: application/json" \
  -d '{ "phone": "+201234567890" }'
Response
200 OK
{
  "data": {
    "disabled": true
  }
}

Re-enrolling the same phone afterward does not require replace: true — a disabled enrollment is treated as a fresh start.