BIO.RE
Notifications

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.

HeaderRequiredNotes
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

FieldTypeNotes
idstring (UUID)WebPushSubscription.id — pass to subscription-specific server-side ops (none currently exposed client-side)
endpointstringThe provider-specific push endpoint URL (provider varies by browser; treat as opaque)
createdAtstring (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

HTTPcode / i18nKeyReason
401(guard)Missing / invalid bearer token

Side effects

  1. prisma.webPushSubscription.findMany({ where: { userId, active: true }, select: { id, endpoint, createdAt }, orderBy: createdAt desc, take: 100 }).
  2. 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

GET
/api/v1/notifications/webpush/subscriptions

Response Body

curl -X GET "https://loading/api/v1/notifications/webpush/subscriptions"
Empty
Empty

Source

SourcePathLines
Controllerapps/api-core/src/modules/notification/webpush.controller.ts68–75 (listSubscriptions)
Serviceapps/api-core/src/modules/notification/webpush.service.ts69–76 (getActiveSubscriptions)
Prisma modelpackages/prisma/prisma/schema.prismaWebPushSubscription (server-only fields excluded from select: p256dh, auth, userAgent)

On this page