# Data processing agreement

> The GDPR article 28 agreement for the monitoring data you send to Lampwick, with the security measures and the list of sub-processors.

This data processing agreement ("DPA") is part of the [Terms of service](/legal/terms/) between you, the controller, and NIO Media, the processor. NIO Media is the trade name of Niels Oosterhoff, sole proprietorship (eenmanszaak) registered with the Netherlands Chamber of Commerce under number 69855773, Roomweg 68, 7523 BR Enschede, the Netherlands. Lampwick is a service of NIO Media; "we" and "Lampwick" mean NIO Media. The DPA applies automatically when you use Lampwick to process personal data; you don't need to sign anything.

If this DPA and the terms conflict about personal data, this DPA wins.

## Subject and duration

Lampwick processes personal data contained in the data your apps, scripts and team members send to or create in Lampwick ("Customer Data", or "your data"), to provide the monitoring service described in the terms. Processing lasts as long as you use the service, and ends as described in [Deletion at the end](#deletion-at-the-end).

### Nature and purpose

Receiving, storing, grouping, analyzing and showing monitoring data; sending alerts about it; checking the URLs and hosts you configure; and publishing the status pages you choose to publish.

### Categories of data

What you send decides what we hold. Depending on your integration, your data can include:

- **Requests, jobs, commands and queries**: URLs and routes, HTTP methods and status codes, the client IP address, request headers (Lampwick removes `Authorization`, `Cookie` and other credential headers on arrival), request bodies of failed requests if you turn that on, SQL text, cache keys, mail subjects, timings.
- **Errors and logs**: exception classes and messages, stack traces, source lines around the error, log messages and their context.
- **Users of your app**: the user id, name and username or email address your integration reports, with their activity and errors.
- **Browser errors** (the `b.js` snippet): the page URL without query string or fragment, the browser's user agent, error messages and stack traces, failed `fetch` targets if turned on, and the user id, name and email address if you call `lampwick.setUser`. The visitor's IP address is not stored with the error; it is used in memory for rate limiting and appears in our web server access logs, like every request.
- **OpenTelemetry** traces and logs, including `enduser.id` and `user.id`.
- **Deploys**: version, commit, environment and author.
- **Uptime, host checks and site crawls**: the URLs you monitor, response times and status codes, certificate, domain and DNS data, and links found on your pages.
- **Status pages**: the names and notices you publish. Visitors' IP addresses are used in memory for rate limiting and appear in our web server access logs.

Our web server access logs (IP address, time, URL, user agent) cover every request, including ingest, browser errors and status pages, and are kept for up to 14 days.

### Data subjects

Users and visitors of your apps and websites, visitors of your status pages, your staff and contractors, and anyone else whose data appears in your logs or errors.

### Special categories

Lampwick is not designed for special categories of personal data (art. 9 GDPR), data about criminal convictions (art. 10), or payment card data. You must not send them.

## Your instructions and obligations

Lampwick processes your data only on your documented instructions, including with regard to transfers to a third country. The terms, this DPA and the settings you choose in the app (what to collect, retention through your plan, alert channels, status pages, deletion) are your instructions. If we think an instruction breaks the GDPR, we tell you. If EU or Dutch law requires us to process data otherwise, we tell you first, unless that law forbids it.

You are responsible for:

- having a legal basis for sending the data and informing the people it is about;
- sending only what you need. Use the redaction settings of the integrations (the Laravel package redacts passwords, tokens and similar fields by default, and doesn't send request bodies unless you turn that on), and don't put personal data in log messages or exception messages you don't need;
- not sending special categories of personal data;
- the settings you choose, such as turning on request payloads or exception messages in alert channels.

### If you are a processor yourself

If you process Customer Data as a processor for your own client (for example as an agency monitoring a client's app), Lampwick acts as your sub-processor; you confirm that your controller has authorized this, and you pass on to us its instructions. We deal only with you.

## Our obligations

Lampwick will:

- process your data only to provide the service and as instructed, never for its own purposes such as advertising, AI training or selling it;
- make sure everyone with access is bound to confidentiality;
- take the measures in [Security measures](#security-measures);
- help you, as far as we reasonably can, to answer requests from data subjects, and with data protection impact assessments and prior consultations (art. 32 to 36 GDPR);
- tell you about a personal data breach as described in [Breach notification](#breach-notification);
- make the information you need to show compliance available, and allow audits as described in [Audits](#audits).

We forward any request we receive directly from one of your data subjects to you and don't answer it ourselves, unless you ask us to.

Our assistance under this DPA is free as far as the self-service features cover it. For other assistance we may charge reasonable costs at our usual rates, agreed in advance, unless the request results from our breach of this DPA or the GDPR.

## Customer-directed transfers

Some features send your data where you tell them to. These recipients are your choice, not our sub-processors, and you are responsible for that transfer:

- **Alert channels**: Slack, Discord, Microsoft Teams or your own webhook endpoint. Messages can contain exception messages; you can turn that off per channel.
- **API and MCP clients**: tokens and connected apps (for example an AI assistant connected through `/mcp`) read the data the token's account can see.
- **Public status pages**: what you publish is visible to anyone.

## Sub-processors

You give general authorization for the sub-processors below. We impose on each sub-processor, by contract, the same data protection obligations as in this DPA, and we remain responsible to you for its performance of those obligations (art. 28(4) GDPR), subject to the liability section of the Terms.

| Sub-processor | Purpose | Your data involved | Location |
|---|---|---|---|
| Hetzner Online GmbH | Servers, database and backups | All of it | Germany |
| Lettermint | Sending alert and service emails | Recipient addresses and alert content: monitor names, failure reasons, URL host and path | EU (the Netherlands) |
| Apple Inc. (Apple Push Notification service) | Push notifications to the Lampwick iOS app, only for team members who install it | Notification text. Issues: project name, issue number, error class and message (for browser errors, the class only). Alerts: title and body, such as monitor names, failure reasons and URL host and path | US (EU-US Data Privacy Framework) |

These parties are not sub-processors for your data:

- **Stripe Payments Europe, Limited** processes billing data about you as our customer, partly as an independent controller. It receives no monitoring data.
- **GitHub and Google** are used only when a person chooses to log in with them. GitHub also hosts our source code and runs our deployments (GitHub Actions), without customer data.
- **Public DNS resolvers** (Cloudflare, Inc. and Google LLC, US companies) and **domain registries** (over RDAP) receive only the host and domain names of the URLs you monitor, to run DNS and domain expiry checks.

### Changes to sub-processors

We announce a new or replaced sub-processor to team owners by email at least 30 days in advance, and on this page. You can object on reasonable data protection grounds within that period. If we can't resolve the objection, you can end the affected subscription before the change and get a pro-rata refund of prepaid fees.

## International transfers

Your data is stored in the EU. It leaves the EU only through Apple's push service, for team members who use the iOS app (under the EU-US Data Privacy Framework), and through the customer-directed transfers above. If a sub-processor transfers your data and the Data Privacy Framework doesn't cover it, we use the Standard Contractual Clauses.

## Security measures

These are the technical and organizational measures (art. 32 GDPR) in place today:

- **Encryption in transit**: all traffic to lampwick.dev uses TLS (certificates from Let's Encrypt), with HSTS. Customers send data over HTTPS only; the unencrypted TCP ingest port is not reachable from the internet.
- **Secrets at rest**: two-factor secrets and alert channel webhook URLs and signing secrets are encrypted with XChaCha20-Poly1305. Passwords are hashed with Argon2. Session ids, API tokens, OAuth tokens and invitation, verification and reset links are stored only as hashes. Project ingest tokens and browser keys are stored readable, because owners need to see them.
- **Tenant isolation**: every project belongs to a team, and every page, API call, search and live stream is checked against the caller's team membership. A project of another team answers exactly like one that doesn't exist.
- **Access control**: team roles (owner and member); only owners see ingest tokens, IP addresses in the audit log and alert channel URLs and secrets. Read-only API tokens. Optional two-factor login for every account.
- **Abuse protection**: rate limits per IP on login, signup and other flows, temporary account lockout after repeated wrong passwords or codes, limits on ingest and public endpoints.
- **Data minimization at ingest**: credential headers are removed on arrival; the browser snippet strips query strings, fragments and credentials from URLs before sending, and the server strips them again.
- **Audit log**: team and account changes are recorded with actor, IP and channel, kept 365 days.
- **Infrastructure**: servers at Hetzner in Germany, firewall with only the needed ports open, SSH with keys only, automatic security updates, the database reachable only from the server itself.
- **Availability and recovery**: nightly database backups, kept 7 days locally and about 30 days off-site in a different EU location, plus Hetzner server backups.
- **Supply chain and deployment**: the source code is on GitHub. GitHub Actions builds each release and deploys it with a dedicated deploy key that can only upload a release and activate it. Releases ship only after automated tests pass, and roll back automatically when a release doesn't start.
- **People**: only NIO Media's owner has access to production.

We may change these measures as long as the overall level of security doesn't go down.

## Breach notification

If we become aware of a personal data breach affecting your data, we notify the team owners by email without undue delay, and within 48 hours where we can. We tell you what we know: what happened, which data and how many people are likely affected, the likely consequences, and what we have done and will do. We add details as we learn them. Notifying the supervisory authority and the people affected is your decision as controller; we help you with it.

## Audits

On request, we give you the information you need to show that we meet art. 28 GDPR, such as an up-to-date description of these measures. If that isn't enough, you or an independent auditor you mandate, bound to confidentiality, may audit our compliance:

- at most once per 12 months, plus after a personal data breach affecting your data, or when a supervisory authority requires it;
- with 30 days' written notice, during business hours, without disrupting the service or seeing other customers' data;
- each party pays its own costs, unless the audit finds a material breach of this DPA by us: then we pay the reasonable cost of the audit.

## Retention

Your data is kept as long as your plan's retention, after which it is deleted automatically.

**Follows the plan's retention** (Free 3 days, Pro 14, Team 30, Business 60):

- events: requests, errors, logs, queries, jobs and other records;
- app users, counted from when they were last seen;
- uptime check results.

**Fixed periods:**

| Data | Kept |
|---|---|
| Issues (the grouped error: class, message, file and line) | 90 days after the last occurrence |
| Host check history, crawl summaries, daily uptime for status pages | Up to the longest plan retention (60 days) |
| Details of the latest successful crawl | Until the next successful crawl |
| Alerts | 30 days |
| Alert channel delivery log | The latest 50 deliveries per channel |
| Scheduled tasks that stopped running | Forgotten after 7 days |
| Status page slug of a deleted or renamed page | Reserved for the team for 30 days |

**Kept until you delete them** (they don't follow the plan's retention):

- deploys, up to the latest 1,000 per project per source;
- monitors, status pages and their notices, alert channels and project settings.

After a downgrade or cancellation, records keep the retention of the previous plan for 30 more days, and team owners get an email before that ends. Deleting a project or team deletes its data right away.

## Deletion at the end

At the end of the agreement, you choose whether we return or delete your data:

- **Return**: export it through the [API](/docs/api/), or ask us for a copy in JSON, during the retrieval period in the terms' [Switching and export](/legal/terms/#switching-and-export) section.
- **Delete**: delete the project, team or account in the app, or ask us to. A team with a running subscription can be deleted once the paid period has ended.

If you make no choice, we delete your data after the retrieval period. Deleted data leaves the live database at once and the backups within about 30 days. We keep no copies unless EU or Dutch law requires us to.

## Liability

The liability limits of the [Terms of service](/legal/terms/#liability) apply to claims between you and us under this DPA, including recourse claims under art. 82(5) GDPR. They don't limit the rights of data subjects. Each party bears the administrative fines imposed on it.

## Contact

Questions about this DPA or about your data: [info@niomedia.nl](mailto:info@niomedia.nl).
