Authy One-Time Passwords (OTP)

Once a user (see Users documentation) has been registered with your Twilio Authy application and receives an AuthyID, you can now implement 2FA, passwordless login or protect an in-application high value transaction. Using the Authy API, you can send one-time passwords over voice or SMS channels, and users can additionally use authentication application or SDK linked soft tokens.

For users that are unable to recieve SMS or voice calls, possibly due to lack of wireless connectivity, they can install the free Authy app or use our SDK to generate offline TOTP codes (soft tokens). You also use the API to verify these tokens, to validate it the user has indeed access to the right phone number (in the case of SMS and voice) or the right trusted devices (in the case of the Authy app or use of the SDK).

Twilio's Authy API follows the algorithms described in RFC 6238 and RFC 4226 to generate TOTP (Time-Based One-Time Passwords) and HOTP (HMAC-Based One-Time Password) passwords. It is also possible to use your own hardware tokens, please contact us for information on how to enable this type of 2FA.

Authenticator App Generated One-Time Passwords

Authy App

When you enroll a user, they will automatically be able to generate Soft Token TOTP codes in the Authy App if they register for Authy with the same phone number that you used to enroll them. You do not need to do anything additional to take advantage of the Authy app. You can disable this behavior with the 'Sync tokens in Authy app' setting in the Authy settings in the Twilio Console.

To validate these One-Time Passwords, use the section 'Verify a One-Time Password' below.

Authenticator SDK

You can embed the same functionality from the Authy app into any mobile application using the Twilio Authenticator SDK.

Other Authenticator Apps

In order to support other Authenticator apps, like Google Authenticator, you will need to display a QR code to your users that contains a compatible OTP secret. The API will return a link to a valid QR code.

In order to customize the QR label and give the final user context about the token like account name or email, you can include the label param in the QR generation endpoint. That way many Authenticator apps will automatically render the label in the token list.

https://authy.com/protected/{FORMAT}/users/{AUTHY_ID}/secret?api_key={KEY}

URL

Name Type Description
FORMAT String The format to expect back from the REST API call. json, or xml.
AUTHY_ID Integer The Authy ID of the user to send a SMS TOTP. Note that password delivery may be upgraded; see below table.

Parameters

Name Type Description
api_key String (required) The api key which can be obtained from the console.
qr_size Integer (optional) Dimension of the QR code that will be returned. Square, so only one number required.
label String (optional) A custom label for the QR code, this field will be shown by the Authenticator app, it gives context to the user, like the account email.
Example

This example adds a GenericToken to a User and returns the QR code with the secret to be scanned by the user in the Authenticator App. The QR size will be 300x300 pixels.

curl "https://api.authy.com/protected/json/users/2/secret" \
-d api_key="d57d919d11e6b221c9bf6f7c882028f9" \
-d label="AppName(myuser@example.com)" \
-d qr_size="300"

Sample response:

{
  “label": ”AppName(myuser@example.com)”,
  “Issuer”: “AppName”,
  “qr_code”: “https://[qr_code]”
  "success":true
}

Request a One-Time Password

When you call the API to start either an SMS or voice based authentication, it automatically checks to see if that user has previously downloaded the Authy app or has an app installed that uses our SDK. If there is a record of a device, by default, the API will not send the 2FA code via SMS or voice, instead a push notification will go to the device, prompting the user to start their app to get the code.

If a user has no record of installing a device, then the API will continue to send the code via SMS or voice. Note this behaviour can be over-ridden to force the sending of code via SMS or voice every time. This is a useful override if a user is specifically selecting "Send SMS" or "Get code via voice call" in your application UI.

Custom Actions (Optional)

Optionally, you can limit a specific token to a single action, for example coupling a one-time password to a specific logon request or transaction. Most implementations will not need this feature.

You can pass action= and action_message= (optional) to send a code that is only valid for the given action. This is useful if you require codes to perform different actions on your app, for example, you can pass action=login&action_message="Login code" when sending a login code.

When using this option you must pass the same action when verifying the code.

GET https://api.authy.com/protected/{FORMAT}/sms/{AUTHY_ID}?api_key={KEY}

URL

Name Type Description
FORMAT String The format to expect back from the REST API call. json, or xml.
AUTHY_ID Integer The Authy ID of the user to send a SMS TOTP. Note that password delivery may be upgraded; see below table.

Parameters

Name Type Description
api_key String (required) The api key which can be obtained from the console.
force Boolean (optional) We suggest using the default, false, as OTP verifications are forward compatible, perhaps setting true for user retries. When true, we will send one-time passwords over the SMS channel even if the user has an Authy or SDK enabled app installed. You can also configure the default behavior through the console.
action String (optional) The optional action or context we are trying to validate.
action_message String (optional) Optional message for the specific action.

Response

Name Type Description
success Boolean Returns true if the request was successful.
message String A message indicating what happened with the request.
cellphone String The country code and last two digits of phone number used to send the message with the rest obfuscated.
ignored Boolean True if we detected an Authy or SDK enabled app installed and we upgraded the OTP delivery channel from 'SMS' to Push Notification. Authy or SDK users are redirected directly to the requested token.
device String The type of the last device used by the user. This is only returned when we upgraded delivery from SMS.


Send a One-Time Password via SMS

curl -i "http://api.authy.com/protected/json/sms/234572" \
    -H "X-Authy-API-Key: d57d919d11e6b221c9bf6f7c882028f9"
Sample response when the user doesn't have the Authy Client or SDK
{
    "success":true,
    "message":"SMS token was sent",
    "cellphone":"+1-XXX-XXX-XX02"
}
Sample response when the user has the Authy Client or SDK
{
    "message":"Ignored: SMS is not needed for smartphones. Pass force=true if you want to actually send it anyway.",
    "cellphone":"+1-XXX-XXX-XX02",
    "device":"android",
    "ignored":true,
    "success":true
}

You can pass in a force=true parameter to this API. This will force the SMS to be sent even if the user is using the Authy Client or SDK.

curl "http://api.authy.com/protected/json/sms/567345?force=true" \
    -H "X-Authy-API-Key: d57d919d11e6b221c9bf6f7c882028f9"
Sample response
{
    "success":true,
    "message":"SMS token was sent",
    "cellphone":"+1-XXX-XXX-XX02"
}

Custom action example

curl "http://api.authy.com/protected/json/sms/126435?action=change_preferences" \
    -H "X-Authy-API-Key: d57d919d11e6b221c9bf6f7c882028f9"
Sample response
{
    "success":true,
    "message":"SMS token was sent"
}


Send a One-Time Password via Voice

For users that don't own a smartphone, and are having trouble with SMS Tokens, Authy allows you to use phone calls instead. This call will be ignored if the user is using the Authy Mobile app.

POST https://api.authy.com/protected/{FORMAT}/call/{AUTHY_ID}?api_key={KEY}

URL

Name Type Description
FORMAT String The format to expect back from the REST API call. json, or xml.
AUTHY_ID Integer The Authy ID of the user to send a Voice TOTP. Note that password delivery may be upgraded; see below table.

Parameters

Name Type Description
api_key String (required) The api key which can be obtained from the Twilio console.
force Boolean (optional) We suggest using the default, false, as OTP verifications are forward compatible, perhaps setting true for user retries. When true, we will send one-time passwords over the Voice channel even if the user has an Authy or an SDK enabled app installed installed. You can also configure the default behavior through the console.
action String (optional) The action or context we are trying to validate.
action_message String (optional) Message for the specific action.

Response

Name Type Description
success Boolean Returns true if the request was successful.
message String A message indicating what happened with the request.
cellphone String The country code and last two digits of phone number used to send the message, with the rest obfuscated.
ignored Boolean True if we detected an Authy or an SDK enabled app installed and we upgraded the OTP delivery channel from 'Voice' to Push Notification. Authy or SDK users are redirected directly to the requested token.
device String The type of the last device used by the user. This is only returned when we upgraded delivery from a voice call.

Example

Requesting a one-time password via Voice Call

curl -i "http://api.authy.com/protected/json/call/209412" \
    -H "X-Authy-API-Key: d57d919d11e6b221c9bf6f7c882028f9"
Sample response when the user doesn't have the Authy app or SDK enabled app
{
    "success":true,
    "message":"Call started...",
    "cellphone":"+1-XXX-XXX-XX02"
}
Sample response when the user has the Authy app or SDK enabled app
{
    "message":"Call ignored. User is using App Tokens and this call is not necessary. Pass force=true if you still want to call users that are using the App.",
    "cellphone":"+1-XXX-XXX-XX02",
    "device":"android",
    "ignored":true,
    "success":true
}

You can pass force=true as parameter to this API. This will force the phone call to start even if the user is using the Authy app.

curl -i "http://api.authy.com/protected/json/call/142352?force=true"  \
    -H "X-Authy-API-Key: d57d919d11e6b221c9bf6f7c882028f9"
Sample response
{
    "success":true,
    "message":"Call started...",
    "cellphone":"+1-XXX-XXX-XX02"
}


Verify a One-Time Password

To verify a one-time password simply pass in the user provided token and the user `authy_id. Twilio will use HTTP status codes for the response.

GET https://api.authy.com/protected/{FORMAT}/verify/{TOKEN}/{AUTHY_ID}?api_key={KEY}

URL

Name Type Description
FORMAT String The format to expect back from the REST API call. json, or xml.
TOKEN Integer The token you are verifying.
AUTHY_ID String The Authy ID of the user validating the TOTP.

Parameters

Name Type Description
api_key String (required) Your private API key.

Responses

Name Type Description
200 Integer Valid token (see note below)*
401 Integer Invalid token. If you wish to verify the token anyway, pass force=true. See the force verification section below for an example.

*Note: Until you successfully verify a token for a new user, this call will return 200.

Response

Name Type Description
token String Either "is valid" or "is invalid"
success String "true" if the code was valid. Please note this field is a String and not a Boolean.
device Object An object including some details about the device used to get or generate the token. The fields included in the device object are: city, region, country, ip, registration_city, registration_region, registration_country, registration_ip, registration_date, os_type, last_account_recovery_at and id.

Example

When the TOTP token is generated in the Authy app or in the SDK, additional device information as well as registration data are provided.

curl -i "http://api.authy.com/protected/json/verify/1234567/142222" \
    -H "X-Authy-API-Key: d57d919d11e6b221c9bf6f7c882028f9"
Response
{
    "message": "Token is valid.",
    "token": "is valid",
    "success": "true",
    "device": {
        "city": "San Francisco",
        "country": "United States",
        "ip": "97.20.126.156",
        "region": "California",
        "registration_city": "San Francisco",
        "registration_country": "United States",
        "registration_ip": "97.34.234.11",
        "registration_method": "sms",
        "registration_region": "California",
        "os_type": "android",
        "last_account_recovery_at": null,
        "id": 83372911,
        "registration_date": 1490996931
    }
}

Example: Token received via SMS

When the OTP token is delivered via SMS or Voice call, no additional device details are provided.

curl -i "http://api.authy.com/protected/json/verify/1234567/111111" \
    -H "X-Authy-API-Key: d57d919d11e6b221c9bf6f7c882028f9"
Response
{
    "message": "Token is valid.",
    "token": "is valid",
    "success": "true",
    "device": {
        "city": null,
        "country": null,
        "ip": null,
        "region": null,
        "registration_city": null,
        "registration_country": null,
        "registration_ip": null,
        "registration_method": "sms",
        "registration_region": null,
        "os_type": "sms",
        "last_account_recovery_at": null,
        "id": null,
        "registration_date": 1490996931
    }
}

Example: Invalid request

curl -i "http://api.authy.com/protected/json/verify/1234567/111111" \
    -H "X-Authy-API-Key: d57d919d11e6b221c9bf6f7c882028f9"
Response
{
    "success": "false",
    "errors": {
        "token":"is invalid"
    }
}

Example: Force One-Time Password Validation for Unregistered User

Use force=true to force verification of a one-time password from a new user. Otherwise, until one token has been successfully verified for that user we will always return 200.

curl -i "http://api.authy.com/protected/json/verify/939393/333333" \
    -H "X-Authy-API-Key: d57d919d11e6b221c9bf6f7c882028f9"
Response if force=false or Not Set
{
    "token":"Not checked. User has not yet finished the registration process. Pass force=true to this API to check regardless (more secure)."
}
Response if force=true
{
    "errors": {
        "token":"is invalid"
    }
}

Custom Actions

When using custom actions to send SMS you have to pass action= to validate the one-time password. For more information see Custom Actions under the Request a One-Time Password section above.

{
    "token": "is valid"
}

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd browsing the Twilio tag on Stack Overflow.