Privacy, security & compliance
GDPR roles, DPA, the data processing register and consent API, children-oriented apps, certifications, and data export and deletion.
What are the respective roles under GDPR?
| Role | Who | What it means |
|---|---|---|
| Data Controller | You | You decide which processing is lawful and inform your users accordingly. |
| Data Processor | Purchasely | We process data strictly under your instructions and in compliance with applicable law. |
Our Data Processing Agreement is public: PURCHASELY-DATA-PROCESSING-AGREEMENT.pdf
What data processing do you perform, and what can I switch off?
The register is exposed directly in the SDK since v5.4, with the legal basis and revocability of each processing:
| Processing | Purpose | Legal basis | Revocable |
|---|---|---|---|
| #1 | Operations strictly necessary for the service to function | Performance of contract | No |
| #2 | Audience measurement, statistical analysis, journey optimization | Legitimate interest or consent | Yes |
| #3 | Personalization of the journey and of the offers presented | Legitimate interest or consent | Yes |
| #4 | Recommendation of offers displayed spontaneously (Campaigns) | Legitimate interest or consent | Yes |
The API is granular, and you wire your CMP to it:
Purchasely.revokeDataProcessingConsent(for: [.allNonEssentials])
// or precisely: .analytics, .identifiedAnalytics, .personalization, .campaigns, .thirdPartyIntegrationsPurchasely.revokeDataProcessingConsent(setOf(PLYDataProcessingPurpose.AllNonEssentials))
The SDK is not wired to your CMP automaticallyYour app is responsible for translating the user's CMP choices into
revokeDataProcessingConsentcalls. There is no direct interface between the two.
User attributes are typed essential or optional. When personalization is revoked, optional attributes are wiped and ignored in Audience matching, while essential ones keep working.
📚 Managing user privacy — full guide
Do you collect email addresses, phone numbers or any PII?
No. Purchasely never asks for an email address or a phone number. The user identifier you pass is an opaque string of your choosing, and an internal UUID is enough — see Users & identity.
If you push custom user attributes, you control what goes in them. Nothing requires directly identifying data.
Do not use an email address as the user IDIt would bring PII into the platform for no functional benefit.
Our app targets children or families — is there a compliant mode?
Yes. There is a maximal setting that stops all UI / SDK event collection:
Purchasely.revokeDataProcessingConsent(for: [.analytics])Purchasely.revokeDataProcessingConsent(setOf(PLYDataProcessingPurpose.Analytics))This is exactly the mode intended for apps targeting children, and for privacy-focused apps in general.
The trade-off is explicitPaywall displays are no longer measured, so you lose the conversion dashboards and the A/B test reports. Revenue and subscription data are unaffected, since those come from server events. Use this setting deliberately, not as a default.
Store-level protections for families are handled natively:
- Ask to Buy / PSD2 — the
IN_APP_DEFERREDevent plus a fully localizable native "Waiting for approval" screen (ply_modal_alert_in_app_deferred_*). The entitlement is opened only once the purchase is actually approved. - Family Sharing —
is_family_sharedon every server event, andFAMILY_SHARED_REVOKEDwhen the owner removes access. A shared subscription attaches to the member automatically on their first app open, with nothing to implement. We receive no data about the payer — the stores do not transmit it.
📚 Localizing your app · Server event attributes · Lifecycle events
What certifications and compliance frameworks do you hold?
Purchasely is compliant with GDPR, COPPA and CCPA, and is SOC 2 certified.
- Security overview: purchasely.com/security
- Documents and certifications (Trust Center): Purchasely Trust Center
Where is the data hosted, and do you have a document for our DPIA?
Our certifications, security policies and the current list of subprocessors are published in the Trust Center, and the contractual commitments — including hosting locations, subprocessors, breach notification and deletion deadlines — are in the Data Processing Agreement.
For a DPIA you will usually also want the technical and organizational measures (TOMs) summary and the hosting regions in writing for your specific contract. Request those from your Purchasely contact or our DPO — they are provided as part of the security review, not published on this page.
How do I export or port a user's data?
Continuously, through the channels you already have:
- S2S webhooks — real-time JSON on the whole lifecycle (entitlement events, 27 lifecycle events, offer events,
TRANSACTION_PROCESSED). The most complete channel: you replicate the data on your side permanently. - Third-party forwarding to your analytics and CRM tools.
- CSV exports from the Console dashboards.
How do I delete the data of one specific user?
Call the user deletion request endpoint:
curl --request POST \
--url https://s2s.purchasely.io/user_deletion_requests \
--header 'X-API-KEY: <your app API key>' \
--header 'Authorization: <HMAC-SHA256 signature of the body>' \
--header 'Content-Type: application/json' \
--data '{"user_id":"12345"}'The request is signed with your Client shared secret, processed asynchronously, and returns a deletion request identifier that support can use to trace it. It covers the whole chain:
- irreversible pseudonymization of the user identifier on all subscription events, including subscriptions transferred from or to that user,
- deletion of the stored webhook history and the associated tokens,
- erasure of the IP addresses of the attached devices,
- purge of the stored purchases in the real-time database,
- deletion marking of the user.
Throttling50 requests per 10 minutes. Beyond that you get a
429and are blocked for 10 minutes. Contact us if you need a higher limit.
📚 User deletion request — full reference
Are third-party integrations a privacy concern for us?
Forwarding uses the identifier you provide, so it is the downstream tool that has to resolve it, not us. If a user declines that processing, switch it off entirely:
Purchasely.revokeDataProcessingConsent(for: [.thirdPartyIntegrations])Purchasely.revokeDataProcessingConsent(setOf(PLYDataProcessingPurpose.ThirdPartyIntegrations))Subscription lifecycle processing itself (Processing #1) cannot be turned off — it is what makes subscriptions work — but its forwarding to external systems can.
Updated 20 minutes ago

