Skip to main content

Consent store integration via REST API


This section explains how to integrate and query 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

POST /webspaces/:id/consents

Route parameters​

NameTypeRequiredDescription
idintegerYesThe 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

  1. Log in to Avacy and open the web space on which you want to record consents.
  2. At the top right, click web space settings and then Avacy integration on your web space.
  3. 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.
warning

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.

Recording consents requires a plan that includes the consent archive. Otherwise the request is rejected with 403, for both form and banner.

Required headers​

NameTypeRequiredDescription
AuthorizationstringYesBearer <token>, where <token> is the web space Access Key (see Authentication)
AcceptstringYesSpecifies the desired response format (application/json)
Content-TypestringYesSpecifies the request content format (application/json)

Request parameters (JSON format)​

NameTypeRequiredDescription
consent_typestringYesThe type of consent: form or banner
optinstringYesConsent status: accepted, rejected or partially_accepted
identifierstringNoUnique identifier of the subject providing consent
ip_addressstringYes for formRequired for forms. The recorded IP is the one the call comes from: if you call from your own server, report the contact's IP in consent_data
consent_featuresarray, object or stringYes for formPurposes of the consent. As an array it lists the purposes for which consent was given. As an object it assigns each purpose its status, true (accepted) or false (refused or revoked): {"phone": true, "whatsapp": false}. Also accepts a comma-separated string ("a,b")
consent_dataarray or stringYes for formConsent data with label/value structure. Also accepts a string ("name=Mario,email=x")
uuidstringNoConsent identifier in UUID format. If omitted, Avacy generates it. Keep it if you need to revoke the consent (see Consent revocation)
sourcestringNoSource of consent (e.g. "website", "app")
html_formstringNoHTML representation of the consent form shown to the user
versionsarrayNoNot used
note
  • 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: banner the Access Key is not needed: Avacy checks that the Origin or Referer header matches a domain of the web space. If both headers are missing the response is 400; if neither matches, it is 403. This check runs only in production. The Bearer token is required for form.
  • The Avacy banner also sends other optin values (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"
],
"html_form": "<p>We use cookies and other technologies...</p>",
"uuid": "550e8400-e29b-41d4-a716-446655440000"
}

To also record the refused purposes, pass consent_features as an object, with one entry for each purpose:

"consent_features": {
"phone": true,
"whatsapp": false,
"email": true
}

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"
],
"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​

CodeWhen
400 Bad Requestbanner only: both Origin and Referer are missing
403 ForbiddenAccess 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 FoundThe 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 EntityRequired fields are missing or invalid

Listing, export, import and deletion​

These endpoints work on the same web space (/webspaces/:id/consents) and require dashboard authentication: the Access Key is not accepted.

List consents​

GET /webspaces/:id/consents

Paginated response, sorted by creation date descending. Filters available as query string:

ParameterDescription
identifierPartial match on the identifier
uuidPartial match on the UUID
typeform or banner
optinaccepted, rejected or partially_accepted
start, endCreation date range (YYYY-MM-DD)
consent_featuresCase-insensitive partial match on the purposes
domainPartial match on the originating domain
limitResults per page (default 15)

Export​

GET /webspaces/:id/consents/export

Returns a .tsv file. It accepts the same filters as the list (except domain) and the ids parameter with comma-separated consent IDs. In the Optin column, accepted is exported as Yes and every other value as No, so partially_accepted can't be distinguished from rejected.

Import​

POST /webspaces/:id/consents/import

Send a csv, tsv or txt file (max 10 MB) in the file field as multipart/form-data. Required columns: Identifier, Consent Type, IP Address, Created At, plus Optin. Invalid rows are skipped and reported in the errors field of the response.

  • IP Address accepts IPv4 addresses only: rows with an IPv6 address are skipped.
  • Optin is imported as accepted only for yes, true, 1, accepted, sì or si. Any other value, including partially_accepted, is imported as rejected.
  • The response is 200 if at least one row is imported, otherwise 422.

Deletion​

EndpointDescription
DELETE /webspaces/:id/consents/:consent_idDeletes one consent
DELETE /webspaces/:id/consents/deleteDeletes the consents listed in consent_ids (an array in the request body). Returns 400 if the array is empty and 404 if no ID matches
DELETE /webspaces/:id/consentsBulk-deletes the consents matching the filters given in the query string

Bulk deletion supports these filters: identifier, uuid, type, optin, start, end and consent_features. The domain filter is not available, and consent_features is case-sensitive here, unlike in the list.

caution

DELETE /webspaces/:id/consents without filters deletes all the consents of the web space.

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:

  1. Keep the uuid you receive in the response when the consent is created.
  2. To revoke, send a new POST with the same uuid and the same identifier, and set the revoked purposes to false in consent_features (as an object). The other fields that are required for form (optin, ip_address, consent_data) must be sent as in a creation.

The parts that change compared to the original consent:

{
"consent_type": "form",
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"identifier": "user-123",
"consent_features": {
"phone": false,
"whatsapp": false,
"email": true
}
}

The last recorded record is the one that applies: the previous ones stay in the archive as history and proof.

caution

Do not use the deletion endpoints to revoke a consent: they delete the record, and the proof with it.