# Authy Webhooks API

> \[!WARNING]
>
> As of November 2022, Twilio no longer provides support for Authy SMS/Voice-only customers. Customers who were also using Authy TOTP or Push prior to March 1, 2023 are still supported. The Authy API is now closed to new customers and will be fully deprecated in the future.
>
> For new development, we encourage you to use the [Verify v2 API](/docs/verify/api).
>
> Existing customers will not be impacted at this time until Authy API has reached End of Life. For more information about migration, see [Migrating from Authy to Verify for SMS](https://www.twilio.com/blog/migrate-authy-to-verify).

Set a webhook to be called after a [publicly visible event](#available-events) happens and improve insight into your Authy application's usage. The API has three endpoints:

* [Create a webhook](#create-webhook)
* [Delete a webhook](#delete-webhook)
* [List webhooks](#list-webhooks)

> \[!NOTE]
>
> Twilio can send your web application an HTTP request when certain events happen, such as an incoming text message to one of your Twilio phone numbers. These requests are called *webhooks*, or *status callbacks*. For more, check out our guide to [Getting Started with Twilio Webhooks](/docs/usage/webhooks/getting-started-twilio-webhooks). Find other webhook pages, such as a [security guide](/docs/usage/webhooks/webhooks-security) and an [FAQ](/docs/usage/webhooks/webhooks-faq) in the [Webhooks](/docs/usage/webhooks) section of the docs.

## Signing Requests

All Webhook API requests require the `X-Authy-Signature` header. These are the steps required to generate the header and sign a request:

1\. Create a string variable using the URL without parameters:

```bash
url = "https://api.authy.com/dashboard/json/application/webhooks"
```

2\. Create a string variable with the HTTP method in upper case (`GET`, `POST`, `DELETE`):

```bash
http_method = "POST"
```

3\. Sort the list of parameters in case-sensitive order and convert them to URL format

Both key and value should be URL-encoded.

```bash
params = {b: "val|ue&2", a: "value1"}
sorted_params = "a=value1&b=val%7Cue%262"
```

4\. Generate a unique [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce)

Your language of choice likely has a nonce generator library, such [`nonce`](https://www.npmjs.com/package/nonce) in Node.js.

```bash
nonce = "1427849783.886085"
```

5\. Join `nonce`, `http_method`, `url` and `params_in_url_format` together with the `|` character:

**Note:** the string should contain exactly 3 `|` characters.

```bash
data = nonce + "|" + http_method + "|" + url + "|" + params_in_url_format
"1427849783.886085|POST|https://api.authy.com/dashboard/json/application/webhooks|a=value1&b=val%7Cue%262"
```

6\. Hash the resulting data using HMAC-SHA256, using your `api_signing_key` as the key:

Get your API signing key from "Webhooks API Keys" section of the [application settings tab in the Twilio Console](https://www.twilio.com/console/authy/applications/).

```bash
digest = hmac_sha256(data, api_signing_key)
```

7\. Base64 encode the digest:

Base64 encoding should not contain line feeds. It must be encoded as described in the [RFC 4648](https://datatracker.ietf.org/doc/html/rfc4648).

```bash
digest_in_base64 = encode_in_base64(digest)
```

8\. Make the HTTP request with specified headers

Send the digest\_in\_base64 in the `X-Authy-Signature` header

Send the nonce in the `X-Authy-Signature-Nonce` header.

```bash
request.headers["X-Authy-Signature"] = digest_in_base64
request.headers["X-Authy-Signature-Nonce"] = nonce
make_request(request)
```

## Webhooks API Keys

Webhook API requests require the `app_api_key` and `access_key` parameters. Signing the request (step 6 above) requires the `api_signing_key`. These are found in the [application settings tab in the Twilio Console.](https://www.twilio.com/console/authy/applications/)

![Authy settings showing application name, ID, and webhooks API keys.](https://docs-resources.prod.twilio.com/8b1c7ba75f2f94dd041a971535a7715fee55e42534dca08881084e4658166c33.png)

## Create a webhook \[#create-webhook]

```bash
POST  https://api.authy.com/dashboard/json/application/webhooks
```

### Parameters \[#create-webhook-parameters]

| Name          | Type         | Description                                                                                                                                                                                                                                                           |
| :------------ | :----------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| url           | string       | The callback URL to receive registered events in the webhook ([🏢 not PII](/docs/glossary/what-is-personally-identifiable-information-pii#fields-marked-not-pii) )                                                                                                    |
| events        | array string | The list of events to monitor by the webhook. See [available events](#available-events) ([🏢 not PII](/docs/glossary/what-is-personally-identifiable-information-pii#fields-marked-not-pii) )                                                                         |
| name          | string       | Identifying name for your webhook. ([🏢 not PII](/docs/glossary/what-is-personally-identifiable-information-pii#fields-marked-not-pii) )                                                                                                                              |
| app\_api\_key | string       | Found in the [application settings tab in the Twilio Console.](https://www.twilio.com/console/authy/applications/) See [webhooks API keys](#webhooks-api-keys). ([🏢 not PII](/docs/glossary/what-is-personally-identifiable-information-pii#fields-marked-not-pii) ) |
| access\_key   | string       | Found in the [application settings tab in the Twilio Console.](https://www.twilio.com/console/authy/applications/) See [webhooks API keys](#webhooks-api-keys). ([🏢 not PII](/docs/glossary/what-is-personally-identifiable-information-pii#fields-marked-not-pii) ) |

### Response \[#create-webhook-response]

| Name    | Type    | Description                                                                                                                                           |
| :------ | :------ | :---------------------------------------------------------------------------------------------------------------------------------------------------- |
| webhook | object  | Details about the created webhook. See below for more details. ([🏢 PII](/docs/glossary/what-is-personally-identifiable-information-pii#pii-fields) ) |
| message | string  | Authy API response description. ([🏢 PII](/docs/glossary/what-is-personally-identifiable-information-pii#pii-fields) )                                |
| success | Boolean | Returns true if the request was successful. ([🏢 not PII](/docs/glossary/what-is-personally-identifiable-information-pii#fields-marked-not-pii) )     |

The response will be JSON with the following structure:

```bash
webhook: webhook object
   id: Webhook id
   name: Webhook name
   account_sid: Twilio owner account id
   service_id: Authy application serial id
   url: Callback url
   signing_key: The key to verify JWT response received by the callback url
   events: List of events which will trigger webhook callbacks
   objects: Objects involved in the event. This is specific by event type.
   creation_date: Date in which webhook was created
message: Authy api response message
success: Whether yes or no request was success
```

Create an Authy Webhook

```bash
curl -X POST "https://api.authy.com/dashboard/json/application/webhooks" \
   -d name="my webhook" \
   -d app_api_key=""tLPrf... \
   -d access_key="usQ4z..." \
   -d url="https://example.com/callback-action" \
   -d events[]="phone_verification_started" \
   -H "X-Authy-Signature-Nonce: 1427849783.886085" \
   -H "X-Authy-Signature: 5RgJYUuz9m/rhi6XPjAjKUtNOJqPgMnP9GKBqWJEGFg="
```

```json
{
  "webhook": {
    "id": "WH_0c04...",
    "name": "my webhook",
    "account_sid": "ACec7...",
    "service_id": "56...",
    "url": "https://example.com/callback-action",
    "signing_key": "WSK_ovh...",
    "events": ["phone_verification_started"],
    "creation_date": "2017-03-30T20:10:37.121+00:00"
  },
  "message": "Webhook created",
  "success": true
}
```

### Available Events

Webhooks can be configured for the following events:

* [account\_recovery\_approved](/docs/authy/api/reporting/account_recovery_approved)
* [account\_recovery\_canceled](/docs/authy/api/reporting/account_recovery_canceled)
* [account\_recovery\_started](/docs/authy/api/reporting/account_recovery_started)
* [custom\_message\_not\_allowed](/docs/authy/api/reporting/custom_message_not_allowed)
* [device\_registration\_completed](/docs/authy/api/reporting/device_registration_completed)
* [multidevice\_setting\_changed](/docs/authy/api/reporting/multidevice_setting_changed)
* [one\_touch\_request\_responded](/docs/authy/api/reporting/one_touch_request_responded) (note: one\_touch refers to the [Authy Push Authentication API](/docs/authy/api/push-authentications)
* [phone\_change\_canceled](/docs/authy/api/reporting/phone_change_canceled)
* [phone\_change\_pin\_sent](/docs/authy/api/reporting/phone_change_requested)
* [phone\_change\_requested](/docs/authy/api/reporting/phone_change_requested)
* [suspended\_account](/docs/authy/api/reporting/suspended_account)
* [token\_invalid](/docs/authy/api/reporting/token_invalid)
* [token\_verified](/docs/authy/api/reporting/token_verified)
* [too\_many\_code\_verifications](/docs/authy/api/reporting/too_many_code_verifications)
* [totp\_token\_sent\_via\_call](/docs/authy/api/reporting/totp_token_sent_via_call)
* [totp\_token\_sent](/docs/authy/api/reporting/totp_token_sent)
* [unlock\_method\_changed](/docs/authy/api/reporting/unlock_method_changed)
* [user\_account\_deleted](/docs/authy/api/reporting/user_account_deleted)
* [user\_added](/docs/authy/api/reporting/user_added)
* [user\_phone\_changed](/docs/authy/api/reporting/user_phone_changed)

The following events are specific to our legacy phone verification API. Please consider [upgrading to Verify V2:](/docs/verify/migrating-1x-2x)

* [phone\_verification\_code\_is\_invalid](/docs/authy/api/reporting/phone_verification_code_is_invalid)
* [phone\_verification\_code\_is\_valid](/docs/authy/api/reporting/phone_verification_code_is_valid)
* [phone\_verification\_failed](/docs/authy/api/reporting/phone_verification_failed)
* [phone\_verification\_not\_found](/docs/authy/api/reporting/phone_verification_not_found)
* [phone\_verification\_started](/docs/authy/api/reporting/phone_verification_started)
* [too\_many\_phone\_verifications](/docs/authy/api/reporting/too_many_phone_verifications)

## Delete a webhook \[#delete-webhook]

```bash
DELETE  https://api.authy.com/dashboard/json/application/webhooks/:webhook_id
```

### URL

| Name        | Type   | Description                                                                                                          |
| :---------- | :----- | :------------------------------------------------------------------------------------------------------------------- |
| webhook\_id | String | The webhook id ([🏢 not PII](/docs/glossary/what-is-personally-identifiable-information-pii#fields-marked-not-pii) ) |

### Parameters \[#delete-webhook-parameters]

| Name          | Type   | Description                                                                                                                                                                                                                                                           |
| :------------ | :----- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| app\_api\_key | string | Found in the [application settings tab in the Twilio Console.](https://www.twilio.com/console/authy/applications/) See [webhooks API keys](#webhooks-api-keys). ([🏢 not PII](/docs/glossary/what-is-personally-identifiable-information-pii#fields-marked-not-pii) ) |
| access\_key   | string | Found in the [application settings tab in the Twilio Console.](https://www.twilio.com/console/authy/applications/) See [webhooks API keys](#webhooks-api-keys). ([🏢 not PII](/docs/glossary/what-is-personally-identifiable-information-pii#fields-marked-not-pii) ) |

### Response \[#delete-webhook-response]

| Name    | Type    | Description                                                                                                                                       |
| :------ | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------ |
| message | string  | Authy API response description. ([🏢 PII](/docs/glossary/what-is-personally-identifiable-information-pii#pii-fields) )                            |
| success | Boolean | Returns true if the request was successful. ([🏢 not PII](/docs/glossary/what-is-personally-identifiable-information-pii#fields-marked-not-pii) ) |

Delete an Authy Webhook

```bash
curl -X DELETE "https://api.authy.com/dashboard/json/application/webhooks/WH_0c04..." \
  -d app_api_key=""tLPrf... \
  -d access_key="usQ4z..." \
  -H "X-Authy-Signature-Nonce: 1427849783.886085" \
  -H "X-Authy-Signature: QB+u2hFTj+fstAEbSUQUfA7409uKJTL2W17MrRuk3OE="
```

```json
{
  "message": "Webhook deleted",
  "success": true
}
```

## List Webhooks \[#list-webhooks]

```bash
GET https://api.authy.com/dashboard/json/application/webhooks
```

This endpoint does not require parameters.

### Response \[#list-webhook-response]

| Name     | Type    | Description                                                                                                                                                    |
| :------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| webhooks | array   | Array of webhook objects. See examples for detailed response structure. ([🏢 PII](/docs/glossary/what-is-personally-identifiable-information-pii#pii-fields) ) |
| success  | Boolean | Returns true if the request was successful. ([🏢 not PII](/docs/glossary/what-is-personally-identifiable-information-pii#fields-marked-not-pii) )              |

List Authy Webhook

```bash
curl -X GET https://api.authy.com/dashboard/json/application/webhooks \
  -d app_api_key="tLPrf..." \
  -d access_key="usQ4z..." \
  -H "X-Authy-Signature-Nonce:1427849783.886085" \
  -H "X-Authy-Signature: QB+u2hFTj+fstAEbSUQUfA7409uKJTL2W17MrRuk3OE="
```

```json
{
  "webhooks":[
    {
      "id":"WH_0c04...",
      "name":"my webhook",
      "account_sid":"ACec7...",
      "service_id":"56...",
      "url":"https://example.com/callback-action",
      "signing_key":"WSK_ovh...",
      "events":[
        "phone_verification_started"
      ],
      "creation_date":"2018-03-30T20:10:37.121+00:00"
    },
    {
      "id":"WH_0c05...",
      "name":"my other webhook",
      "account_sid":"ACec7...",
      "service_id":"57...",
      "url":"https://example.com/callback-action",
      "signing_key":"WSK_ivf...",
      "events":[
        "phone_verification_started"
      ],
      "creation_date":"2018-03-30T20:10:37.121+00:00"
    }
  ],
  "success":true
}
```

## More Examples

You can find more examples of how to use Authy Webhooks in the [Node implementation of the webhooks API](https://github.com/AuthySE/webhooks-api) on Github.

## Verify Callbacks

The Twilio Authy webhooks service will send a callback every time a registered event occurs. The response will be coded in JWT and signed with the `signing_key` for the registered webhook. Use that `signing_key` to validate the response when you decode it.

[Visit this page for more information on validating webhooks](/docs/authy/validation).
