Error codes

The error format, what each code means, rate limits, and how to fix each one.

Errors use a standard HTTP status and a JSON body with a machine-readable code and a human-readable message:

{
  "error": {
    "code": "invalid_phone",
    "message": "phone must be an 8-digit Mongolian number"
  }
}

Branch on code, not on message. Messages may change.

Codes

HTTPcodeWhat happenedWhat to do
400invalid_requestThe body is not valid JSON, or a field is missing or malformed. Also returned when the widget state is not 1 to 128 characters of A-Z a-z 0-9 . _ ~ -Check the request against the API reference
400invalid_phoneThe phone number (also the widget phone option) is not a valid 8-digit Mongolian numberSend 8 digits; +976 and 976 prefixes are accepted
401unauthorizedThe API key is missing, invalid, revoked, or used from an IP address outside its allowlistSend Authorization: Bearer sk_... with an active key; if the key has an IP allowlist, add your server's IP
403client_suspendedYour account is suspendedContact support
403test_onlyThe endpoint works only with test keysUse an sk_test_ key, for example for /v1/test/mo
409rule_limitThe client already has the maximum number of live rules (5)Delete a rule you no longer need, or email hello@2fa.mn to have the limit raised
404not_foundThe object doesn't exist in this modeCheck the id and that you use the API key of the same mode
409prefix_takenA live rule prefix overlaps another client's prefix. Prefixes are shared across 150073, so none may be a prefix of another (HIHI blocks HI and HIHI2)Pick a different prefix
429rate_limitedToo many requestsBack off and retry later; see Limits
400invalid_tokenThe widget token is malformed or not recognised (POST /v1/verifications, or GET /v1/verifications/{token})Pass the token from the browser unchanged
409token_usedThe widget token was already redeemedA token works once. To verify again, start the widget again
410token_expiredThe widget token has expiredRedeem the token soon after verification, or verify again
403origin_not_allowedThe widget was loaded from a site not on the publishable API key's listAdd your site's origin under Dashboard > Widget
403widget_disabledThe widget is turned offTurn it on under Dashboard > Widget. If it is on, contact support
500internal_errorA temporary problem on our sideRetry after a short wait; if it keeps happening, email hello@2fa.mn with the request time

Not an error

Sending the code of an already verified session again is treated as already_verified. It is not an error: no new webhook is sent, and the SMS does not count toward that number's wrong-SMS throttle.

Rate limits

See Limits for when 429 rate_limited is returned.

Tips

  • A 404 for an object you just created usually means you're mixing test and live API keys.
  • Retry 429 and 5xx responses with backoff. Don't retry other 4xx responses unchanged.
  • Log the code together with your request id to make support faster.

What's next

Was this page helpful?