> ## Documentation Index
> Fetch the complete documentation index at: https://secdocs.asikoexpress.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Real-time Notifications

> WebSocket push for in-app notifications and admin alerts

In-app notifications (`GET /v1/notifications` in the reference) are also pushed live over a
Socket.IO connection, so a frontend doesn't have to poll. Every notification that's pushed live
is also persisted — a client that connects late will still see it via the REST endpoint.

## Connecting

Connect through **api-gateway**, not directly to any backend service — exactly like every REST
call. The gateway terminates the WebSocket upgrade and proxies it internally.

```js theme={null}
import { io } from "socket.io-client";

const socket = io("https://asikodevapi.candourit.io", {
  path: "/v1/ws/notifications",
  auth: { token: accessToken }, // the same JWT access token used for REST
  transports: ["websocket"],
});
```

<Warning>
  `path` must be exactly `/v1/ws/notifications` — this is a Socket.IO **path** (an HTTP-routable
  endpoint), not a namespace, since the gateway proxies on the raw path of the WebSocket upgrade
  request.
</Warning>

If you can't set a custom `auth` payload (some Socket.IO client environments can't), pass the
token as a `token` query parameter instead: `?token=<accessToken>`. A connection with no token, or
an invalid/expired one, is disconnected immediately after the handshake.

## Events you'll receive

<ResponseField name="notification" type="event">
  Sent to the connected user whenever a new in-app notification is created for them — the same
  shape as an item from `GET /v1/notifications`.

  ```json theme={null}
  {
    "id": "f8b002df-6857-4aa1-b7cb-ddf9318d5440",
    "userId": "a096a92b-9571-487e-a99c-978ae8d6c5df",
    "title": "You earned 5 points!",
    "content": "You earned 5 points for sharing a product.",
    "readAt": null,
    "createdAt": "2026-08-02T15:48:51.045Z"
  }
  ```
</ResponseField>

<ResponseField name="admin-alert" type="event">
  Sent only to sockets authenticated as `ADMIN` or `SUPER_ADMIN` — an ephemeral ops ping (not
  persisted, not retrievable via REST) for things that need staff attention.

  ```json theme={null}
  {
    "title": "New Wholesale Application - Acme Traders",
    "content": "New wholesale application from Acme Traders (tracking CRA-7806394). Needs review.",
    "createdAt": "2026-08-02T15:52:38.047Z"
  }
  ```
</ResponseField>

## What triggers a push

A `notification` event fires for any account-affecting action with a customer-facing template —
registration, wholesale application status changes, order placed/paid/dispatched/delivered/
cancelled, password changes, and loyalty point awards (leaving a review, referring a friend,
sharing a product). See the [Domain Events Catalog](/domain-events) for the exhaustive list of
which actions currently trigger a notification versus which are defined but not yet wired.

An `admin-alert` fires for a smaller set of events ops needs to react to: new customer
registration, new wholesale application, new order placed, and low stock.
