Record a consent choice
Records the shopper's choice from the banner, the "Cookie settings" link or the account page:
a new consent record (the previous one is kept, marked superseded). Withdrawing is the same call
with the category set to false. Answers 201 with the consent now in force, like GET consent,
plus consent_token: keep it in the HttpOnly consent cookie for 12 months and forward it as
X-Consent-Token from then on. A visitor id (X-Visitor-Id) is linked only when analytics is
granted.
tenantKeyX-Tenant-Key<token>The public store key (pk_live_…). Required on every call.
X-Client-IP?stringOptional. IP address of the shopper (one IPv4/IPv6, no port, no list). Honoured only together with a valid X-Tenant-Secret; ignored otherwise. Used for rate limits and recorded with form submissions.
X-Tenant-Secret*stringRequired here. Server secret of the store: this route is server-to-server only, never from a browser. Also enables X-Client-IP.
Idempotency-Key?stringOptional; recommended (a UUID made once per user action, reused only to retry that action). Only a success is stored (24 hours): the same key with the same body, URI and credentials (Authorization, X-Cart-Token, X-Chat-Token) replays it (Idempotent-Replayed: true); anything else under that key is 422 IDEMPOTENCY_KEY_REUSED. An error is never stored: after a 4xx or 5xx, retrying with the same key runs the request again.
X-Session-Id*stringRequired. The shopper's sid cookie value (8-128 of letters, digits, . _ : -).
X-Visitor-Id?stringOptional. The vid cookie value, when the shopper has one (it exists only with analytics consent). On PUT, linked to the record only when analytics is granted.
X-Consent-Token?stringOptional. The consent cookie value: the consent_token an earlier PUT consent returned. Remembers the choice across sessions, including "reject all".
application/json- body
PUT /api/v1/consent: the shopper's choice, forwarded by the storefront BFF.
categories every category, explicitly: analytics, advertising, personalisation
(booleans; a category the banner did not offer must be false)
source banner | settings_link | account_page
banner_version the banner version the shopper saw (default: the current one)
Plus the subject headers: X-Session-Id required, X-Visitor-Id and
X-Consent-Token optional; a malformed one is a 422 like any field.
categories*The choice for each category. Strictly necessary is not a choice and is ignored if sent.
source*stringWhere the choice was made: the banner (first visit or a re-prompt), the persistent "Cookie settings" link, or the customer's account page.
(login is the engine's own linking record at sign-in and is never accepted here.)
"banner""settings_link""account_page"banner_version?integerThe banner version the shopper was shown (banner.version of GET consent). Default: the current version.
1 <= valueSuccess.
application/json- response
data*curl -X PUT 'https://api.elaraone.app/api/v1/consent' \ -H 'X-Tenant-Key: pk_live_…' \ -H 'X-Tenant-Secret: string' \ -H 'X-Session-Id: string' \ -H 'Content-Type: application/json' \ -d '{ "categories": { "analytics": true, "advertising": true, "personalisation": true }, "source": "banner"}'{ "data": { "record_id": 0, "show_banner": true, "reprompt_reason": "no_choice", "choice": "accept_all", "categories": { "strictly_necessary": true, "analytics": true, "advertising": true, "personalisation": true }, "consent_mode": { "ad_storage": "granted", "ad_user_data": "granted", "ad_personalization": "granted", "analytics_storage": "granted", "personalization_storage": "granted", "functionality_storage": "granted", "security_storage": "granted" }, "recorded_at": "string", "expires_at": "string", "record_banner_version": 0, "record_privacy_notice_version": "string", "record_register_version": "string", "consent_token": "string", "delete_visitor_id": true, "withdrawn": [ "analytics" ], "banner": { "version": 0, "privacy_notice_version": "string", "title": "string", "body": "string", "labels": { "accept_all": "string", "reject_all": "string", "manage": "string", "save": "string", "settings_link": "string" }, "links": { "privacy_notice": "string", "cookie_table": "string" }, "strictly_necessary": { "label": "string", "description": "string" }, "categories": [ { "key": "analytics", "label": "string", "description": "string" } ] } }}Get the consent in force GET
The shopper's consent now: what may be used (`categories`), the Google Consent Mode v2 signals, whether to show the banner (and why), and the current banner to render. Everything is denied until the shopper chooses, after 12 months, and after a change of purpose or a new major storage register version, until they answer again. Call it from the storefront server with the shopper's `sid`, `vid` and `consent` cookie values; send none of them and the answer is "no choice yet".
Get the cookie table GET
Every identifier the store's analytics and conversion tracking keep, on the device or on the servers, with its purpose, lifetime, consent category and when it is deleted; the ad click IDs and their windows; what is never used; and the register's version history. Render it as the store's cookie table (the page the consent banner links to). `register_version` is the version consent records store. Cache it for 5 minutes; revalidate with `If-None-Match` for a bodyless `304`.