Push Notifications API
Web Push subscription lifecycle and sending endpoints
Danvas exposes Web Push subscription and sending endpoints. A provider-accepted push is not a guarantee that a browser displayed or a user acknowledged the notification; delivery outcomes are governed by the notification operations runbook.
sessionAuth__session<token>Clerk session cookie
application/json- body
endpoint*stringPush endpoint URL from the browser
keys*expirationTime?|Optional subscription expiration time in milliseconds
Subscription saved
application/json- response
success?booleancurl -X POST "https://example.com/api/push/subscribe" \
-H "Content-Type: application/json" \
-d '{
"endpoint": "string",
"keys": {
"p256dh": "string",
"auth": "string"
}
}'{
"success": true
}sessionAuth__session<token>Clerk session cookie
application/json- body
endpoint*stringPush endpoint URL from the browser
Subscription removed
application/json- response
success?booleandeleted?booleancurl -X DELETE "https://example.com/api/push/subscribe" \
-H "Content-Type: application/json" \
-d '{
"endpoint": "string"
}'{
"success": true,
"deleted": true
}bearerAuthAuthorizationBearer <token>Clerk JWT token from session
application/json- body
title?stringNotification title
body?stringNotification body text
url?stringDeep link URL when notification is clicked
targetUserId?stringOptional user ID to send to; another user requires admin authentication and must be in the current team
Notification sent
application/json- response
success?booleansent?integerfailed?integerexpired?integercurl -X POST "https://example.com/api/push/send" \
-H "Content-Type: application/json" \
-d '{}'{
"success": true,
"sent": 0,
"failed": 0,
"expired": 0
}Authentication and lifecycle
POST /api/push/subscribecreates or updates the authenticated caller’s current-device subscription.DELETE /api/push/subscriberemoves only the authenticated caller’s subscription identified byendpoint; it cannot delete another user’s subscription.POST /api/push/sendallows self-targeting. Targeting anothertargetUserIdrequires an admin role. The send URL must be a safe relative same-origin path.- Expired subscriptions are removed before send, and stale
404/410provider responses trigger cleanup. Subscribe/unsubscribe and send operations are rate-limited by the current route contracts.
VAPID Keys
Push notifications use VAPID (Voluntary Application Server Identification) for security:
# Environment variables
NEXT_PUBLIC_VAPID_PUBLIC_KEY=<public key>
VAPID_PRIVATE_KEY=<private key>Generate keys with:
npx web-push generate-vapid-keysNotification display
When the browser receives a push, the service worker may display a native notification. Payload URLs must be relative app paths so notification clicks stay same-origin:
self.registration.showNotification(title, {
body,
icon: "/apple-icon.png",
badge: "/favicon.ico",
data: { url }
});Related files
| File | Purpose |
|---|---|
apps/app/src/app/api/push/subscribe/route.ts | Create/update and delete the caller’s subscription |
apps/app/src/app/api/push/send/route.ts | Authenticated push send endpoint |
apps/app/src/app/sw.ts | Service-worker push handling |
packages/notifications/push.ts | Server-side push helper, expiry cleanup, and URL safety |
docs/features/push-subscription-lifecycle.md | Canonical feature contract |