# App integration

How product apps wire into Notifications V2: browser inbox, server-side cross-user publish (API key stays off the SPA), the npm client, and rate limits.

flowchart LR
  SPA["SPA"] -->|"user JWT"| NpmClient["@inovus-medical/notifications"]
  NpmClient -->|"inbox / self"| API["notifications Worker"]
  SPA -->|"app session only"| BFF["Your edge / API route"]
  BFF -->|"X-Api-Key from env"| API

# 1. Browser path (user JWT)

Install the published client:

npm install @inovus-medical/notifications
import { NotificationsClient, createNotificationService } from '@inovus-medical/notifications';

const client = new NotificationsClient({
  baseUrl: 'https://notifications.totumcloud.com',
  getAccessToken: () => auth.getValidAccessToken(),
});

export const notification = createNotificationService(client);
Allowed with user JWT Not allowed
List / mark read / delete own inbox Cross-user publish({ userGuid }) (403)
publishSelf / notification.success(...) to self Shipping PUBLISHER_API_KEYS or M2M secrets in the browser

Full narrative: Publishing — Can an app use a user’s JWT?.
Agent brief: AGENT.md.


# 2. Cross-user path (API key or M2M — server only)

When Assess / a job / a webhook must notify another user:

  1. Hold a publisher credential in server env (NOTIFICATIONS_API_KEY or Cognito M2M client secret).
  2. Call the Worker from that server (or from a small BFF in front of the SPA).
  3. Always set a meaningful dedupeKey.

SPA must not call the Worker with an API key. If the UI triggers “notify surgeon X”, the SPA calls your backend; your backend calls Notifications.

Credential Where it lives
X-Api-Key from PUBLISHER_API_KEYS Worker secret + your BFF/job env — api-keys.md
Cognito M2M + notifications/publish Your job’s secrets — cognito-setup.md

# 3. BFF / edge proxy contract

Minimal pattern (see runnable samples):

Item Detail
Route e.g. POST /api/notifications/publish on your app
Auth Verify the caller with your session / Cognito user JWT (same product pool). Reject anonymous.
Body Same shape as Worker publish: userGuid, title, body, optional severity, actionUrl, dedupeKey, metadata
Outbound NotificationsClient({ baseUrl, apiKey }) or fetch + X-Api-Key to POST /v2/notifications
Never Accept a client-supplied API key; return the key in responses

Samples:

Long-running jobs can skip the BFF and call the Worker directly with the same env-held key.


# 4. Rate limits (abuse mitigation)

Full detail: Rate limiting.

Short version: after auth, inbox/self is capped at 300 requests / 60s per user; cross-user publish at 600 / 60s per publisher. Over the limit → 429 with Retry-After: 60. The npm client retries 429 when retries are allowed.


# 5. Checklist

  • [ ] SPA uses npm client + user token for inbox / self only
  • [ ] Cross-user publish goes through BFF or backend job with env-held key
  • [ ] dedupeKey set on every cross-user publish
  • [ ] Client subscribe() stopped on logout
  • [ ] Handle 429 (client retries by default)