WhatsApp OTP API
aut2fa is an API that sends one-time verification codes (OTP, 2FA) over WhatsApp. Your backend sends a phone number to POST /v1/send; aut2fa generates a 6-digit code, delivers it from one of its WhatsApp numbers and reports when it was sent, delivered and read. You pay the WhatsApp price per code only when the code is delivered.
Updated on
Key facts
- Endpoint
POST https://api.aut2fa.com/v1/sendwith the headerAuthorization: Bearer ak_live_….- Code
- 6 digits, generated by aut2fa. To use your own, send it in the
codefield. - Expiry
- The code expires 10 minutes after the send is created.
- Verification
POST /v1/send/{id}/verifywith the code the user typed. After 5 wrong attempts the send is locked.- Delivery status
queued,sending,sent,delivered,readorfailed, each with a timestamp, atGET /v1/send/{id}/status.- Message language
- English or Brazilian Portuguese, set with
locale:enorpt-BR. - Price
- The WhatsApp price per code, charged only when the code is delivered. See the pricing page for the current price.
- Test mode
- Keys that start with
ak_test_are free, and the code aut2fa generates for a test send is always000000. - Retries
- Repeat a request with the same
Idempotency-Keyheader and you get the original send, not a second code. - Abuse limits
- Every account has a ceiling of sends per minute, and each application can add caps per minute and per phone number per hour. A request over a cap gets HTTP 429 with
Retry-After, before anything is sent. - Code storage
- The code is kept encrypted until the message is sent; after that only a hash remains.
How a WhatsApp code is delivered
Your backend calls
POST /v1/sendwith the user's phone number in international format, such as+5531999999999. aut2fa answers202with the sendid.aut2fa picks one of its WhatsApp numbers and sends the message with the code. If that number fails, it tries another, up to 3 attempts.
Every status change is stored with its time. Read it at
GET /v1/send/{id}/statusor on the statement in the dashboard.When the user types the code, your backend calls
POST /v1/send/{id}/verify. The response says whether the code isvalidand how manyattempts_leftremain.
Send and verify with cURL
Two requests: one sends the code, the other checks what the user typed.
curl https://api.aut2fa.com/v1/send \
-H "Authorization: Bearer ak_live_…" \
-H "Content-Type: application/json" \
-d '{"to": "+5531999999999"}'
# The user typed 482913
curl https://api.aut2fa.com/v1/send/snd_8Kq2wR7tXz/verify \
-H "Authorization: Bearer ak_live_…" \
-H "Content-Type: application/json" \
-d '{"code": "482913"}'Send response
POST /v1/send answers 202 Accepted. channel and from stay null until aut2fa routes the send.
{
"id": "snd_8Kq2wR7tXz",
"status": "queued",
"verification": "pending",
"mode": "live",
"channel": null,
"from": null,
"expires_at": "2026-10-11T18:10:00Z",
"created_at": "2026-10-11T18:00:00Z",
"sent_at": null,
"delivered_at": null,
"read_at": null,
"verified_at": null,
"failed_at": null,
"failure_reason": null
}What aut2fa doesn't do
- Let you pick the channel or the sending number. aut2fa chooses both, and the send status shows which it used.
- Bill after the fact. The balance is prepaid; there is no subscription or post-paid invoice.
- Charge in other currencies. Balance and prices are in Brazilian reais (BRL).
WhatsApp OTP questions
What if the phone number has no WhatsApp?
aut2fa can't deliver the code, so the send ends as failed and costs nothing.
How long is the code valid?
10 minutes from the moment you create the send. After that, /verify answers with verification set to expired.
What happens after 5 wrong codes?
The send is locked: verification becomes locked and no further code is accepted. Create a new send to try again.
Can I send my own code?
Yes. Put it in the code field of POST /v1/send; otherwise aut2fa generates a 6-digit code.
Can I test for free?
Yes. Keys that start with ak_test_ are free and the code aut2fa generates for a test send is always 000000, so automated tests run the whole flow without touching your balance.