aut2fa

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/send with the header Authorization: Bearer ak_live_….
Code
6 digits, generated by aut2fa. To use your own, send it in the code field.
Expiry
The code expires 10 minutes after the send is created.
Verification
POST /v1/send/{id}/verify with the code the user typed. After 5 wrong attempts the send is locked.
Delivery status
queued, sending, sent, delivered, read or failed, each with a timestamp, at GET /v1/send/{id}/status.
Message language
English or Brazilian Portuguese, set with locale: en or pt-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 always 000000.
Retries
Repeat a request with the same Idempotency-Key header 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

  1. Your backend calls POST /v1/send with the user's phone number in international format, such as +5531999999999. aut2fa answers 202 with the send id.

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

  3. Every status change is stored with its time. Read it at GET /v1/send/{id}/status or on the statement in the dashboard.

  4. When the user types the code, your backend calls POST /v1/send/{id}/verify. The response says whether the code is valid and how many attempts_left remain.

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.