> For the complete documentation index, see [llms.txt](https://developers.didomi.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.didomi.io/integrations/generic-integrations/webhooks.md).

# Webhooks

Webhooks allow your organization to subscribe to events happening on the Didomi platform to implement custom workflows when your end-users change their consent preferences. When end-users make choices on your websites, mobile apps, or preference centers, you will receive a notification allowing you to react to these choices.

When an event is triggered, Didomi will send an HTTP POST payload to the configured webhook endpoint. Webhooks are configured at the organization level and automatically apply to all consent events triggered within your organization, on all websites, mobile apps, and preference centers.

{% hint style="warning" %}
Webhooks are enabled for GDPR events by default but are available for non-GDPR regulations at your organization's request (i.e. multi-regulation events). Contact your Didomi representative to enable multi-regulation events.

Once multi-regulation events are enabled for webhooks, your organization will receive events for all regulation types, not just GDPR. If your organization maps regulation events to a single contact record without distinguishing between them, a non-GDPR event, such as a CPRA event, can silently overwrite GDPR consent for the same contact.
{% endhint %}

## Configuration

Webhooks can be configured from the Didomi Marketplace. Once enabled, go to the *Manage* subsection under the Marketplace to configure your webhook.

Alternatively, you can reach out to our support team if you need further assistance. Provide the endpoint to send events to and, optionally, the OAuth credentials (client ID and client secret) to use.

To ensure that consent events are received when your endpoint is down, we retry at least five times every five minutes before moving on.

After the maximum number of retries is reached, the event is placed in a permanent storage for later processing.

### Authentication

#### OAuth Access Token

Requests sent to your API endpoint can be authenticated via [OAuth Client Credentials grant](https://oauth.net/2/grant-types/client-credentials/).

The Didomi servers will authenticate against your OAuth authorization server with a Client ID and a Client Secret that you provide to obtain an Access Token.

Didomi will then call your API endpoint for sending events with the Access Token provided in the `Authorization` header as a Bearer token.

#### IP address

API calls from Didomi will originate from the IP `35.159.1.63`. You must whitelist that IP to allow traffic from it for events to be sent.

## Payload

Events sent to your HTTP endpoints are sent as JSON-encoded objects with the following information:

<table><thead><tr><th width="148">Field</th><th width="140">Data type</th><th>Description</th></tr></thead><tbody><tr><td><code>type</code></td><td>String</td><td>The type of event.</td></tr><tr><td><code>parameters</code></td><td>Object</td><td>Entities affected by the event.</td></tr><tr><td><code>regulation</code></td><td>String</td><td>The regulation to which the event belongs.</td></tr></tbody></table>

## Events

| `Type`          | Description                                | `Parameters`                                                                                                                                                                                                                                                                                                                                                                 |
| --------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `event.created` | A new consent event has been created       | <ul><li><code>entity</code>: Created <a href="/pages/-LexpTSc8MeACh6tMW46#event-schema">Event</a></li></ul>                                                                                                                                                                                                                                                                  |
| `event.updated` | An existing consent event has been updated | <ul><li><code>source</code></li><li><code>old\_entity</code>: <a href="/pages/-LexpTSc8MeACh6tMW46#event-schema">Event</a> before it gets updated</li><li><code>new\_entity</code>: <a href="/pages/-LexpTSc8MeACh6tMW46#event-schema">Event</a> after the update</li></ul>                                                                                                  |
| `event.deleted` | An existing consent event has been deleted | <ul><li><code>entity</code>: Deleted <a href="/pages/-LexpTSc8MeACh6tMW46#event-schema">Event</a></li></ul>                                                                                                                                                                                                                                                                  |
| `user.created`  | A new user has been created                | <ul><li><code>entity</code>: Created <a href="/pages/-LcAr3fzXxjJl_zHJgRA#user-schema">User</a></li></ul>                                                                                                                                                                                                                                                                    |
| `user.updated`  | An existing user has been updated          | <ul><li><code>source</code>: Event that triggered the <a href="/pages/-LcAr3fzXxjJl_zHJgRA#user-schema">User</a> update (if any)</li><li><code>old\_entity</code>: <a href="/pages/-LcAr3fzXxjJl_zHJgRA#user-schema">User</a> before it gets updated</li><li><code>new\_entity</code>: <a href="/pages/-LcAr3fzXxjJl_zHJgRA#user-schema">User</a> after the update</li></ul> |
| `user.deleted`  | An existing user has been deleted          | `entity`: Deleted [User](/api-and-platform/consents/users.md#user-schema)                                                                                                                                                                                                                                                                                                    |

The payload is a JSON string in the body of the HTTP request. Examples:

```javascript
{
  "type": "user.updated",
  "parameters": {
    "source": {
      "id": "unique_event_id",
      "created_at": "2019-08-07T10:45:11Z",
      ...
    },
    "old_entity": {
      "id": "didomi_user_id",
      "organization_user_id": "organization_user_id",
      ...
    },
    "new_entity": {
      "id": "didomi_user_id",
      "organization_user_id": "organization_user_id",
      ...  
    }
  }
}
```

```javascript
{
  "type": "event.deleted",
  "parameters": {
    "entity": {
      "id": "deleted_event_id",
      "created_at": "2019-08-07T10:45:11Z",
      ...
    }
  }
}
```

### Filters

You can customize which events your webhook will receive by selecting the desired event types in the Didomi Marketplace. If no event types are selected, the webhook will receive **all** available events by default.

### Flatten request body

By enabling this option in the interface, your webhook payload will be transformed into a flat JSON object, simplifying property mapping depending on your webhook use case. Flattening converts a JSON object into a flat key-value format, where each key represents a property in the original JSON using a double underscore (`__`) as a separator. Currently, only the `entity` and `new_entity` properties are flattened, merging into a single `entity` property for simplicity.

**Example**

```json
// event.created (original)
{
  "type": "event.created",
  "parameters": {
    "entity": {
      "organization_id": "didomi",
      "user": {
        "id": "some_unique_id",
        "organization_user_id": "example@didomi.io"
      },
      "consents": {
        "purposes": [
          {
            "id": "geolocation_data",
            "enabled": true
          },
          {
            "id": "market_research",
            "enabled": true
          }
        ]
      }
    }
  }
}
```

```json
// event.created (Flattened)
{
  "type": "event.created",
  "parameters__entity__organization_id": "didomi",
  "parameters__entity__user__id": "some_unique_id",
  "parameters__entity__user__organization_user_id": "example@didomi.io",
  "parameters__entity__consents__purposes__geolocation_data__enabled": true,
  "parameters__entity__consents__purposes__market_research__enabled": true
}
```

### Pending events

Pending events (with status `pending_approval` or similar) are always sent as `event.created` webhooks.

However, new pending events only generate `user.created` events if a new user is created as a result of a pending event. If a pending event applies to an existing user, a `user.updated` event is **not generated** as the user is not effectively modified until the event becomes confirmed.

When a pending event becomes confirmed and, assuming it contains changes that effectively modify the status of the user, then and only then a `user.updated` event is sent.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers.didomi.io/integrations/generic-integrations/webhooks.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
