OTP applies only to user sessions (JWT login).
pk_ API keys are
exempt: they are server-to-server integrations with no human holding a
phone on the other side. If your whole operation runs on API keys, this
page changes nothing in your integration.How it works
Theotp_token is single use, bound to your user and to the action it
was issued for, and expires with the challenge (10 minutes after the code
was sent).
1. Check your policy
GET /v1/otp/settings tells you whether OTP is active and which actions
require it:
2. Request the code
201 — the code is already on its way to the account’s phone:
409 phone_required (set it with
PATCH /v1/me). Hourly send limits apply — exceeding them returns
429 too_many_attempts.
3. Verify the code
401 invalid_code (you get 5 attempts per challenge).
4. Execute the action with the token
idempotency_key remains the duplicate protection — OTP does not
replace it.
Two-step login
If your policy requires OTP onlogin, POST /v1/auth/login no longer
returns the session directly:
pending_token cannot call the API: it is only exchanged, along
with the code, for the real session:
The account’s phone
- E.164 format (
+56912345678), set at registration, throughPATCH /v1/meor by your operator. phone_verifiedflips totruethe first time you verify a challenge: it proves the holder has the phone in hand.- Changing the phone (action
phone_change) validates the code against the previous number — nobody can redirect your codes without holding your current phone. - If the phone is linked for the first time (or changed without
verification), SMS/WhatsApp challenges stay locked for 24 hours: the
anti session-hijacking window. During the cooldown, if you have the
authenticator app enrolled or a verified email, the challenge is issued
automatically over that stronger factor (the channel comes back in the
challenge response); you only get
403 phone_binding_cooldownwhen no alternative factor exists. A phone set by your operator has no cooldown. - The two-step login honors the same rule: with login 2FA over
SMS/WhatsApp and the phone in cooldown, the login code is issued over the
authenticator app or your login email instead (the effective
channelcomes back in the login response) — it is never sent to a recently linked, unverified number. Without an alternative factor the login responds403 phone_binding_cooldownuntil the cooldown expires.
Errors
FAQ
Does OTP affect my server-to-server integrations?
Does OTP affect my server-to-server integrations?
No.
pk_ API keys are exempt by design: automation never goes through
OTP. Guard your keys accordingly — issuing a new key CAN require OTP
(action api_key_create).Can I choose SMS or WhatsApp?
Can I choose SMS or WhatsApp?
The channel is configured by your operator per action (per account or
for the whole organization). You see it in
GET /v1/otp/settings.How long does a code last and how many attempts do I get?
How long does a code last and how many attempts do I get?
The code and challenge last 10 minutes. You get 5 verifications per
challenge and an hourly send limit. The resulting
otp_token is single
use.Can I request one token and use it for several actions?
Can I request one token and use it for several actions?
No: the token is bound to the exact action the challenge was created
for (a
payout token does not work for transfer) and is consumed on
first use.The action failed after consuming the token — do I pay twice?
The action failed after consuming the token — do I pay twice?
No. A consumed token only means you must verify a new challenge; the
operation’s
idempotency_key still guarantees there are no duplicates.