Skip to main content

Data export & GDPR

Three GDPR webhooks (mandatory)

Per Shopify's app requirements, every app must implement three GDPR-related webhook handlers:

WebhookWhen firedSumeru behavior
customers/data_requestCustomer requests data exportGenerate full data JSON; deliver per request
customers/redactCustomer requests deletionRun erase pipeline immediately
shop/redact30 days after app uninstallPermanent shop-data deletion

Each is signed with HMAC-SHA256 (per Shopify webhooks).

customers/data_request — export

What gets exported

Full Customer 360 + all related data:

{
"customer": {
"id": "cus_abc123",
"email": "jane@example.com",
"phone": "+15551234567",
"shopify_customer_id": "gid://shopify/Customer/12345",
"lifecycle_stage": "loyal",
"total_spent": 487.20,
"first_order_at": "2024-08-15T...",
"last_order_at": "2026-04-22T...",
"predicted_ltv_12mo": 920.40
},
"events": [
{ "type": "page_view", "timestamp": "...", "url": "..." },
{ "type": "cart_abandoned", "timestamp": "...", "cart_value": 67.50 }
],
"messages": [
{ "channel": "email", "campaign_id": "...", "sent_at": "...", "opened_at": "..." }
],
"attributions": [
{ "order_id": "...", "model": "linear", "credit_per_touchpoint": [...] }
],
"opt_ins": [
{ "channel": "email", "action": "opt_in", "consent_text": "...", "timestamp": "..." }
],
"segments": [ "vip", "loyal-uk" ],
"journey_enrollments": [ ... ],
"identity_links": [
{ "kind": "email", "value": "jane@example.com" },
{ "kind": "phone", "value": "+15551234567" },
{ "kind": "session", "value": "anon_xyz" }
]
}

Delivery

Per Shopify's contract, exports are delivered to:

  • The merchant's contact email, OR
  • A data_request_url configured at app install

Delivery within 30 days SLA (typically <1 hour).

customers/redact — erase

Erase pipeline

Wrapped in a single DB transaction:

What's nulled vs deleted vs kept

FieldAction
email, phone, namesnull (in place)
Identity linksdelete
Web sessionsdelete
Marketplace IDsdelete
Order amounts (anonymized)kept (revenue analytics still work)
Customer 360 rowkept (with PII null + dataDeletedAt set)
OptInRecordsdelete (audit trail of consent removed)
Segment membershipsdelete
Active journeysexited with reason gdpr_erasure
Audit log of the redact itselfkept (regulator-required)

Reversibility

Wrong-customer redacts are reversible for:

  • Free / Starter: 24h
  • Pro: 7 days
  • Agency: 30 days
  • Enterprise: 90 days

After window: irreversible (re-pull from Shopify if customer recreates).

shop/redact — full erasure

Fired by Shopify 30 days after app uninstall. Sumeru:

  1. Anonymizes/deletes all Customer 360 rows for the shop
  2. Deletes all events, messages, opt-ins, attributions
  3. Deletes all journey enrollments + segment definitions
  4. Deletes all webhook subscriptions
  5. Cancels all API tokens
  6. Deletes shop record
  7. Logs to GdprRequest

After this, the shop's data is permanently gone from Sumeru. No recovery possible.

Programmatic export (alternative)

Merchants can also trigger exports directly:

curl -X POST \
-H "Authorization: Bearer copt_live_..." \
-d '{"customer_id": "cus_abc123"}' \
"https://api.sumeru.systems/api/v1/gdpr/export"

Returns:

{
"data": {
"export_id": "gex_xyz789",
"status": "processing",
"download_url": null
}
}

Poll for completion:

curl -H "Authorization: Bearer copt_live_..." \
"https://api.sumeru.systems/api/v1/gdpr/exports/gex_xyz789"

When status: completed, download_url is available (signed URL, expires in 24h).

Programmatic erase

# Preview first (counts what would be erased)
curl -X POST \
-H "Authorization: Bearer copt_live_..." \
-d '{"customer_id": "cus_abc123"}' \
"https://api.sumeru.systems/api/v1/gdpr/erase/preview"

# Then erase
curl -X POST \
-H "Authorization: Bearer copt_live_..." \
-d '{"customer_id": "cus_abc123", "actor": "support@yourshop.com"}' \
"https://api.sumeru.systems/api/v1/gdpr/erase"

actor is logged in the audit trail.

Audit verification

Every GDPR action logged to GdprRequest table; queryable via /api/v1/gdpr/requests:

curl -H "Authorization: Bearer copt_live_..." \
"https://api.sumeru.systems/api/v1/gdpr/requests?filter[customer_id]=cus_abc123"

Returns full history:

{
"data": [
{
"id": "gdr_abc",
"type": "EXPORT",
"source": "shopify_webhook",
"status": "completed",
"completed_at": "2026-05-10T14:25:00Z"
},
{
"id": "gdr_xyz",
"type": "REDACT",
"source": "merchant_initiated",
"actor": "support@yourshop.com",
"status": "completed",
"completed_at": "2026-05-10T14:30:00Z",
"counts": {
"events": 4820,
"attributions": 86,
"opt_ins": 14,
"identity_links": 6
}
}
]
}

Compliance posture

  • All data encrypted at rest (AES-256)
  • TLS 1.3 in transit
  • Access logged via audit log
  • DPA available (sumeru.systems/legal/dpa)
  • Sub-processors documented + updated
  • Data residency option (EU): Enterprise tier

See also