Skip to content

Privacy & GDPR

Pionne is designed to be GDPR-compliant by default. Here’s what’s done, what you should know, and what you can do on top.

Before sending, the SDK sanitizes common PII patterns: email, card numbers, IBAN, JWT, tokens, IPs, phone numbers. See PII Scrubbing for the full list and customization.

  • The server never logs the IP of an event.
  • The user.id field is free SDK-side — use an anonymous identifier (UUID, hash). Never send the email.
// Good
Pionne.setUser('user_a8f2c1');
// Bad
Pionne.setUser('john@doe.com');

Events are automatically deleted after 30 days. No action required. This duration covers the vast majority of post-release debug needs without piling up data indefinitely.

If a user of your app asks for their data to be deleted:

  1. Get their user.id (the anonymous identifier you assigned them).
  2. Filter the issues in the Pionne dashboard by that user.id.
  3. Delete the relevant issues via DELETE /api/projects/{id}/issues/{issueId}.

Since the only link between an event and the real user is that anonymous ID stored in your app, deletion on the Pionne side is final.

Pionne can show the approximate city/region/country on every event — useful for spotting a regression localized to an ISP or a country. Disabled by default.

Enable:

Pionne.init({
token: '...',
sendGeography: true,
});

What happens:

  • A single HTTP call at startup to https://ipapi.co/json/ (4 s timeout). No GPS coordinates, no OS permission required.
  • The result — { city, region, country, country_code } — is cached and attached to every event under contexts.geo.
  • The raw IP is never persisted: only the approximate city/region/country is, under the same 30-day retention as everything else.
  • The lookup can be disabled at runtime via setEnabled(false) or by passing sendGeography: false on the next init().

Want your own provider to keep things in-house? geographyEndpoint: 'https://geo.yourapi.com/' accepts any URL returning { city, region, country, country_code }.

Screenshots are:

  • Opt-in (captureScreenshot: true).
  • Stored as JPG q=0.5 by default on the Pionne server.
  • Subject to the same 30-day retention.

For these sensitive verticals, go beyond the default:

Pionne.init({
token: '...',
captureScreenshot: false,
scrubPii: [
{ re: /patient_[a-z0-9]+/gi, replace: '[patient]' },
{ re: /diagnosis:[^\n]+/gi, replace: 'diagnosis:[redacted]' },
],
beforeSend: (event) => {
// Drop anything containing sensitive business fields
if (event.extra?.medicalRecord) return null;
return event;
},
});
  • Data hosted in France (EU datacenter).
  • Backend: Laravel + SQL stack.
  • No transfers outside the EU.
  • Subprocessors: Apple/Google for push notifications only.