How Notifikations works
Private by design. Your raw secret never leaves your device — here's exactly what happens when you send a notification.
The delivery path
Every notification takes the same route from the sender to your screen:
Your webhook URL
When you first open the app, a webhook secret is generated on-device using a cryptographically secure random number generator. It never leaves your device in plaintext.
You get two webhook URLs:
Device webhook
Sends a notification to this device only. Each device has its own unique secret.
User webhook
Sends to every device signed in to your iCloud account at once — fan-out delivery. The response includes a sent count.
What gets stored — and where
The backend stores the minimum required to route a notification. Here's the complete picture:
| Data | Stored by backend | Where | Purpose |
|---|---|---|---|
| APNs push token 1 | yes | Cloudflare KV | Required to address the notification to your device |
| SHA-256 digest of device secret | yes | Cloudflare KV | Verifies incoming webhook requests without storing the secret |
| SHA-256 digest of user secret | yes | Cloudflare KV | Fan-out: maps one user webhook to all their devices |
| Device label (optional) | yes | Cloudflare KV | Human-readable name (e.g. "iPhone 15 Pro") |
| Raw webhook secret | never | Your device + iCloud | Generated on-device, synced only through your private CloudKit database |
| Notification contents | never | — | Pass through in-flight only, never logged or persisted |
| Notification history | device only | On-device (SwiftData) | Stored locally so you can review missed notifications |
1 An APNs push token is a unique, random code Apple gives to each app install so the system knows exactly which device to deliver a notification to — without identifying who you are.
How verification works
When a webhook request arrives at /api/v1/:secret, the worker:
Hashes the secret
Computes SHA-256(secret) from the URL path. This is the only operation performed on your raw secret — it never touches a database or log.
Looks up the digest
Checks Cloudflare KV for a matching digest. If none found, returns 404 webhook not found.
Retrieves the push token
The KV record links the digest to an APNs push token. No secret is stored — only the hash and the token.
Forwards to APNs
The notification payload is signed with the APNs key and sent to Apple. Apple handles delivery, retries, and queuing.
Rotating secrets
If you want to invalidate your current webhook URL and get a new one:
- The app generates a new secret on-device.
- Only the new digest and the old digest are sent to the server — the raw secret is never transmitted.
- The server atomically replaces the old digest with the new one. The old URL stops working immediately.
Syncing across devices
Your raw webhook secrets are stored in your iCloud private database via CloudKit. This data:
- Is tied to your personal iCloud account
- Is end-to-end encrypted by Apple
- Is inaccessible to the Notifikations backend
- Is automatically deleted when you delete the app
This is how the same user webhook URL works across all your devices — each device registers independently, but they all share the same user secret from CloudKit.
Infrastructure
Cloudflare Workers
Webhook verification and APNs forwarding. Runs at the edge, close to the sender.
Cloudflare KV
Stores push tokens and secret digests. Globally replicated, low-latency reads.
Apple CloudKit
Stores your raw secrets in your private iCloud database. Not accessible to us.
Apple APNs
Handles final delivery, retries, and queuing to your device over HTTP/2.