---
title: "Webhooks"
url: "https://docs.signnow.com/docs/guides-webhooks"
type: "page"
section: "Documentation"
slug: "guides-webhooks"
---

# Webhooks

## About Webhooks

**Webhooks** or **Event Subcriptions** are one of a few ways SignNow can communicate with your system using callbacks based on subscribe SignNow events. It allows you to receive and handle a real-time data from SignNow to your system.

When you add a webhook, you choose which events you want to subscribe to. To limit the number of HTTP requests to your server, you should only subscribe to the specific events that you plan on handling.

<!-- theme: info -->

> **Note**: In SignNow, Webhooks and Event Subscriptions mean the same thing. They are available with an API free trial, an active API subscription, or a Site License.

### What's the use for webhooks?

Being notified about an event allows you to build automated workflows with various documents being sent for signature in a specific order to specific recipients.

## Entity types

### How do I set up the scope of info I'd like to receive?

SignNow uses `entity types` to mark the amount of information about the event that you'd like to filter out. This means you can be triggered only by events regarding one of the entity types.  So:

**Entity type** - an object in SignNow API that limits the scope of webhook callbacks.

**Available entity types**: `user`, `document`, `document_group`.

| Entity type        | Meaning                                                                  | Example                                                                                                                                                                                                                                                                 |
| ------------------ | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **User**           | Is used to subcscribe to events happening with a specific user.          | For example, an invite has been sent to multiple users, and one user has declined to sign it. You'll receive a callback only about the event of declining to sign because this was the action of the user you've specified as your entity type.                         |
| **Document**       | Is used to subscribe to events happening with a specific document.       | For example: a document has been modified and sent for signature. Some people signed it, some declined to sign it. You'll receive callbacks about all of these events because all these actions happened to the entity type you've specified: this particular document. |
| **Document group** | Is used to subscribe to events happening with a specific document group. | For example: a document group has been sent for signature and signed by all the recipients. You'll receive callbacks about all of these events because all these actions happened to the entity type you've specified: the document group.                              |

## Entity events

### What kind of events can trigger the webhook?

**Entity events** - create, update, delete actions that might occur with a specific entity type.

### User events

| Event type        | Meaning                         |
| ----------------- | ------------------------------- |
| **User document events** ||
| `user.document.create` | This user created a document |
| `user.document.open` | This user's document was opened |
| `user.document.update` | This user's document was edited |
| `user.document.complete` | All the required fields on this user's document were filled in |
| `user.document.delete` | This user's document was deleted |
| `user.template.copy` | This user created a document from template |
| `user.document.generated` | This user generated a document from a DOCX template |
| `user.document.fieldinvite.create` | This user created a document field invite |
| `user.document.fieldinvite.sent` | This user sent a document field invite |
| `user.document.fieldinvite.signed` | A document field invite sent by this user was signed |
| `user.document.fieldinvite.reassign` | A signer reassigned a document field invite for this user's document |
| `user.document.fieldinvite.decline` | A document field invite sent by this user was declined |
| `user.document.fieldinvite.resend` | This user resent a document field invite |
| `user.document.fieldinvite.replace` | This user replaced a signer of a document field invite |
| `user.document.fieldinvite.delete` | This user deleted a document field invite |
| `user.document.freeform.create` | This user created a document freeform invite |
| `user.document.freeform.signed` | A document freeform invite sent by this user was signed |
| `user.document.freeform.resend` | This user resent a document freeform invite |
| `user.document.freeform.cancel` | This user canceled a document freeform invite |
| `user.document.fieldinvite.consent.agreed` | A signer agreed to this user's terms within a document field invite |
| `user.document.fieldinvite.consent.declined` | A signer declined their consent to this user's terms within a document field invite |
| `user.document.fieldinvite.consent.withdrawn` | A signer withdrew their consent to this user's terms within a document field invite |
| `user.document.fieldinvite.authentication.failed` | A signer's authentication failed for this user's document field invite |
| `user.document.fieldinvite.email.delivery.failed` | An email with the document field invite from this user was not delivered |
| `user.invite.expired` | A field invite sent by this user expired (applies to both document and document group) |
| **User document group events** ||
| `user.document_group.create` | This user created a document group |
| `user.document_group.open` | This user opened a document group |
| `user.document_group.update` | This user updated a document group |
| `user.document_group.complete` | All the required fields on this user's document group were filled in, or the invite has expired |
| `user.document_group.copy` | This user copied a document group |
| `user.document_group.generated` | This user generated a document group from a DOCX template |
| `user.document_group.delete` | This user deleted a document group |
| `user.document_group.invite.create` | This user created a document group field invite |
| `user.document_group.invite.sent` | This user sent a document group field invite |
| `user.document_group.invite.signed` | A document in a document group field invite sent by this user was signed |
| `user.document_group.invite.signer.complete` | All documents in a document group field invite sent by this user were completed by a specific signer |
| `user.document_group.invite.reassign` | A signer reassigned a document field invite for this user's document group |
| `user.document_group.invite.declined` | A document group field invite sent by this user was declined |
| `user.document_group.invite.resend` | This user resent a document group field invite |
| `user.document_group.invite.update` | This user updated a document group field invite |
| `user.document_group.invite.cancel` | This user canceled a document group field invite |
| `user.document_group.invite.expired` | A document group field invite sent by this user expired |
| `user.document_group.freeform.create` | This user created a document group freeform invite |
| `user.document_group.freeform.signed` | A document group freeform invite sent by this user was signed |
| `user.document_group.freeform.resend` | This user resent a document group freeform invite |
| `user.document_group.freeform.cancel` | This user canceled a document group freeform invite |
| `user.document_group.invite.consent.agreed` | A signer agreed to this user's terms within a document group field invite |
| `user.document_group.invite.consent.declined` | A signer declined their consent to this user's terms within a document group field invite |
| `user.document_group.invite.consent.withdrawn` | A signer withdrew their consent to this user's terms within a document group field invite |
| `user.document_group.invite.authentication.failed` | A signer's authentication failed for this user's document group field invite |
| `user.document_group.invite.email.delivery.failed` | An email with the document group field invite from this user was not delivered |

### Document events

| Event type | Meaning     |
| ---------- | ----------- |
| `document.open` | This document was opened |
| `document.update` | This document was edited |
| `document.complete` | All the required fields on this document were filled in |
| `document.delete` | This document was deleted |
| `template.copy` | A document was generated from this template |
| `document.fieldinvite.create`| A field invite for this document was created  |
| `document.fieldinvite.sent` | A field invite for this document was sent |
| `document.fieldinvite.signed` | A field invite for this document was signed |
| `document.fieldinvite.reassign` | A signer reassigned a field invite for this document |
| `document.fieldinvite.decline` | A field invite for this document was declined |
| `document.fieldinvite.resend` | A field invite for this document was resent |
| `document.fieldinvite.replace` | A sender replaced a signer of the field invite for this document |
| `document.fieldinvite.delete` | A field invite for this document was deleted |
| `document.freeform.create` | A freeform invite for this document was created |
| `document.freeform.signed` | A freeform invite for this document was signed |
| `document.freeform.resend` | A freeform invite for this document was resent |
| `document.freeform.cancel` | A freeform invite for this document was canceled |
| `document.fieldinvite.consent.agreed` | A signer agreed to the terms within a field invite with this document |
| `document.fieldinvite.consent.declined` | A signer declined their consent to the terms within a field invite with this document |
| `document.fieldinvite.consent.withdrawn` | A signer withdrew their consent to the terms within a field invite with this document |
| `document.fieldinvite.authentication.failed` | A signer's authentication failed for a field invite with this document |
| `document.fieldinvite.email.delivery.failed` | An email with a field invite with this document was not delivered |

### Document group events

| Event type                     | Meaning                                                 |
| ------------------------------ | ------------------------------------------------------- |
| `document_group.open`          | This document group was opened                   |
| `document_group.update`        | This document group was updated                  |
| `document_group.complete`      | All the required fields on this document group were filled in, or the invite has expired |
| `document_group.copy`      | This document group was copied |
| `document_group.delete`        | This document group was deleted                     |
| `document_group.invite.create` | A field invite for this document group was created |
| `document_group.invite.sent`   | A field invite for this document group was sent   |
| `document_group.invite.signed` | A document in this document group field invite was signed |
| `document_group.invite.signer.complete` | All documents in this document group field invite were completed by a specific signer |
| `document_group.invite.reassign` | A field invite for this document group was reassigned |
| `document_group.invite.declined` | A field invite for this document group was declined |
| `document_group.invite.resend` | A field invite for this document group was resent |
| `document_group.invite.update` | A field invite for this document group was updated |
| `document_group.invite.cancel` | A field invite for this document group was canceled |
| `document_group.freeform.create` | A freeform invite for this document group was created |
| `document_group.freeform.signed` | A freeform invite for this document group was signed |
| `document_group.freeform.resend` | A freeform invite for this document group was resent to the same signer |
| `document_group.freeform.cancel` | A freeform invite for this document group was canceled |
| `document_group.invite.consent.agreed` | A signer agreed to the terms within a field invite with this document |
| `document_group.invite.consent.declined` | A signer declined their consent to the terms within a field invite with this document group |
| `document_group.invite.consent.withdrawn` | A signer withdrew their consent to the terms within a field invite with this document group |
| `document_group.invite.authentication.failed` | A signer's authentication failed for a field invite with this document group |
| `document_group.invite.email.delivery.failed` | An email with a field invite with this document group was not delivered |

## Additional options for webhooks

### HMAC security

SignNow allows API users to verify callbacks from SignNow API using HMAC Security algorithm. Once the HMAC secret key is configured for an event subscription, a new header is included in every callback URL. This verifies that the message has been sent using SignNow and has been delivered exactly the same as it was at the moment of sending.

#### HMAC mechanism setup

To setup HMAC mechanism for webhooks, please set the `secret_key` parameter when creating a webhook event. This key will be used to generate a specific signature header for each response from a triggered webhook in SignNow. (See Example 1. Create event subscription with HMAC secret key)

<!-- theme: info -->

> **Note**: SignNow doesn't issue the HMAC secret key: you create it yourself. Via API, pass any string of your choice (up to 300 characters) as `secret_key`. In the API Dashboard, enter your own key or click **Generate New Key**. Copy and save the key: you'll need it to verify the signature of incoming callbacks.

The signature header contains the original message body hashed with the HMAC key. To verify an event, the application validates the HMAC header using the provided `secret_key` and re-create the original message.

<!--
type: tab
title: Example 1. Create event subscription with HMAC secret key
-->

```json
curl --request POST \
  --url https://api.signnow.com/v2/event-subscriptions \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer {{access_token}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "event": "document.fieldinvite.sent",
    "entity_id": "63XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "attributes": {
      "callback": "https://some.callback.url/",
      "use_tls_12": true,
      "docid_queryparam": true,
      "headers": {
        "string_head": "test",
        "int_head": 12,
        "bool_head": false,
        "float_head": 12.24
      },
      "secret_key": "MySecretKey" // It enables HMAC security logic.
    }
  }'
```
<!-- type: tab-end -->

[`GET /v2/event-subscriptions`](/docs/manage-event-subscriptions/operations/get-v2-dashboard-event-subscriptions) request can be used to view the value of configured `secret_key`.

#### HMAC webhook verification

Once the event is created with a `secret_key` parameter, this secret key will be used to hash the webhook response body using HMAC algorithm. The hash value will be sent in `X-SignNow-Signature` HTTP header with each callback.

When the callback is received at your servers, you can use the `secret_key` to compute the HMAC hash value of the callback payload and compare it against the HMAC hash value in `X-SignNow-Signature` HTTP header to verify that the request was sent by SignNow. (See Example 2: Verification of the HMAC hash)

<!--
type: tab
title: Example 2. Verification of the HMAC hash
-->

```json
<?php
class HMAC_Service
{
    /*
     * Compute HMAC hash 
     * Useful reference: https://www.php.net/manual/en/function.hash-hmac.php
     */
    public static function ComputeHash($secret,$payload)
    {
        $hexHash = hash_hmac('sha256',$payload,utf8_encode($secret));
        $base64Hash = base64_encode(hex2bin($hexHash));
        return $base64Hash;
    }
    public static function HashIsValid($secret,$payload,$verify)
    {
        return hash_equals($verify, self::ComputeHash($secret,$payload));
    }
}
?>
```

<!-- type: tab-end -->

### Retries

Each callback delivery attempt has a 20-second timeout. If a callback returns an error, we will either email you or try sending a callback again, depending on the error type.

| Error type | Description | What we do |
|---|---|---|
| Unreachable host | We don't know if the error can be fixed soon. It may take several days or may never be fixed. | 1. We send 5 retries, 10 seconds apart.<br> 2. We send up to 2 more retries, each 4 hours apart.<br> 3. Before the last retry, we send you a warning email.<br> 4. If that retry also fails, we unsubscribe you from the webhook and send you a cancellation email. |
| 4xx HTTP error | The host is accessible but responds with a 4xx HTTP error status. There are no retries for 4xx errors — each new event triggers a new delivery attempt. If errors persist, we unsubscribe you from the webhook. | 1. If we get 10 or more errors within 10 minutes, we send you a warning email. The warning is sent once per subscription.<br> 2. If we get 30 or more errors within 60 minutes, we unsubscribe you from the webhook and send you a cancellation email. |
| 5xx HTTP error | 5xx HTTP errors can often be fixed quickly. We never unsubscribe you from the webhook for 5xx errors. | 1. We send 5 retries, 10 seconds apart. <br> 2. We send 5 more retries, each 4 hours apart. |

When creating a webhook, you can limit the number of retries for 5xx errors. To do so, use the `retry_count` attribute in the payload of the [Create event subscription request](/docs/manage-event-subscriptions/operations/create-event-subscription-2). The maximum number of retries is 10, and the minimum is 1.

**Example**

```json
{
  "event": "document.complete",
  "entity_id": "0f7848d0cfadeb2cdd230e4ad433efbca2423d8f",
  "attributes": {
    "callback": "https://example.com",
    "retry_count": 3
    }
}
```

### Webhook recovery

Even with retries in place, webhooks can occasionally be missed — for example, due to extended downtime, a misconfigured endpoint, or network issues on your side. Use the following best practices to keep your integration in sync.

- **Check your callback log.** Use [`GET /v2/event-subscriptions/{{subscription_id}}/callbacks`](/docs/callbacks-info/operations/get-v2-dashboard-event-history) to retrieve the list of callbacks sent for a specific subscription and verify which events were delivered.
- **Build reconciliation logic.** Compare received webhooks against expected events based on the current document status to identify and handle any gaps.
- **Log all incoming webhooks with timestamps.** Maintain a log of received callbacks for auditing and debugging purposes.
- **Contact support to retrigger specific callbacks.** If a critical webhook was missed and cannot be recovered through polling, reach out to SignNow support to have the callback retriggered for a specific event.

### Metadata in webhooks

Webhooks can transmit metadata attached to documents and document groups. The metadata is invisible to signers.

To use metadata with webhooks:

1. Add metadata to the [document](/docs/document/operations/put-document-document_id-metadata) or [document group](/docs/document-group/operations/put-v2-document-groups-document_group_id-metadata).
2. [Create](/docs/manage-event-subscriptions/operations/create-event-subscription-2) a webhook and include metadata to the payload by setting `include_metadata` to true.

When the event specified in the webhook is triggered and affects the document or document group, the payload will contain the metadata.

**Example**

<!--
type: tab
title: Add metadata
-->

```json

{
    "sales_rep": "Jane Doe",
    "source": "webhook"
}

```

<!--
type: tab
title: Webhook payload
-->

```json
{
    "meta": {
        "timestamp": 1728310375,
        "event": "user.document.open",
        "environment": "https://app.signnow.com/api",
        "callbackUrl": "https://webhook.site/ba2650c4-f8a3-4664-a42f-a1ea40b17bbc?Param={\"docId\":\"3cd9758f093545089954894be9da90af210741b0\"}",
        "accessToken": "********",
        "initiatorId": "646a5e78f4154a0880a596b11c21a95866ee66e2",
        "metadata": {
            "sales_rep": "Jane Doe",
            "source": "webhook"
        }
    },
    "content": {
        "documentId": "3cd9758f093545089954894be9da90af210741b0",
        "documentName": "Sales Agreement",
        "userId": "646a5e78f4154a0880a596b11c21a95866ee66e2",
        "viewerUserUniqueId": "646a5e78f4154a0880a596b11c21a95866ee66e2"
    }
}
```
<!-- type: tab-end -->

You can also view metadata attached to [documents](/docs/document/operations/get-document-document_id-metadata) and [document groups](/docs/document-group/operations/get-v2-document-groups-document_group_id-metadata).

### Callback delay

You can set up the delay between the event being triggered and a notification being sent. To do so, use the `delay` attribute in the payload of the  [Create event subscription](/docs/basic-auth/operations/create-event-subscription) request. The maximum delay time is 100 seconds.

**Example**

```json
{
  "event": "document.complete",
  "entity_id": "0f7848d0cfadeb2cdd230e4ad433efbca2423d8f",
  "attributes": {
    "callback": "https://example.com",
    "delay": 30
    }
}
```

## Troubleshooting

This section covers the most common webhook issues and how to diagnose them.

<!-- theme: info -->

> **Note**: Webhooks require an API free trial, an active API subscription, or a Site License.

<!-- theme: warning -->

> **Note**: An API subscription is separate from your SignNow business plan: an active Business or Enterprise plan does not automatically include API access. If the API Dashboard shows an upgrade screen when you create a webhook even though your API plan is active, contact API support at **api@signnow.com** to have your API subscription status checked.

### Where to check webhook logs

If a webhook didn't arrive or behaves unexpectedly, start with the logs:

- **API Dashboard**. Go to [API Dashboard > Webhooks > Events History](https://app.signnow.com/webapp/api-dashboard/web-hooks) to see every callback attempt for your subscriptions. Filter by event, entity type, response status code, or start time. Click an event entry to open **Event details** with the **Response status code** and **Response content** (error `code` and `message`) returned by your callback URL. For details, see [API Dashboard | SignNow](/docs/account#events-history).
- **Via API**. Use [`GET /v2/event-subscriptions/{{subscription_id}}/callbacks`](/docs/callbacks-info/operations/get-v2-dashboard-event-history) to retrieve the list of callbacks sent for a specific subscription. You can filter results by response status code, event, and date.

### Common issues

| Issue | Likely cause | What to do |
|---|---|---|
| Callbacks stopped arriving | SignNow unsubscribed you because your callback URL kept failing: an unreachable host after all [retries](/docs/guides-webhooks#retries), or 30+ `4xx` errors within 60 minutes. `5xx` errors never cause unsubscribing. A warning email is sent before, and a cancellation email after (see [API email notifications](/docs/account#api-email-notifications)). | Go to **API Dashboard** > **Webhooks** > **Subscriptions** and filter by **Status**. Fix your endpoint, reactivate or recreate the subscription, then recover missed events: see [Webhook recovery](/docs/guides-webhooks#webhook-recovery) and manual [Retries](/docs/account#retries). |
| Callbacks stopped arriving, subscriptions look active | Your API subscription became inactive or expired. API requests return `403` errors `80001003`, `80001005`, or `80001002`. | Check [API Dashboard > Plan usage](/docs/account#plan-usage). If your plan should be active, contact API support at **api@signnow.com**. |
| A specific event fails while others work | Each event is a separate subscription: one (for example, `document.fieldinvite.sent`) can be deactivated or unsubscribed while the rest keep working. Your endpoint may also fail on that event's payload structure. | Filter **Subscriptions** by event name and check the status. Review the response codes in **Events History** for that subscription. To isolate the issue, temporarily point the subscription to an online webhook test tool (for example, [Webhook.site](https://webhook.site)). |
| Duplicate callbacks | Multiple active subscriptions share the same entity and event (up to 20 are allowed with different callback URLs), or retries and manual resends delivered the same callback again. | Filter **Subscriptions** by event and entity ID and remove the extras. Make your handler idempotent: deduplicate incoming callbacks using the `meta.timestamp`, event name, and entity ID from the payload. |
| Can't manage a webhook (management actions are unavailable) | On a Site License, webhooks can only be managed by the user who created them. The subscription owner sees all webhooks but can't activate, deactivate, unsubscribe, or resend those owned by other users. See [Webhook ownership on a Site License](/docs/account#webhook-ownership-on-a-site-license). | Check the **Owner** column on the **Subscriptions** page. Ask the webhook owner to make the change, or create your own subscription for the same event. |

### Errors when creating a subscription

| Error | Code | What it means | What to do |
|---|---|---|---|
| `Active subscriptions are limited to 20 subscriptions with this combination of entityId and eventName.` | `15006044` | You've reached the maximum of 20 active subscriptions for the same entity and event. | Delete unused subscriptions for this entity and event, then retry. |
| `Active subscriptions must have different combinations of entityId, eventName, and callbackUrl.` | `15006045` | A subscription with the same entity, event, and callback URL already exists. | Use the existing subscription, or delete it first if you want to recreate it. |
| `You have reached the limit of event subscriptions.` | `80001006` | Accounts without an active API subscription (or a Site License) are limited to 10 active webhooks. | Delete or deactivate webhooks you no longer need, or upgrade to a paid API plan. |
| `Event subscription already exists.` | `15006002` | An identical subscription already exists. | Use the existing subscription. |
| `Host is not allowed.` | `15006001` | The callback URL points to a host that isn't accepted, for example `localhost` or a private IP address. | Use a publicly reachable callback URL. |
| `Unknown callback host or callback host unreachable.` | `15007029` | SignNow couldn't reach the callback host when validating the URL. | Verify the URL resolves publicly and your server or firewall accepts incoming requests from SignNow. |
| `Subscription to event is not allowed` | `15006009` | The bearer token doesn't belong to the user in `entity_id`, or the user is not the owner of the document or document group. | Create the subscription with the entity owner's access token. |
| `Your API subscription is inactive.` / `Your API subscription has expired.` | `80001003` / `80001005` | Webhooks require an active API subscription. | Check your plan in [API Dashboard > Plan usage](/docs/account#plan-usage). If your plan is active, contact API support at **api@signnow.com**. |
| `Not found entity with id = {entity_id}` | — | The user, document, or document group in `entity_id` doesn't exist or isn't available to this account. | Verify the entity ID. |

## Set up webhook at API Dashboard

You can create event subscriptions in bulk using the API Dashboard. Go to [API Dashboard / Webhooks](https://app.signnow.com/webapp/api-dashboard/web-hooks/subscriptions) and select **Create Webhook**. For more information, see [API Dashboard | SignNow](/docs/account#webhooks).

## Create webhook via API 

### Step 0. Before you begin

In order to create a subscription for user's event, first you need to:

- [Generate an access token](/docs/oauth2/operations/post__oauth2_token)

```json
curl --request POST \
  --url https://api.signnow.com/oauth2/token \
  --header 'Accept: application/json' \
  --header 'Authorization: Basic {{basic_authorization_token}}' \
  --header 'Content-Type: multipart/form-data' \
  --form 'username=username@signnow.com' \
  --form 'password=testpass' \
  --form 'grant_type=password' \
  --form 'scope=*'
```

- [Retrieve user ID](/docs/user/operations/get-user-info) of the user that will trigger the webhooks

```json
curl --request GET \
  --url https://api.signnow.com/user \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer {{access_token}}' \
```

- Create a publicly available **callback URL**.  This is the URL where your webhook listener will receive the event messages sent by SignNow when the webhook is triggered. For an end-to-end example, including a runnable callback server that verifies and processes the payload, see [Handling SignNow event callbacks](/docs/guides-handling-signnow-event-callbacks).

<!-- theme: info -->

> **Note**: For test purposes, you can use a URL from an online webhook test tool to receive and check the payload. You can use the tool like [Webhook.site](https://webhook.site/#!/5ce0f84e-7e51-4499-8458-aa33055d4371). Simply copy the automatically generated “Your unique URL” and insert in the payload of your POST request.

- Pick the event name from the list of entity events.

### [Step 1. Create webhooks for the most used events associated with the user](/docs/manage-event-subscriptions/operations/create-event-subscription-2)

Let's create a subscription for two different events:

<!-- theme: info -->

> **Note**: Each event subscription is a separate POST request.

- `user.document.fieldinvite.sent` - commonly used when you need to track that the invite has been sent for signature.

```json
curl --request POST \
  --url https://api.signnow.com/v2/event-subscriptions \
  --header 'Accept: application/json, ' \
  --header 'Authorization: Bearer {{access_token}}' \
  --header 'Content-Type: application/json' \
  --data '{
  "event": "user.document.fieldinvite.sent",
  "entity_id": "{{user_id}}",
  "attributes": {
    "callback": "{{callbak_url}}"
  }
}'
```

- `user.document.fieldinvite.signed`- commonly used when you need to create a workflow regarding a signed invite.

```json
curl --request POST \
 --url https://api.signnow.com/v2/event-subscriptions \
 --header 'Accept: application/json, ' \
 --header 'Authorization: Bearer {{access_token}}' \
 --header 'Content-Type: application/json' \
 --data '{
  "event": "user.document.fieldinvite.signed",
  "entity_id": "{{user_id}}",
  "attributes": {
    "callback": "{{callbak_url}}"
  }
}'
```

### [Step 2. Get the list of webhook event subscriptions](/docs/manage-event-subscriptions/operations/get-v2-dashboard-event-subscriptions)

Get the list of webhook events subscriptions that you had subscribed to.

```json
curl --request GET \
  --url https://api.signnow.com/v2/event-subscriptions \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer {{access_token}}' \
  --header 'Content-Type: application/json'
```

**Response example**

```json
{
    "data": [
        {
            "id": "b3XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            "entity_type": "user",
            "event": "user.document.fieldinvite.sent",
            "entity_id": 126390148,
            "entity_unique_id": "b2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            "request_method": "post",
            "action": "callback",
            "active": true,
            "json_attributes": {
                "use_tls_12": false,
                "docid_queryparam": false,
                "callback_url": "http://example.com/"
            },
            "application_name": "Sample App",
            "version": 2,
            "created": 1688128984
        }
    ],
    "meta": {
        "pagination": {
            "total": 3,
            "count": 3,
            "per_page": 15,
            "current_page": 1,
            "total_pages": 1,
            "links": []
        }
    }
}
```

### [Step 3. Send and sign the field invite to test the event](/docs/document-field-invite/operations/post-field_invite)

Create a field invite to test the event `user.document.fieldinvite.sent`. After you receive the signature request, open the email and sign the field invite via web UI.

```json
curl --request POST \
  --url https://api.signnow.com/document/{{document_id}}/invite \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer {{access_token}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "document_id": "{{document_id}}",
    "to": [
      {
        "email": "{{signer}}",
        "role": "Signer 1",
        "role_id": "{{role_id_1}}",
        "order": 1,
        "reassign": "1",
        "decline_by_signature": "0",
        "reminder": {
          "remind_after": 1
        },
        "expiration_days": 15
      }
    ],
    "from": "{{user}}",
    "cc_step": []
  }'
```

### Step 4. Check the webhook request at your Callback URL

You should receive two callbacks with the event payloads.

**Example 1 with `user.document.fieldinvite.sent`**:

```json
{
  "meta": {
    "timestamp": 1661430933,
    "event": "user.document.fieldinvite.sent",
    "environment": "https://example.com",
    "callback_url": "http://example.com/handle?hash=XXXXXXXX&Param={\"docId\":\"b9XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"}",
    "access_token": "********",
    "initiator_id": "b2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  },
  "content": {
    "document_id": "b9XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "document_name": "Sample document",
    "user_id": "b2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  }
}
```

**Example 2 with `user.document.fieldinvite.signed`**:

```json
{
  "meta": {
    "timestamp": 1661430936,
    "event": "user.document.fieldinvite.signed",
    "environment": "https://example.com",
    "callback_url": "http://example.com/handle?hash=XXXXXXXX&Param={\"docId\":\"b9XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"}",
    "access_token": "********",
    "initiator_id": "b2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  },
  "content": {
    "document_id": "b9XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "document_name": "Sample document",
    "user_id": "b2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  }
}
```

Another way to get the callbacks and their payloads is by sending an [API request](/docs/callbacks-info/operations/get-v2-dashboard-event-history).

```json
curl --request GET \
  --url https://api.signnow.com/v2/event-subscriptions/{{subscription_id}}/callbacks \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer {{access_token}}' \
  --header 'Content-Type: application/json'
```

### [Step 5. Delete event subscription](/docs/manage-event-subscriptions/operations/delete-v2-event-subscriptions-subscription_id)

To finish working with the test data, unsubscribe from the webhook.

```json
curl --request DELETE \
  --url https://api.signnow.com/v2/event-subscriptions/{{subscription_id}}  \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer {{access_token}}' 
```

### [Step 6. Check your webhook event log at the API Dashboard/Webhooks](/docs/account#webhooks)

At the **API Dashboard** -> **Webhooks** -> **Events History** page, you can see subscription information and the list of all events under selected Webhook. To get detailed information for the event (Event details) click on its line. Check you webhook subscription [here](https://app.signnow.com/webapp/api-dashboard/web-hooks).


### Try out in Postman

[Access](https://www.postman.com/signnow-api/workspace/signnow-public-collection/collection/24778743-12de04ca-0d9a-47c7-8c9c-8ba14ffcfb41?action=share\&creator=24778743) this flow in Postman, and feel free to add event subscriptions to your workflow.

For more information, check out our video tutorial.

https://youtu.be/Knd_3VeqtJc?si=Udco07jZOe9yt_0C


---
*Full page: https://docs.signnow.com/docs/guides-webhooks*
