Takaisin blogiin
Technical

GetCookies Webhooks: Real-Time Consent Events for Your Systems

GetCookies-tiimiJanuary 7, 202515 min lukuaika
WebhooksAPIIntegrationReal-TimeDeveloper

TLDR: GetCookies webhooks deliver real-time consent events to your systems via HTTP POST. 15+ event types, HMAC-SHA256 signing, automatic retries, and delivery tracking. Sync consent to your CRM, trigger marketing automation, and build custom workflows.

Read full summary

Complete guide to GetCookies webhook integration for real-time consent event delivery. Covers all supported event types (consent, domain, scan, compliance), payload structure, security with HMAC signing, retry logic, and practical use cases including CRM sync, marketing automation triggers, and compliance audit logging.

Summary by Claude AI

The Real-Time Consent Problem

Illustrative scenario: a composite example, not a specific reported case.

A DTC e-commerce brand had a sophisticated marketing stack: Klaviyo for email, Attentive for SMS, Meta Ads for retargeting. Each platform needed to know user consent status. But consent was collected in the browser, and these platforms lived server-side.

Their solution: batch export consent records once per day. The result: 24 hours of potential violations. Marketing messages went to users who had rejected consent. Retargeting pixels targeted people who had opted out.

Real-time consent requires real-time data flow. Batch processing is a compliance gap waiting to happen.

Why Webhooks for Consent

Immediate Action

When a user withdraws consent, your systems should know instantly—not tomorrow morning.

No Polling Required

Webhook push is more efficient than repeatedly asking "any new consents?" Reduce API calls, reduce latency.

Event-Driven Architecture

Modern systems are event-driven. Webhooks let consent changes trigger downstream workflows immediately.

Audit Trail

Webhook deliveries are logged. You can prove when you were notified and how quickly you acted.

GetCookies Webhook Events

Consent Events

Event Description When Triggered
consent.accepted User accepted consent Banner interaction
consent.rejected User rejected consent Banner interaction
consent.updated Preferences changed Settings update
consent.withdrawn Consent revoked Settings or GPC signal

Domain Events

Event Description When Triggered
domain.created New domain added Dashboard action
domain.updated Domain config changed Settings save
domain.deleted Domain removed Deletion confirmed
domain.verified Ownership confirmed DNS verification

Scan Events

Event Description When Triggered
scan.started Cookie scan began Manual or scheduled
scan.completed Scan finished Scan completion
scan.failed Scan error occurred Error state

Compliance Events

Event Description When Triggered
compliance.violation_detected Issue found Post-scan analysis
compliance.audit_generated Report ready Audit completion

Webhook Payload Structure

Standard Payload

{
  "id": "evt_abc123xyz",
  "type": "consent.accepted",
  "timestamp": "2025-01-15T14:32:00Z",
  "domain_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "visitor_id": "v_xyz789",
    "consent_categories": {
      "essential": true,
      "analytics": true,
      "marketing": false,
      "personalization": false
    },
    "consent_version": "2.1",
    "gpc_enabled": false,
    "user_agent": "Mozilla/5.0...",
    "ip_country": "DE"
  }
}

Consent-Specific Fields

{
  "data": {
    "previous_consent": {
      "analytics": false,
      "marketing": false
    },
    "new_consent": {
      "analytics": true,
      "marketing": false
    },
    "consent_method": "banner",
    "consent_duration": 3400,  // ms until decision
    "tc_string": "CPA..."     // if TCF enabled
  }
}

Global Privacy Control (GPC) Fields

Every consent webhook now includes GPC information for audit-ready compliance logging:

{
  "data": {
    "gpc": {
      "signal_detected": true,
      "honored": true,
      "consent_source": "gpc_auto",
      "region_code": "US-CA"
    }
  }
}
Field Type Description
signal_detected boolean Whether browser sent GPC signal (navigator.globalPrivacyControl or Sec-GPC header)
honored boolean Whether the opt-out was applied based on the signal
consent_source string How consent was obtained: banner, gpc_auto, api, account_settings
region_code string Jurisdiction code (e.g., US-CA, EU, GB) for compliance context

Why this matters: 12+ US states now require honoring GPC as a legally binding opt-out signal, including California, Colorado, Connecticut, Texas, Oregon, Montana, Delaware, New Jersey, New Hampshire, Nebraska, Minnesota, and Maryland. These fields let you prove you detected and honored the signal for audit purposes.

Do Not Track (DNT) Fields

We also detect and log the legacy DNT signal for completeness:

{
  "data": {
    "dnt": {
      "signal_detected": true,
      "honored": true
    }
  }
}
Field Type Description
signal_detected boolean Whether browser sent DNT signal (navigator.doNotTrack)
honored boolean Whether the signal was honored (not legally required but good faith)

Note: DNT is not legally binding anywhere, but some organizations still honor it as a good faith privacy measure.

Security: HMAC Signing

Every webhook is signed with HMAC-SHA256. Verify to ensure authenticity.

Signature Header

X-GetCookies-Signature: sha256=a3f9b2c1d8e7...

Verification Code

Node.js:

const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your webhook handler
app.post('/webhooks/consent', (req, res) => {
  const signature = req.headers['x-getcookies-signature'];
  const isValid = verifySignature(
    JSON.stringify(req.body),
    signature,
    process.env.WEBHOOK_SECRET
  );

  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }

  // Process event...
  res.status(200).send('OK');
});

Python:

import hmac
import hashlib

def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
    expected = 'sha256=' + hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

Retry Logic

Failed deliveries are retried with exponential backoff:

Attempt Delay
1 Immediate
2 30 seconds
3 2 minutes
4 10 minutes
5 1 hour

After 5 failures, the webhook is marked as failing. You'll receive an email notification.

Delivery Status

Each webhook tracks:

  • Delivery attempts
  • Response codes
  • Response times
  • Error messages

View history in your dashboard or via API.

Creating Webhooks

Via Dashboard

  1. Go to Settings > Webhooks
  2. Click Add Webhook
  3. Enter endpoint URL
  4. Select events to subscribe
  5. Copy the signing secret
  6. Click Create

Via API

curl -X POST https://api.getcookies.co/v1/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain_id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "CRM Sync",
    "url": "https://your-api.com/webhooks/consent",
    "events": ["consent.accepted", "consent.updated", "consent.withdrawn"],
    "retry_enabled": true,
    "retry_max_attempts": 5
  }'

Use Case: CRM Consent Sync

HubSpot Integration

app.post('/webhooks/consent', async (req, res) => {
  const { type, data } = req.body;

  if (type === 'consent.accepted' || type === 'consent.updated') {
    // Find or create contact by visitor ID
    const contact = await hubspot.contacts.getByProperty(
      'getcookies_visitor_id',
      data.visitor_id
    );

    // Update consent properties
    await hubspot.contacts.update(contact.id, {
      properties: {
        analytics_consent: data.consent_categories.analytics,
        marketing_consent: data.consent_categories.marketing,
        consent_updated_at: data.timestamp,
        consent_version: data.consent_version
      }
    });
  }

  res.status(200).send('OK');
});

Salesforce Integration

if (type === 'consent.withdrawn') {
  // Immediately update Salesforce contact
  await salesforce.sobjects.Contact.update({
    Id: contactId,
    GDPR_Consent__c: false,
    Marketing_Consent__c: false,
    Consent_Withdrawal_Date__c: new Date().toISOString()
  });

  // Remove from marketing campaigns
  await salesforce.sobjects.CampaignMember.delete({
    ContactId: contactId
  });
}

Use Case: Marketing Automation

Email Suppression

if (type === 'consent.rejected' || type === 'consent.withdrawn') {
  // Add to suppression list immediately
  await klaviyo.profiles.suppress({
    email: data.email,
    reason: 'consent_withdrawn'
  });

  // Stop any active flows
  await klaviyo.flows.cancelForProfile(data.email);
}

Segment User Updates

// Update Segment traits in real-time
analytics.identify(data.visitor_id, {
  analytics_consent: data.consent_categories.analytics,
  marketing_consent: data.consent_categories.marketing,
  consent_source: 'getcookies_webhook'
});

Use Case: Compliance Logging

Immutable Audit Trail

// Write to append-only compliance log
await complianceLog.append({
  event_id: req.body.id,
  event_type: req.body.type,
  timestamp: req.body.timestamp,
  visitor_id: req.body.data.visitor_id,
  consent_state: req.body.data.consent_categories,
  raw_payload: JSON.stringify(req.body),
  received_at: new Date().toISOString()
});

Datadog Event

// Send compliance events to monitoring
dogstatsd.event({
  title: `Consent ${req.body.type.split('.')[1]}`,
  text: JSON.stringify(req.body.data.consent_categories),
  tags: [
    `domain:${req.body.domain_id}`,
    `country:${req.body.data.ip_country}`,
    `event_type:${req.body.type}`
  ]
});

Use Case: Slack Notifications

if (type === 'compliance.violation_detected') {
  await slack.postMessage({
    channel: '#compliance-alerts',
    blocks: [
      {
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: `⚠️ *Compliance Violation Detected*\n\nDomain: ${data.domain}\nIssue: ${data.violation_type}\nSeverity: ${data.severity}`
        }
      },
      {
        type: 'actions',
        elements: [{
          type: 'button',
          text: { type: 'plain_text', text: 'View Details' },
          url: `https://app.getcookies.co/domains/${data.domain_id}/compliance`
        }]
      }
    ]
  });
}

Testing Webhooks

Test Endpoint

Send a test event from the dashboard:

  1. Go to Settings > Webhooks
  2. Click ... menu on your webhook
  3. Select Send Test Event
  4. Choose event type
  5. View delivery result

Local Development

Use ngrok or similar to expose local endpoints:

ngrok http 3000
# Use the generated URL for webhook testing

Webhook Debugging

Check the delivery log for:

  • Request payload sent
  • Response code received
  • Response body (if any)
  • Timing information

Best Practices

Respond Quickly

Return 200 immediately, then process asynchronously:

app.post('/webhooks/consent', async (req, res) => {
  // Acknowledge immediately
  res.status(200).send('OK');

  // Process in background
  processWebhook(req.body).catch(err => {
    console.error('Webhook processing failed:', err);
  });
});

Handle Duplicates

Network issues can cause duplicate deliveries. Use event ID for idempotency:

const processed = await cache.get(`webhook:${req.body.id}`);
if (processed) return res.status(200).send('Already processed');

await cache.set(`webhook:${req.body.id}`, true, 86400);
// Process event...

Monitor Failures

Set up alerts for webhook failures to catch issues early.

Getting Started

  1. Create a webhook endpoint in your application
  2. Register it in GetCookies dashboard
  3. Implement signature verification
  4. Handle the event types you need
  5. Test with sample events
  6. Monitor delivery success

Real-time consent data enables real-time compliance. Webhooks make it possible.

Usein kysytyt kysymykset

What events can webhooks deliver?
Webhooks support consent events (accepted, rejected, updated, withdrawn), domain events (created, updated, deleted), scan events (started, completed, failed), and compliance events (violation detected, resolved).
Are webhook payloads secure?
Yes, all webhook payloads are signed with HMAC-SHA256 using a unique secret per endpoint. Your server can verify the signature to ensure payloads are authentic.
What happens if my endpoint is down?
GetCookies automatically retries failed deliveries with exponential backoff for up to 24 hours. The webhook dashboard shows delivery status and allows manual replay.
G

GetCookies-tiimi

Kirjoittanut ja ylläpitää GetCookies-tiimi, Getia AS, Oslo, Norja. Artikkeli on yleistä tietoa evästesuostumuksesta eikä oikeudellista neuvontaa.

Skannaa oma sivustosi ilmaiseksi

Ilmaispaketissa banneri toimii yhdellä sivustolla ja saat kolme evästeskannausta kuukaudessa. Ei korttia, ei myyntipuheluita.