Supercommerce API Docs
Vendor API

Notifications Module — Vendor surface

Vendor-facing HTTP surface for mobile device registration so the vendor app can receive push notifications (new-order alerts, payout updates, application status, etc.). The wider…

Vendor-facing HTTP surface for mobile device registration so the vendor app can receive push notifications (new-order alerts, payout updates, application status, etc.). The wider notifications module is event-driven — it listens for domain events, resolves recipients, renders templates, and dispatches to FCM/email — but the only vendor-callable endpoints register/unregister an FCM token bound to the logged-in user's vendor app.

Source: api-modules/notifications/src/controllers/vendor-device.controller.ts.


Conventions

Authentication

Both endpoints require a Better-Auth bearer session.

Authorization: Bearer <session-token>

Devices are scoped by session.user.id (not by active vendor). A single user who is a member of multiple vendor organizations re-uses the same device row — push delivery happens based on the event payload, not the registration call.

Tenant scoping

The device row is stamped with appKind: "vendor" so the platform can address the vendor audience separately from the storefront customer audience. The same physical device may register both a "customer" row (via /store/devices) and a "vendor" row (via this surface) when the same OS account uses both apps.

Response envelope

{
  "data": <payload>,
  "message": "Success",
  "statusCode": 200,
  "metadata": { /* optional */ }
}

Error envelope

statusCodeerrorCode examples
400BAD_REQUEST, VALIDATION_ERROR
401UNAUTHORIZED
500INTERNAL_SERVER_ERROR

Domain types

DeviceResponse

type DeviceResponse = {
  id: string;
  platform: "android" | "ios";
  appKind: "vendor";
  lastSeenAt: string;                  // ISO
};

Vendor devices

Base path: /vendor/devices. The vendor app registers its FCM token after login and is expected to call DELETE on logout to stop unrelated pushes leaking to a shared device.

POST /vendor/devices — Register vendor device

Idempotent upsert keyed by (userId, token) — re-registering the same token refreshes lastSeenAt instead of creating a duplicate row. The row is stamped with appKind="vendor".

Body

{
  "platform": "android",               // "android" | "ios"
  "token": "fcm_abcdef..."             // 10..4096 chars, FCM registration token
}
FieldTypeConstraints
platform"android" | "ios"Required
tokenstringTrimmed; 10..4096 chars

Response 201DeviceResponse.

{
  "data": {
    "id": "01J9...",
    "platform": "android",
    "appKind": "vendor",
    "lastSeenAt": "2026-05-13T09:14:22.000Z"
  },
  "message": "Success",
  "statusCode": 201
}

Errors

StatusCodeWhen
400VALIDATION_ERRORBody fails zod (bad platform, token too short)
401UNAUTHORIZEDNo session

DELETE /vendor/devices — Unregister vendor device

Idempotent: deleting an unknown token is a 200 with { ok: true }. The token is matched only against rows owned by the calling user — cross-user tokens silently return the same ok body (no leak of token existence).

Body

{ "token": "fcm_abcdef..." }
FieldTypeConstraints
tokenstringTrimmed; 1..4096 chars

Response 200

{ "data": { "ok": true }, "message": "Success", "statusCode": 200 }

Errors

StatusCodeWhen
400VALIDATION_ERRORBody fails zod
401UNAUTHORIZEDNo session

What the vendor app actually receives

The vendor app does not subscribe to channels through this surface — push and email recipients are resolved server-side from domain events. The events that produce a vendor-targeted push or email today include:

EventChannelTypical content
order.placedemail + push"New order on <product>"
order.vendor.cancelled (when admin-initiated)emailOrder was cancelled by admin
vendor.application.approved / .rejectedemailOnboarding decision (sent to the applicant user)
Payout lifecycle eventsemailManual-admin payout flow updates

The full event catalogue, audience-resolution rules, and broadcast (admin push/email) endpoints live in notifications.md — they are not callable from the vendor surface.


  • authuserId on the device row references the Better-Auth user.
  • notifications-push-fcm — provider module that actually dispatches to FCM using these device rows.
  • order — emits the order.* events that produce vendor-targeted pushes. See order.md.
  • vendor — emits vendor.application.* events that produce onboarding emails. See vendor.md.

On this page