Developers
GetCookies for developers
GetCookies has three developer surfaces: a JavaScript API in the browser on every plan, a server-side Consent Verification API with API keys on Business and above, and signed webhooks on Business and above. This page lists the methods, endpoints, limits and errors as the product implements them.
JavaScript API (every plan)
The loader exposes window.GetCookies as soon as it runs, and the full widget replaces it once loaded. A consent object looks like { id, timestamp, categories, interaction, version, expiry }, where categories is an array such as ["necessary", "analytics"].
getConsent()
Returns the current consent object, or
nullbefore the visitor has chosen.hasConsent(category)
Returns
trueif the visitor allowed a category:necessary,analytics,marketingorpreferences.updateConsent(choice)
Saves a choice from your own UI, either as an array of category ids,
updateConsent(['analytics']), or as an object of booleans,updateConsent({ analytics: true, marketing: false }).necessaryis always added. Returns a promise with the saved consent; any other argument rejects with aTypeErrorand saves nothing.on(event, callback) and off(event, callback)
Subscribe to
consent,consent-updatedorloaded. The callback receives the event detail. The same events are dispatched onwindowasgetcookies:consent,getcookies:consent-updatedandgetcookies:loaded.show(), hide() and reset()
Open or close the banner, or clear the stored choice and ask again.
optOut() and getComplianceMode()
getComplianceMode()returnsopt-in,opt-outornotice-onlyfor the current visitor.optOut()records a Do Not Sell or Share choice and only acts in opt-out mode.getVisitorId()
Returns this browser's pseudonymous GetCookies visitor id, a random UUID kept in local storage. Consent records are stored under it; pass it to your server to look the visitor up with the Consent Verification API.
Consent Verification API (Business and above)
Base URL: https://app.getcookies.co/api/v1/consent. Create a key under API Keys in the dashboard; it starts with olc_, is shown once and is stored only as a SHA-256 hash. Send it as Authorization: Bearer olc_… and keep it on your server.
visitor_id_type is visitor_id (the value of GetCookies.getVisitorId(), hashed by GetCookies before the lookup), ip_hash (the default: a 64-character hex key, matched as stored), raw_ip (keyed with GetCookies' server-side HMAC key before the lookup) or cookie_id (matched as sent). Records written by the banner are keyed by the visitor id; the banner does not store IP addresses. The inline settings embed, when the browser sends no key, stores a keyed HMAC of the IP address (never the address or a plain hash of it), which raw_ip finds. Purposes can be GetCookies categories (necessary, analytics, marketing, functional, advertising, preferences) or Google Consent Mode names such as ad_storage and ad_user_data, which are mapped to a category and reported in mapped_to.
POST /verify
Body:
domain_id,visitor_id, optionalvisitor_id_type, andpurposes(1 to 20). Returnsconsent_found, the consent and expiry timestamps, and per purposegranted,can_processand, without a record,reason: no_consent_record.POST /verify/bulk
The same check for up to 1,000 visitors in one request, with a summary of how many had consent.
GET /record
Query:
domain_id,visitor_id, optionalvisitor_id_type. Returns the full latest consent record, or 404 when there is none.GET /history
The same query plus
limit(1 to 100, default 10). Returns earlier records for audits.GET /purposes
Lists the supported purposes and the third-party names that map to them.
Rate limits
Per plan
Business: 1,000 API requests per hour per account. Enterprise: no hourly plan limit. Free, Starter and Pro have no API access.
Per key
60 requests per minute by default and 10,000 per day.
Bulk checks
A bulk request counts as one request and can cover up to 1,000 visitors.
Errors
Errors are JSON in the form { "error": { "code", "message" } }.
401 UNAUTHORIZED
Missing or invalid key, or a plan without API access.
403 FORBIDDEN
The domain does not belong to your organization.
404 NOT_FOUND
Unknown domain, or no consent record for
/record.422 VALIDATION_ERROR
The request body or query does not match the schema.
429 RATE_LIMIT_EXCEEDED
A plan or key limit was reached. Back off and retry later.
Webhooks (Business and above)
Add an HTTPS endpoint under Webhooks and choose events such as consent.accepted, consent.rejected, consent.updated, scan.completed and widget.updated. Each delivery is a JSON POST with the headers X-Webhook-Signature, X-Webhook-Event and X-Webhook-Delivery-Id. The signature is t=<unix seconds>,v1=<hex>, where v1 is the HMAC-SHA256 of <t>.<raw request body> with your signing secret: verify it over the bytes you received, before parsing the JSON, and reject a t more than 5 minutes old. Consent events are sent for every consent the banner or the inline embed records, usually within a minute. Answer with a 2xx status. A failed delivery is retried as many times as the endpoint's retry setting allows (0 to 10), after 30 seconds, 2 minutes, 10 minutes, 30 minutes and 1 hour, then 2, 4, 8, 12 and 24 hours; use X-Webhook-Delivery-Id to ignore a delivery you already processed. Payloads and Global Privacy Control fields are in the event catalog.
Dashboard API, SDK, CLI and MCP server
The dashboard runs on a REST API under /api/v1 that authenticates with a signed-in user's access token, not with API keys. The getcookie-sdk, getcookie-cli and getcookie-mcp packages on npm call that API. It has no published reference yet and can change, so build long-lived server integrations on the Consent Verification API and webhooks.
Example: check consent on your server before sending a conversion
Before your server forwards an event to an advertising API, it can ask GetCookies whether the visitor allowed marketing. Read the visitor id in the browser with `GetCookies.getVisitorId()`, send it to your server with the event, and look it up with `visitor_id_type: visitor_id`. Without a matching consent record, every purpose except necessary comes back as not allowed, with `reason: no_consent_record`.
curl -X POST https://app.getcookies.co/api/v1/consent/verify \
-H "Authorization: Bearer olc_your_key" \
-H "Content-Type: application/json" \
-d '{
"domain_id": "your-domain-uuid",
"visitor_id": "6f1c2e7a-3b4d-4c5e-8f60-718293a4b5c6",
"visitor_id_type": "visitor_id",
"purposes": ["marketing", "ad_user_data"]
}'{
"verified": true,
"domain_id": "your-domain-uuid",
"visitor_id": "2f61a21a34550262...",
"consent_found": true,
"timestamp": "2026-10-25T12:00:00+00:00",
"consent_timestamp": "2026-10-20T09:14:02+00:00",
"consent_expires": "2027-10-20T09:14:02+00:00",
"purposes": {
"marketing": { "granted": true, "mapped_to": null, "can_process": true },
"ad_user_data": { "granted": true, "mapped_to": "marketing", "can_process": true }
}
}Example: verify a webhook signature
The `X-Webhook-Signature` header is `t=<unix seconds>,v1=<hex>`. Compute the HMAC-SHA256 of `<t>.<raw body>` with your signing secret over the bytes exactly as received, compare it in constant time, and reject a delivery whose `t` is more than 5 minutes away from your clock, so a captured request cannot be replayed later. Parsing the JSON first and serializing it again changes the bytes and the signature no longer matches.
import crypto from 'node:crypto';
import express from 'express';
const app = express();
const TOLERANCE_SECONDS = 300;
function verifySignature(rawBody, header, secret) {
const parts = (header || '').split(',').map((part) => part.trim().split('='));
const timestamp = Number(parts.find(([key]) => key === 't')?.[1]);
const signatures = parts.filter(([key]) => key === 'v1').map(([, value]) => value);
if (!Number.isInteger(timestamp) || signatures.length === 0) return false;
if (Math.abs(Date.now() / 1000 - timestamp) > TOLERANCE_SECONDS) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.`)
.update(rawBody)
.digest('hex');
return signatures.some((signature) =>
signature.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))
);
}
app.post('/webhooks/getcookies', express.raw({ type: 'application/json' }), (req, res) => {
const secret = process.env.GETCOOKIES_WEBHOOK_SECRET;
if (!verifySignature(req.body, req.get('X-Webhook-Signature'), secret)) {
return res.sendStatus(401);
}
const event = JSON.parse(req.body);
console.log(event.event_type, req.get('X-Webhook-Delivery-Id'));
res.sendStatus(204);
});Try GetCookies on your own site
Start on the Free plan: one domain, a cookie scan and a consent banner, no credit card required. Upgrade only when you need more.
Start free