List Web Push Subscriptions
Read the calling user's active web push subscriptions. Returns up to 100 rows ordered newest-first. Public-safe slice — keys NOT exposed.
GET /api/v1/notifications/webpush/subscriptions — 🔑 Bearer
Returns the calling user's active WebPushSubscription rows (active: true), ordered by createdAt DESC, capped at 100. Each row exposes only the public-safe slice (id, endpoint, createdAt) — the p256dh / auth keys are kept server-side and never returned.
Use this to drive a "Connected devices" UI in account settings: render one row per subscription, optionally show a label derived from the endpoint's provider host (e.g. "Chrome on macOS" can't be inferred reliably — only an opaque endpoint URL is available; the original userAgent was captured at subscribe time but is not exposed by this endpoint).
Inactive subscriptions are excluded. Rows with active: false (after unsubscribe) are not returned. To see them you'd need an admin endpoint or direct DB access — there's no client-facing "show inactive" toggle.
Request
No body, no params.
| Header | Required | Notes |
|---|---|---|
Authorization: Bearer <accessToken> | ✓ | JWT from POST /auth/login |
Response
200 OK
{
"subscriptions": [
{
"id": "ws1a2b3c4-d5e6-7890-abcd-ef1234567890",
"endpoint": "https://push.example.com/abc123...",
"createdAt": "2026-04-29T20:00:00.000Z"
}
]
}(Not wrapped in ApiResponseOf<T> — the controller returns the bare object.)
Item fields
| Field | Type | Notes |
|---|---|---|
id | string (UUID) | WebPushSubscription.id — pass to subscription-specific server-side ops (none currently exposed client-side) |
endpoint | string | The provider-specific push endpoint URL (provider varies by browser; treat as opaque) |
createdAt | string (ISO 8601) | When the subscription row was created |
Excluded fields
The following are stored server-side but never returned by this endpoint:
p256dh/auth— cryptographic keys (server-only; required for dispatch but never re-exposed)userAgent— captured at subscribe time, kept for support trails but not surfaced
Errors
| HTTP | code / i18nKey | Reason |
|---|---|---|
401 | (guard) | Missing / invalid bearer token |
Side effects
prisma.webPushSubscription.findMany({ where: { userId, active: true }, select: { id, endpoint, createdAt }, orderBy: createdAt desc, take: 100 }).- Return
{ subscriptions }. No mutations.
Code samples
curl https://api.bio.re/api/v1/notifications/webpush/subscriptions \
-H "Authorization: Bearer $ACCESS_TOKEN"type WebPushSubscriptionItem = {
id: string;
endpoint: string;
createdAt: string;
};
async function listWebPushSubscriptions(accessToken: string): Promise<WebPushSubscriptionItem[]> {
const res = await fetch('https://api.bio.re/api/v1/notifications/webpush/subscriptions', {
headers: { Authorization: `Bearer ${accessToken}` },
});
const json = await res.json();
if (!res.ok) {
throw new Error('Subscriptions fetch failed');
}
return json.subscriptions as WebPushSubscriptionItem[];
}import { useQuery } from '@tanstack/react-query';
export const notificationKeys = {
webpushSubscriptions: () => ['notifications', 'webpush', 'subscriptions'] as const,
};
export function useWebPushSubscriptions() {
return useQuery({
queryKey: notificationKeys.webpushSubscriptions(),
queryFn: async () => {
const res = await fetch('/api/v1/notifications/webpush/subscriptions');
if (!res.ok) throw new Error('Subscriptions fetch failed');
const json = await res.json();
return json.subscriptions as WebPushSubscriptionItem[];
},
staleTime: 60_000,
});
}Try it
curl -X GET "https://loading/api/v1/notifications/webpush/subscriptions"Source
| Source | Path | Lines |
|---|---|---|
| Controller | apps/api-core/src/modules/notification/webpush.controller.ts | 68–75 (listSubscriptions) |
| Service | apps/api-core/src/modules/notification/webpush.service.ts | 69–76 (getActiveSubscriptions) |
| Prisma model | packages/prisma/prisma/schema.prisma | WebPushSubscription (server-only fields excluded from select: p256dh, auth, userAgent) |
Unsubscribe Web Push
Soft-deactivate a single web push subscription by endpoint. Ownership-checked. Server keeps the row (active=false) for forensic / re-subscribe-detection.
Get Load Packages
Public list of suggested wallet top-up amounts plus the absolute min/max limits and active currency. Drives the load-amount picker in the wallet UI.