# Links

A consent link is a pre-authenticated URL that creates a consent event when it gets accessed from a browser. Consent links can be used to show or send users links that they can click to update their consent status. This includes use cases like unsubscribing from all communications in an email, sending a confirmation email with an action button, etc.

We support two types of authorization for consent links:

* [Pre-authorized](#pre-authorized-consent-link): Consent links are pre-created by calling the Didomi API and include a unique signed token in the URL. This requires an API request to create the consent link. This is the recommended way to create consent links.
* [Digest](#consent-links-with-digest-authorization): Consent links are created on-the-fly and include a unique hash digest or HMAC signature to authenticate them. This does not require a request to the Didomi API and consent links can be generated entirely on your server. This is useful for environments where sending HTTP requests is complicated (emailing providers, for instance).

## Consent links with pre-authorization

To create a consent link for a user, send a POST request to `https://api.didomi.io/consents/links?organization_id=<ID of your organization>` and specify the following parameters in the body:

| Property               | Description                                                                                                                                                     |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| organization\_user\_id | Organization user ID that a consent event should be created for when the link gets executed                                                                     |
| action                 | Action to execute when a user loads the consent link in a browser. Must be `event.create` or `event.update`.                                                    |
| event                  | The[consent event](https://developers.didomi.io/api-and-platform/consents/events) to create or update when a user loads the consent link in a browser.          |
| redirect\_url          | The URL to redirect the user to after loading the consent link and executing the action. This allows the user to end up on a page that you own.                 |
| lifetime               | Lifetime of the consent link in seconds. The consent link automatically expires after that duration and becomes unusable. Defaults to 15 minutes (900 seconds). |

Example:

```javascript
POST https://api.didomi.io/consents/links?organization_id=<ID of your organization>
{
    "organization_user_id": "<User ID>",
    "action": "event.create",
    "event": {
        "consents": {
            "purposes": [
                ...Update to purposes
            ]
        }
    },
    "redirect_url": "https://www.ourwebsite.com"
}
```

The API will respond with the created link in the `url` field:

```javascript
{
    "organization_user_id": "<User ID>",
    "action": "event.create",
    "event": {
        "consents": {
            "purposes": [
                ...Update to purposes
            ]
        }
    },
    "redirect_url": "https://www.ourwebsite.com",
    "url": "https://api.privacy-center.org/consents/execute/..."
}
```

The created link includes a unique token. When loaded in a browser, the corresponding event will be created or updated without any other authentication required.

The `/consents/links` endpoint of the API is used to create consent links.\
For a full reference of the endpoint and the resources that it returns, visit <https://api.didomi.io/docs/>.

### Action and event

When executing a consent link, the Didomi API will execute the action that is defined in the `action` parameter of the consent link. That action can be either creating a new consent event (`event.create`) or updating an existing consent event (`event.update`).

#### Creating an event

The event to create must be specified in the `event` parameter. The event schema is the standard [Didomi consent event schema](https://developers.didomi.io/api-and-platform/events#event-schema).

For instance, to unsubscribe a user from a purpose, you could send the following JSON event:

```javascript
{
    "consents": {
        "purposes": [{
            "id": "purpose_id",
            "enabled": false
        }]
    }
}
```

Any event that can be created through the regular `POST /consents/events` API can be created with a consent link with the same structure.

#### Updating an event

The event to update must be specified in the `event` parameter. The event schema is the standard [Didomi consent event schema](https://developers.didomi.io/api-and-platform/events#event-schema). An `id` field must be specified with the ID of an existing consent event to update. The other properties specified in the `event` parameter will be merged into the event.

For instance, to confirm an event that was previously in status `pending_approval`, you could send the following object:

```javascript
{
    "id": "ddd2a1cd-589d-4f44-98f5-0b828a1c2a36",
    "status": "confirmed"
}
```

## Consent links with digest authorization

Digest authorization allows you to specify all the parameters of a consent link (organization user ID, event to create/update, etc.) in the query-string parameters of a URL.\
To authorize that request, you must add a digest computed from the organization user ID and [a secret shared with Didomi](https://developers.didomi.io/api-and-platform/consents/secrets). This ensures that the request originates from your servers and cannot be freely created.

When using digest authorization, you must build the consent link URL yourself from scratch. The base of the URL is [`https://api.privacy-center.org/v1/consents/execute`](https://api.privacy-center.org/v1/consents/execute) to which you can add the query-string parameters that form your consent link.\
\
Example of a consent link with digest authorization:\
<https://api.privacy-center.org/v1/consents/execute?key=fe295974-e126-49a4-9d6f-84bc5884c298&auth_algorithm=hash-md5&auth_sid=secret-id&auth_digest=e067d565e248267d5c3dd2f82409f5e3&auth_salt=salt&organization_user_id={organization_user_id}&action=event.create&event=%7B%22consents%22%3A%7B%22purposes%22%3A%5B%7B%22id%22%3A%22purpose_id%22%2C%22enabled%22%3Afalse%7D%5D%7D%7D&redirect_url=https%3A%2F%2Fwebsite.com>

This link is composed of the following parameters:

| Parameter                 | Description                                                                                                                                                                                 |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `key`                     | The Public API key of your organization (from the Console).                                                                                                                                 |
| `auth_algorithm`          | The method and algorithm used for generating the digest.                                                                                                                                    |
| `auth_sid`                | ID of the secret used for generating the digest.                                                                                                                                            |
| `auth_digest`             | Digest computed from the organization user ID and secret value.                                                                                                                             |
| `auth_salt` (optional)    | The salt used for computing the digest.                                                                                                                                                     |
| `organization_user_id`    | The organization user ID for which an event will be created or updated                                                                                                                      |
| `action`                  | The action to run when executing the consent link. This could be either `event.create` (for creating an event) or `event.update` (for updating an existing event).                          |
| `event`                   | The event to create or update as URL-encoded JSON object. If the event is being updated (action is `event.update`), an `id` field must be provided to indicate what event is being updated. |
| `redirect_url` (optional) | The URL to redirect to after executing the consent link. No redirect URL will show a blank page to the user.                                                                                |

Read on for more information on every parameter and how they are built.

### Digest

#### Digest and algorithm (auth\_algorithm and auth\_digest)

The digest is a hex-encoded string computed by running a hash or HMAC algorithm on the concatenated `organization_user_id` and `secret`. The digest must be provided in the `auth_digest` query-string parameter of the consent link.

For example and assuming your organization user ID is `user@domain.com` and your secret value is `secret_value`, you could compute a MD5 hash digest as MD5(`user@domain.comsecret_value`) = `2d7d57c0b588a5c4bc508b17ace5fd7e`. Note that there is no separator between the organization user ID and the secret.

We support the following digest types and algorithms:

| Type | Algorithm | ID (auth\_algorithm) |
| ---- | --------- | -------------------- |
| Hash | MD5       | `hash-md5`           |
| Hash | SHA1      | `hash-sha1`          |
| Hash | SHA256    | `hash-sha256`        |
| HMAC | SHA1      | `hmac-sha1`          |
| HMAC | SHA256    | `hmac-sha256`        |

We recommend using Hash / SHA256 or HMAC / SHA256 if possible. The algorithm that you will be using must be provided in the `auth_algorithm` query-string parameter of the consent link.

#### Secret (auth\_secret)

The digest is used as a proof that the consent link was created by your organization and not by a third-party generating a consent link for your users without authorization. For the digest to be a valid proof, it needs to include a unique secret value only known by Didomi and your organization.\
When the Didomi API receives a consent link with a digest, it re-computes the digest and compares it with the provided digest. If the digests match, the consent link was created by an organization that knows the secret value associated with the consent link.

For Didomi to be able to compute the digest, you must specify the ID of the secret value that was used for computing the digest on your side. To do so, specify the `auth_sid` query-string parameter with the ID (not the secret value itself) of the secret used for the digest.

You can create and manage secrets by [reading our documentation](https://developers.didomi.io/api-and-platform/consents/secrets).

#### Salt (auth\_salt) - Optional

To further improve the security of the secret, you can include a random unique salt in every consent link that you create. The digest should then be computed on the organization user ID, the secret, and the salt.

For example and assuming your organization user ID is `user@domain.com` , your secret value is `secret_value`, and your salt is `salt`, you could compute a MD5 hash digest as MD5(`user@domain.comsecretsalt`) = `e067d565e248267d5c3dd2f82409f5e3`. Note that there is no separator between the organization user ID, the secret, and the salt.

The salt must be provided in plain-text in the `auth_salt` query-string parameter of the consent link. The salt is not secret and it is safe to pass it unencrypted. The salt is present to increase the uniqueness of the digest and make it harder for attackers to guess the secret with [pre-computed hash attacks](https://en.wikipedia.org/wiki/Salt_\(cryptography\)).\
We recommend generating a new random salt for every consent link that you create.

### Action and event

When executing a consent link, the Didomi API will execute the action that is defined in the `action` query-string parameter of the consent link. That action can be either creating a new consent event (`event.create`) or updating an existing consent event (`event.update`).

#### Creating an event

The event to create must be specified as a URL-encoded JSON consent event in the `event` query-string parameter. The event schema is the standard [Didomi consent event schema](https://developers.didomi.io/api-and-platform/events#event-schema).

For instance, to unsubscribe a user from a purpose, you could send the following JSON event:

```javascript
{
    "consents": {
        "purposes": [{
            "id": "purpose_id",
            "enabled": false
        }]
    }
}
```

URL-encoded to fit in a query string, you would get:

```javascript
%7B%22consents%22%3A%7B%22purposes%22%3A%5B%7B%22id%22%3A%22purpose_id%22%2C%22enabled%22%3Afalse%7D%5D%7D%7D
```

Any event that can be created through the regular `POST /consents/events` API can be created with a consent link with the same structure.

#### Updating an event

The event to update must be specified as a URL-encoded JSON consent event in the `event` query-string parameter. The event schema is the standard [Didomi consent event schema](https://developers.didomi.io/api-and-platform/events#event-schema). An `id` field must be specified with the ID of an existing consent event to update. The other properties specified in the `event` parameter will be merged into the event.

For instance, to confirm an event that was previously in status `pending_approval`, you can could send the following JSON:

```javascript
{
    "id": "ddd2a1cd-589d-4f44-98f5-0b828a1c2a36",
    "status": "confirmed"
}
```

## Redirection

You can provide a URL to redirect the user to after executing the action via the `redirect_url` query-string parameter for digest authorization, and via the `redirect_url` body parameter for pre-authorization.

If an error happens while executing the action, Didomi will append an `error` query-string parameter to the redirection URL. The `error` parameter will contain an error code and can be used to show an error message to the user to let them know that their action has failed.

#### **Example**

If the provided redirect URL is `https://www.ourwebsite.com/consent-updated`, then:

* Didomi will redirect to `https://www.ourwebsite.com/consent-updated` if the action is successful
* Didomi will redirect to `https://www.ourwebsite.com/consent-updated?error=[ERROR CODE]` if the action fails to execute

### **Error codes**

The `error` query-string parameter will contain one of the following error codes:

| Code                | Description                                                                                                                                       | Link type        |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| MISSING\_OID        | The `organization_id` parameter is missing.                                                                                                       | Digest           |
| MISSING\_SID        | The `auth_sid` parameter is missing.                                                                                                              | Digest           |
| INVALID\_SID        | The `auth_sid` parameter is not a valid secret ID. Double check that the secret exists on the Didomi platform and that the ID is valid.           | Digest           |
| INVALID\_ALG        | The `auth_algorithm` parameter is invalid. Ensure that it is one of the values listed in our documentation.                                       | Digest           |
| INVALID\_DIGEST     | The `auth_digest` parameter provided does not match the digest that we computed. Ensure that the secret, algorithm, and salt are all valid.       | Digest           |
| MISSING\_ACTION     | The `action` query-string parameter is missing.                                                                                                   | Digest           |
| MISSING\_OUID       | The `organization_user_id` query-string parameter is missing.                                                                                     | Digest           |
| INVALID\_OUID       | The organization user ID provided in the`organization_user_id` query-string parameter is invalid. The action will still be executed in this case. | Digest           |
| MISSING\_EVENT      | The `event` query-string parameter is missing.                                                                                                    | Digest           |
| INVALID\_EVENT      | The data provided in the `event` query-string parameter is not a valid JSON string.                                                               | Digest           |
| MISSING\_EVENT\_ID  | The event provided does not include an event ID (if the action is `event.update`).                                                                | Digest, Pre-auth |
| UNKNOWN             | An unknown error happened.                                                                                                                        | Digest, Pre-auth |
| UNSUPPORTED\_ACTION | The action provided is not supported. We currently support `event.create` and `event.update` actions.                                             | Digest, Pre-auth |
| MISSING\_TOKEN      | An action token must be provided in the URL.                                                                                                      | Pre-auth         |
| INVALID\_TOKEN      | The token provided in the URL is not a valid JWT token created by the Didomi platform.                                                            | Pre-auth         |
