Privacy Policy
Effective date: 22 June 2026
This policy explains how anpasio UG (“buoycal”, “we”) processes personal data when you use the hosted buoycal service at buoycal.com.
This policy covers the hosted service only. If you self-host buoycal from the open-source repository, you (or whoever runs your instance) are the controller of the data on your own machine, and this policy does not apply to that deployment. The engine’s behaviour, what it reads and what it never writes down, is the same code in either case; only the controllership changes.
We have tried to write this in plain language. Where a paragraph carries legal weight, such as the lawful basis we rely on or the period for which we keep something, we say so.
1. Who we are and how to reach us
Controller under Art. 4(7) GDPR:
anpasio UG (haftungsbeschränkt)
Mühlenaue 15a
53909 Zülpich, Germany
Represented by: Philipp Franke
Commercial register: Amtsgericht Köln, HRB 118550
VAT ID: DE367743908
For any privacy question, request, or concern, including the rights described in §9, write to hello@buoycal.com.
We have not appointed a Data Protection Officer. We are not required to under Art. 37 GDPR or §38 BDSG: we are a micro-entity, we do not carry out large-scale special-category processing, and our processing does not require a Data Protection Impact Assessment. Privacy enquiries are answered at the address above.
2. What buoycal does
buoycal copies the busy signal from one of your calendars into another so you can keep separate calendars in sync without sharing meeting details across them. We read your source calendar through an API and write a content-free block to your destination calendar.
The block on the destination calendar carries no source content. It has a start time, an end time, and a kind word: Busy, Out of office, or Focus. It does not contain the original meeting’s title, attendees, description, or location. You can configure a block to surface a little more, for example that you are remote or on site, or your RSVP status, but that material is generated from source-free signals you choose to reveal, never copied verbatim from the original event.
3. What we read, and what we keep
3.1 The data we hold on disk
To operate the service we store, in our database hosted in Germany:
- Your account email, which is also the address you sign in with.
- The OAuth tokens that let us reach your calendars at Google and Microsoft, and the app passwords you give us for CalDAV servers (iCloud, Fastmail, Nextcloud, your own). These are encrypted at rest with strong authenticated encryption, cryptographically bound to the row so a stolen ciphertext cannot be replayed against a different account or table.
- Your sync configuration: which calendars you connected, what you named them, the when/then rules you set. This is content-free; no event data is captured here.
- Activity records for the syncs we run on your behalf: timestamps, counts, content-free status labels, skip and abort reasons. No event titles, descriptions, attendees, or locations appear here.
- Push-subscription metadata from Google and Microsoft, so we are notified when your calendars change. This is provider IDs and expiry times, not calendar contents.
- Billing identifiers: a Stripe customer ID, subscription status, and your billing address and VAT ID if you provided one. Card details never reach us; they stay at Stripe.
3.2 What never reaches disk
When we run a sync, the worker reads the minimum it needs to decide whether a busy block should appear on your destination calendar and what to call it. From source events we read:
- start and end times, and the all-day flag;
- the title, transiently in memory, only to evaluate your rules and pick the block kind;
- your own RSVP status on the event;
- two binary flags: whether the event has a location, and whether it has a conferencing link.
We do not read attendee names or email addresses, organiser identity (only whether the organiser is you), or location text. For CalDAV calendars we also read the event description on the round-trip, but only to recognise the buoycal-written marker so we update the same block instead of duplicating it.
Once the busy block is computed, the source event is discarded from memory. No event title, description, attendee list, or location is ever written to our database, our logs, our metrics, or anywhere else. This is not a promise layered on an otherwise unconstrained system: the database schema cannot represent event content, and our build pipeline rejects any code change that would introduce such a field.
Because rule-matching reads the title, a title you wrote may occasionally contain something sensitive, such as a clinic’s name, a support group, or a religious observance. We match it only to choose the content-free block to write, and never look for, infer, store, or act on anything sensitive in it; the title is then discarded with the rest of the event. So nothing about your health, beliefs, or other special categories (Art. 9 GDPR) is ever recorded.
3.3 Other people in your calendar
Some of the events on a calendar you sync were created by other people. From those events we read only your RSVP status and a boolean for whether you yourself organised the event. Both are facts about you, not about them. We never read attendee names, attendee email addresses, organiser identity beyond the “is it me?” boolean, or location text. Nothing about third parties is persisted, logged, or forwarded.
Under Art. 14(5)(b) GDPR we do not notify those individuals separately because doing so would require disproportionate effort and because the data is minimal, transient, and never written down. We describe the categories and source here for transparency.
3.4 Connection and technical data
Like any online service, we receive your IP address and basic details of each request, such as which page you asked for, and when. We keep your IP only in shortened form (never the full address), in short-lived logs that are deleted within 30 days, and we use it solely to run and protect the service (our legitimate interest, Art. 6(1)(f)). Clerk (sign-in) and Stripe (payments) also receive your IP address through their own systems; see §7.
4. Why we are allowed to do this (Art. 6 GDPR)
| Activity | Lawful basis |
|---|---|
| Holding your account, your configuration, and your credentials, and running the syncs you asked us to run | Art. 6(1)(b), performance of our contract with you |
| Keeping the service secure, preventing abuse, and emailing you when a sync breaks so you can re-authorise | Art. 6(1)(f), our legitimate interests, balanced against yours |
| Billing, invoicing, and meeting our German tax-retention obligations | Art. 6(1)(b) and Art. 6(1)(c) |
| The one strictly-necessary session cookie that keeps you signed in | Art. 6(1)(b)/(f) |
| The incidental data about third parties described in §3.3 | Art. 6(1)(f), the interest in delivering the sync you asked for |
Providing your account email and connecting a calendar are necessary to use buoycal. They are part of your contract with us, and without them we cannot create your account or run a sync. You are under no statutory obligation to provide this data; the only consequence of withholding it is that the service cannot run for you.
We do not rely on consent under Art. 6(1)(a) for any of the above. Granting OAuth access at Google or Microsoft is part of performing the contract you opened with us, not a separate consent transaction. We do not seek out or record special-category data (Art. 9): as §3.2 explains, a title we read in passing may occasionally contain sensitive details, but we use it only to choose a content-free block and never store or infer anything from it. We have screened the service under Art. 35 GDPR. No Data Protection Impact Assessment is mandatory, because event content is never stored, there is no profiling, and no automated decisions of legal or significant effect are made.
The balancing test for the legitimate-interests basis above turns on the same facts as the rest of this policy: the data is minimal and content-free, the only recipient of an alert email is you, there is no profiling, and the right to object (Art. 21) is available, since you can pause or disconnect at any time.
5. How long we keep things (Art. 5(1)(e), 13(2)(a))
| Data | How long we keep it |
|---|---|
| Account, configuration, and credentials | For as long as your connection exists. Deleted when you disconnect or delete your account (see §6). |
| The activity log of sync runs, for active accounts | 90 days, rolling. Older entries are deleted automatically. |
| Server access logs (masked IP plus basic request data) | Rotated by size and time, and deleted within 30 days. |
| Tenant rows after account deletion (terminated or lapsed) | Tombstoned immediately, then hard-purged after 60 days. |
| Billing identifiers | 8 years for invoices and accounting documents (§147 AO, §257 HGB; period in force since 1 January 2025). Non-statutory billing data, such as the Stripe customer ID, is deleted approximately 60 days after account deletion. |
| Push subscriptions to Google/Microsoft | Self-expiring (about 24 hours at Google, about 7 days at Microsoft); renewed while active, removed when the connection is torn down. |
| Encrypted database backups | 14 days, then aged out. |
6. Deleting your account, revoking access
You can delete your account from the dashboard. When you do, the following happens, in order:
- Every buoycal-written block on your destination calendars is swept off. This is best-effort: if a calendar is unreachable, your erasure is not held up by it.
- For Google, each refresh token is revoked at Google’s
/revokeendpoint before the token is deleted from our database. - For Microsoft, no app-callable token-revocation endpoint is exposed to a delegated-only client, so destroying the stored ciphertext is the erasure step. You can also revoke at account.live.com/consent/Manage if you want belt-and-braces.
- All your child records are deleted; your tenant row is tombstoned and your email is set to NULL on it.
- After 60 days the tombstoned row is hard-purged.
Disconnecting a single calendar
If you disconnect one Google calendar without deleting your account, we delete the stored token, but we do not at present also call Google’s revoke endpoint for that single grant. Only full account deletion revokes at Google. If you want to revoke an individual grant immediately, you can do so at myaccount.google.com/permissions.
Erasure and backups
When you delete your account, your data leaves the live database immediately. It remains in our encrypted backups until they age out of the 14-day window. If we ever restore from backup, the deletion is reapplied so that a deleted account is not silently revived.
7. Who else handles your data (sub-processors)
We rely on the following sub-processors. Each has a written agreement with us under Art. 28 GDPR where one is required.
| Recipient | What for | Personal data they see | Location | Transfer basis |
|---|---|---|---|---|
| Hetzner Online GmbH | Hosting and encrypted database backups | All hosted data (credentials encrypted at rest; backups encrypted before leaving the host) | Germany (EU) | None required (EU) |
| Grafana Labs | Service observability (operational metrics) | Content-free metric labels only: enums such as queue state and provider. No tenant ID, no email, no event data. | EU (Germany stack) | None required (EU) |
| Clerk, Inc. | Authentication, and the SSO broker for “Sign in with Google/Microsoft” | Sign-in email, identity claims from social sign-in, Clerk user ID, and connection/session data (IP address, device and session details) used to sign you in and keep your session secure | USA | EU–US Data Privacy Framework; Standard Contractual Clauses as fallback |
| Stripe Payments Europe, Ltd. (SPEL) | Payment execution and billing. Stripe acts as our processor for executing payments on our instruction, and as an independent controller for fraud prevention, card-network compliance, and its own PCI/regulatory duties. | Billing/invoice data, billing address, VAT ID, Stripe identifiers. Card data never reaches us. | Ireland (EU) | None required for the contract (EU). Stripe’s onward transfers to its US affiliates are covered by Stripe’s own EU–US Data Privacy Framework certification, with SCCs as fallback. |
| Resend, Inc. | Sending the transactional email that tells you a sync has failed | Your own account email; the subject and body are content-free | USA | EU–US Data Privacy Framework; SCCs as fallback |
| Google LLC | (a) Google Calendar API, accessed under your OAuth grant when you connect a Google calendar; (b) optional “Sign in with Google”, brokered through Clerk | (a) calendar data within the scopes you granted; (b) email and name as identity claims at sign-in | USA | EU–US Data Privacy Framework; SCCs as fallback |
| Microsoft Corporation | (a) Microsoft Graph for Outlook / Microsoft 365 calendars when connected; (b) optional “Sign in with Microsoft”, brokered through Clerk | (a) calendar data within the scopes you granted; (b) email and name as identity claims at sign-in | USA | EU–US Data Privacy Framework; SCCs as fallback |
Google and Microsoft are not our Art. 28 sub-processors in either flow. When you connect a calendar, buoycal acts on your OAuth grant to your account at the provider, so you hold the direct controller relationship with them, governed by their own terms (Google’s API Services User Data Policy / Limited Use; Microsoft’s Graph publisher terms). When you sign in with Google or Microsoft, they act as independent identity providers under their own terms, passing identity claims (email, name) through Clerk. We list them here for transparency.
8. International transfers (Art. 44–49 GDPR)
The sub-processors marked USA above receive personal data outside the EU. We rely on the EU–US Data Privacy Framework (DPF) as the primary transfer mechanism, and each US recipient above is an active DPF participant. As a fallback, our contracts incorporate the European Commission’s Standard Contractual Clauses together with a transfer-impact assessment.
The adequacy decision underlying the DPF was upheld by the General Court of the EU on 3 September 2025 (Case T-553/23) and is currently subject to a pending appeal at the Court of Justice (Case C-703/25 P). We monitor that appeal and will update this policy if the legal basis changes.
Residual risk for US transfers. Even with the DPF and SCCs in place, two US laws can reach data held by US providers and, in some cases, their EU subsidiaries. FISA Section 702 lets US intelligence services compel “electronic communications service providers” to disclose data about non-US persons. The CLOUD Act (18 U.S.C. § 2713) lets US authorities require disclosure of data held by US companies and their controlled subsidiaries abroad, including encryption keys held by the provider. The DPF was designed to address FISA 702 through the Data Protection Review Court (DPRC), but the redress mechanism is untested. We mention this not because we expect it to be invoked against the data we hold (account email, encrypted credentials, content-free metadata, all of limited target value), but because Art. 13(1)(f) and EDPB transfer guidance expect us to.
EU sub-processors (Hetzner; Grafana Cloud’s EU stack) do not require a transfer mechanism; your data stays inside the EU. Stripe is also contracted through an EU entity (SPEL, Ireland), so the contract itself is EU-internal; however, Stripe’s group operations may onward-route data to its US affiliates, where Stripe’s own DPF certification (with SCCs as fallback) governs the onward transfer.
9. Your rights (Art. 15–22 GDPR)
You have the following rights under the GDPR. We respond to requests within one month of receipt (extendable by two further months for complex or numerous requests, with notice to you), free of charge save for the exceptional manifestly-unfounded case. We will verify your identity against your account before releasing data; if we cannot, we may ask you for further information (Art. 12(6) GDPR).
- Information (Art. 13/14): what you are reading.
- Access (Art. 15): request a copy of the personal data we hold about you.
- Rectification (Art. 16): correct your email or profile in the dashboard, or ask us to fix anything you cannot edit yourself.
- Erasure (Art. 17): delete your account from the dashboard, as described in §6.
- Restriction (Art. 18): pause connections in-app, or write to us for anything broader.
- Portability (Art. 20): the configuration you provided is downloadable from the dashboard as a structured file. For the residual account metadata, write to us.
- Objection (Art. 21): you can stop the only Art. 6(1)(f) processing we do by pausing or disconnecting, and we will not subject you to alerts you cannot stop.
- No solely-automated decisions (Art. 22): we do not profile you and we make no decisions about you by automated means alone.
If you believe we have processed your data unlawfully, you may lodge a complaint with our supervisory authority:
Landesbeauftragte für Datenschutz und Informationsfreiheit Nordrhein-Westfalen (LDI NRW)
Kavalleriestraße 2–4, 40213 Düsseldorf, Germany
www.ldi.nrw.de
You may also complain to the supervisory authority of your habitual residence or place of work.
10. Sign-in providers
You can create your buoycal account with an email and password, or with “Sign in with Google” or “Sign in with Microsoft”. When you choose social sign-in, Google or Microsoft act as independent identity providers under their own terms, passing identity claims (your email and name) through our authentication processor Clerk. This is separate from connecting a calendar: your sign-in identity is deliberately decoupled from any calendar grant you make later, and you can sign in with one account while syncing calendars from a different one.
11. Cookies
We use one strictly-necessary cookie: the Clerk __session cookie that keeps you signed in to the dashboard. No advertising cookies, no analytics cookies, no third-party tracking scripts. Because no non-essential cookies are set, no consent banner is required.
When you connect a calendar via OAuth, Google or Microsoft show you a consent screen listing the scopes we request. That consent is given to them, not to us, and it can be withdrawn from your Google or Microsoft account at any time.
12. Security of processing (Art. 32 GDPR)
Beyond the standard “we take security seriously”:
- OAuth tokens and CalDAV passwords are encrypted at rest with strong authenticated encryption, cryptographically bound to the row, so a stolen ciphertext cannot be replayed against a different account or table.
- Logs stay on the host. They are rotated by size and time (each file capped, rolled at least daily, and deleted within 30 days) and never shipped off-box. Our application and worker logs carry only pseudonymous tenant identifiers, never event content, third-party emails, or token values. Our reverse-proxy access logs additionally record request metadata (a masked, truncated client IP, user-agent, method, path, status, and timing) but redact the sensitive headers (Authorization, Cookie, Set-Cookie) and strip OAuth credentials from the URL, so your session token, the
__sessioncookie, and authorization codes never appear, and request bodies are never recorded. - Operational metrics are content-free. Labels are enums (queue state, route, status class, provider). No tenant ID, no email, no calendar name, no event.
- Backups are encrypted before they leave the database host; the decryption key is kept on a separate, isolated system.
- Least-privilege OAuth scopes: read-only on source calendars, and on destinations the narrowest writable scope each provider offers. For Microsoft, that scope is broader than we would like (
Calendars.ReadWrite, because Graph offers no app-created-only write scope), so we mitigate by writing only to a dedicated calendar we created.
13. Personal-data breaches (Art. 33–34 GDPR)
If we become aware of a personal-data breach affecting your data, we will notify the LDI NRW within 72 hours unless the breach is unlikely to result in a risk to your rights and freedoms, and we will notify you directly without undue delay where the breach is likely to result in a high risk.
Because tokens are encrypted at rest and event content is never stored, the realistic worst case from a database compromise is encrypted credentials, account emails, and content-free metadata, which is what any notification we sent would describe.
14. AI training, advertising, and selling data
We do not train, and have never trained, machine-learning models on your calendar data, your configuration, or anything else from your account. We do not sell your personal data or share it with advertisers. Our sub-processors are contractually limited to processing your data for the specific purpose listed in §7.
Google’s API Services User Data Policy and its Limited Use requirements, which govern our access to Google Calendar data, prohibit using that data for advertising and for training generalised AI models, and prohibit any sale to third parties. Our use of Google Calendar data complies with that policy.
15. Children
buoycal is a business productivity tool and is not directed at children. We do not knowingly collect personal data from anyone under 16 (or, where lower under local law, the applicable digital-services consent age). If you believe a child has created an account with us, please write to hello@buoycal.com and we will delete the account.
16. Changes to this policy
If we make a material change, such as adding a sub-processor, changing a retention period, or expanding what we collect, we will update this policy and the effective date at the top. For changes that affect account holders materially we will also send an email. Previous versions are available on request.
This policy is published by anpasio UG (haftungsbeschränkt), Mühlenaue 15a, 53909 Zülpich, Germany. Last updated 22 June 2026.