Data export & GDPR
Three GDPR webhooks (mandatory)
Per Shopify's app requirements, every app must implement three GDPR-related webhook handlers:
| Webhook | When fired | Sumeru behavior |
|---|---|---|
customers/data_request | Customer requests data export | Generate full data JSON; deliver per request |
customers/redact | Customer requests deletion | Run erase pipeline immediately |
shop/redact | 30 days after app uninstall | Permanent 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_urlconfigured 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
| Field | Action |
|---|---|
| email, phone, names | null (in place) |
| Identity links | delete |
| Web sessions | delete |
| Marketplace IDs | delete |
| Order amounts (anonymized) | kept (revenue analytics still work) |
| Customer 360 row | kept (with PII null + dataDeletedAt set) |
| OptInRecords | delete (audit trail of consent removed) |
| Segment memberships | delete |
| Active journeys | exited with reason gdpr_erasure |
| Audit log of the redact itself | kept (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:
- Anonymizes/deletes all Customer 360 rows for the shop
- Deletes all events, messages, opt-ins, attributions
- Deletes all journey enrollments + segment definitions
- Deletes all webhook subscriptions
- Cancels all API tokens
- Deletes shop record
- 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