Consent store integration via REST API
This section explains how to record consents in the consent archive, which you need to store proof of the consent to personal data processing that users may have knowingly given while browsing your website.
This documentation describes the endpoints for managing consents within web spaces. The base URL of the API is
https://api.avacy.eu/:team/v4
Create a new consent for a specific web space
POST /webspaces/:id/consents
Route parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | The identifier of the web space on which the consent is created |
Authentication
The request requires an Access Key, sent in the Authorization: Bearer <token> header.
How to get the Access Key
- Log in to Avacy and open the web space on which you want to record consents.
- At the top right, click web space settings and then Avacy integration on your web space.
- Open the Access Keys tab and create a new access key, give it a name so you can recognize it (e.g. "WordPress plugin") and copy the code shown.
The code is shown only once: keys that have already been created are no longer visible. Only the most recently created key for the web space is valid: earlier keys are rejected with 403. If you generate a new one, update it everywhere it is used. If you delete the most recently created key, the previous one (if it still exists) becomes valid again.
A key is valid only for the web space it was generated for and does not expire.
Keep the Access Key on your server and call the API from there. Do not put it in your site's JavaScript: anyone who opens the page could read it and record consents on your behalf.
Recording consents requires a plan that includes the consent archive. Otherwise the request is rejected with 403, for both form and banner.
Required headers
| Name | Type | Required | Description |
|---|---|---|---|
Authorization | string | Yes | Bearer <token>, where <token> is the web space Access Key (see Authentication) |
Accept | string | Yes | Specifies the desired response format (application/json) |
Content-Type | string | Yes | Specifies the request content format (application/json) |
Request parameters (JSON format)
| Name | Type | Required | Description |
|---|---|---|---|
consent_type | string | Yes | The type of consent: form or banner |
optin | string | Yes | Consent status: accepted or rejected |
identifier | string | No | Unique identifier of the subject providing consent |
ip_address | string | Yes for form | Required for forms. The contact's IP, not your server's. If it is not a valid IP address, the IP the call comes from is recorded |
consent_features | array or string | Yes for form | Purposes of the consent, as an array of strings. In Avacy forms privacy_policy and cookie_policy are always present, because the form cannot be submitted without them; the API does not enforce them, so in your own form include only the entries the user actually accepted. The other entries (for example newsletter or tracking) are optional and can be revoked. Form data (name, email, phone…) goes in consent_data, not in consent_features. Also accepts a comma-separated string ("privacy_policy,cookie_policy,newsletter") |
consent_data | array or string | Yes for form | Consent data with label/value structure. Also accepts a string ("name=Mario,email=x") |
uuid | string | No | Consent identifier in UUID format. If omitted, Avacy generates it. Keep it if you need to revoke the consent (see Consent revocation) |
source | string | No | Source of consent (e.g. "website", "app") |
html_form | string | No | HTML representation of the consent form shown to the user |
versions | array | No | Not used |
- The recorded versions are those of the policies (privacy and cookie) generated by Avacy on the web space. If you use an external policy, include its details in
consent_data. - With
consent_type: bannerthe Access Key is not needed: Avacy checks that theOriginorRefererheader matches a domain of the web space. If both headers are missing the response is400; if neither matches, it is403. This check runs only in production. The Bearer token is required forform. - The Avacy banner also sends other
optinvalues (consent-all,reject-all,save-preferences,close-banner): they are internal to the banner and must not be used in integrations.
Example:
{
"consent_type": "form",
"optin": "accepted",
"ip_address": "192.168.1.20",
"consent_data": [
{
"label": "name",
"value": "Mario"
},
{
"label": "surname",
"value": "Rossi"
}
],
"identifier": "user-123",
"source": "website",
"consent_features": [
"privacy_policy",
"cookie_policy",
"newsletter"
],
"html_form": "<p>We use cookies and other technologies...</p>",
"uuid": "550e8400-e29b-41d4-a716-446655440000"
}
Successful Response
Code: 201 Created
{
"message": "Consent created successfully",
"data": {
"id": 123,
"webspace_id": 1,
"ip_address": "192.168.1.20",
"consent_type": "form",
"optin": "accepted",
"consent_data": [
{
"label": "name",
"value": "Mario"
},
{
"label": "surname",
"value": "Rossi"
}
],
"versions": [
{
"slug": "privacy_policy",
"link": "https://assets.example.com/policies/.../privacy_policy.html",
"date": "2025-05-15"
}
],
"identifier": "user-123",
"domain": null,
"source": "website",
"consent_features": [
"privacy_policy",
"cookie_policy",
"newsletter"
],
"html_form": "<p>We use cookies and other technologies...</p>",
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"created_at": "2025-11-12T10:30:00.000000Z",
"updated_at": "2025-11-12T10:30:00.000000Z"
}
}
domain contains the request's Origin header (or Referer if Origin is missing). It is null if you call from your own server without these headers. In versions, date is the date and time the consent was recorded.
Error Response
| Code | When |
|---|---|
400 Bad Request | banner only: both Origin and Referer are missing |
403 Forbidden | Access Key missing or invalid (including a key replaced by a more recent one, or generated for another web space); for banner, a domain that doesn't belong to the web space; or a plan without the consent archive |
404 Not Found | The web space with the specified ID does not exist. You can't get this error with form: an id that doesn't match the key's web space returns 403 first |
422 Unprocessable Entity | Required fields are missing or invalid |
Listing, export and import
The Access Key API is for recording consents. Listing, searching, exporting and importing are done in the SaaS, under Consent archive. Instructions are in the Help Center.
Consent revocation
There is no dedicated revocation endpoint. A consent is revoked by recording a new consent with POST /webspaces/:id/consents, as the Avacy banner does:
- Keep the
uuidyou receive in the response when the consent is created. - To revoke, send a new
POSTwith the sameuuidand the sameidentifier. Inconsent_features, put the entries that are still valid (for exampleprivacy_policyandcookie_policy), leaving out the revoked ones. Keepoptinset toaccepted:consent_featurestells what was revoked. The other fields that are required forform(ip_address,consent_data) must be sent as in a creation.
For example, if the initial consent had ["privacy_policy", "cookie_policy", "newsletter"], the newsletter revocation is recorded like this. Compared to the original consent, only consent_features changes:
{
"consent_type": "form",
"optin": "accepted",
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"identifier": "user-123",
"consent_features": ["privacy_policy", "cookie_policy"]
}
The API creates a new record with the same uuid (201); the previous one stays in the archive as history and proof. The current consent is the one from the record with the highest id among those with the same uuid (records created close together can have the same created_at).
Do not delete the previous consent to record a revocation: deleting it also removes the proof of the earlier choice.