Installation
Available on GitHub and npm.Usage
Instantiate the Courier client.CourierClient options
| Option | Type | Required | Description |
|---|---|---|---|
| userId | string | Yes | The user to authenticate and whose messages should be fetched. This is the same user ID to which you should send a message. |
| jwt | string | Yes | The access token (JWT) minted for the user. |
| tenantId | string | No | Optional: The tenant to which messages should be scoped. See Inbox and Tenants for more information. |
| apiUrls | CourierApiUrls | No | Optional: REST/GraphQL and inbox GraphQL/WebSocket base URLs. Defaults to US hosts. For EU, see EU and regional endpoints at the end of this page. Type shape: CourierApiUrls under Models. |
| showLogs | boolean | No | Optional: Enable debugging console logs from the Courier SDK. Defaults to process.env.NODE_ENV === 'development'. |
Authentication
To use the SDK, you need to generate a JWT (JSON Web Token) for your user. This JWT should always be generated by your backend server, never in client-side code.JWT Authentication Flow
Your client calls your backend
When your app needs to authenticate a user, your client
should make a request to your own backend (ex.
GET https://your-awesome-app.com/api/generate-courier-jwt).Your backend calls Courier
In your backend endpoint, use your Courier API Key to call the Courier Issue Token Endpoint and generate a JWT for the user.
Development Authentication with cURL
To quickly test JWT generation for development only, you can use cURL to call the Courier Issue Token Endpoint directly.Do not call the Issue Token API from client-side code. Always keep your Courier API keys secure.
Inbox APIs
Use the Courier Inbox APIs to read and update inbox messages. Pass an optionalfilter to getMessages() (and the same shape to getUnreadCounts() — see Unread Counts) to narrow results by tags, archive state, read status, or a creation time lower bound (from, an ISO 8601 datetime string).
Unread Counts
You can show unread badges or totals in a custom UI in three ways: a single global count, batched counts per filter (for tabs or feeds), or theunreadCount field returned with getMessages(). For live updates, connect the inbox WebSocket and refetch counts when message events arrive.
getUnreadMessageCount()
Returns a Promise<number> with the total number of unread inbox messages for the authenticated user. When you pass tenantId to CourierClient, the count is scoped to that tenant.
getUnreadCounts(filtersMap)
Fetches unread counts for several named filters in one GraphQL request. Use this for per-tab or per-feed badges without multiple round trips.
| Argument | Type | Description |
|---|---|---|
filtersMap | Record<string, CourierGetInboxMessagesQueryFilter> | Map from your own dataset ID (e.g. tab key) to the same filters you use with getMessages() (tags, archived, status, from). |
Promise<Record<string, number>> — the same keys as filtersMap, each mapped to an unread count.
If a filter sets status: 'read', the client returns 0 for that key without calling the server (there are no unread messages in a read-only view).
from with other fields so per-tab unread badges only count messages after a cutoff (same ISO 8601 string as getMessages()).
Unread count from getMessages()
getMessages() responses include both count (total messages matching the list filter) and unreadCount. Unless your filter already sets status, unreadCount reflects the unread subset that matches your tags, archived, from, and tenant constraints.
Real-time updates
The SDK does not push a numeric unread total over the socket. Subscribe to inbox message events, then refetch counts (or reload your message list) when relevant events fire.- Call
courierClient.inbox.socket.connect()so the WebSocket is open. - Register listeners with
addMessageEventListener. It returns a function — call it to unsubscribe. - Optionally compare
envelope.eventtoInboxMessageEvent(exported from@trycourier/courier-js).
InboxMessageEvent includes: NewMessage ('message'), Read, Unread, Archive, ArchiveAll, ArchiveRead, Clicked, MarkAllRead, Opened, Unarchive, and Unopened. Listen to whichever events should trigger a refresh in your app.
Preferences APIs
Use the Courier Preferences APIs to read and update user notification preferences per topic. See Preferences for more information.Brands APIs
Use the Courier Brands APIs to read custom brand settings. See Brands for more information.Lists
Use the Courier Lists APIs to subscribe and unsubscribe users to lists. See Lists for more information.Models
Inbox
InboxMessage
InboxAction
CourierGetInboxMessagesQueryFilter
Optional filters for getMessages() and entries in getUnreadCounts(). Fields combine with AND logic.
CourierApiUrls
Shape used for CourierClient apiUrls and for signIn in React / UI packages. For presets, use EU_COURIER_API_URLS or getCourierApiUrlsForRegion() — see EU and regional endpoints.
Preferences
CourierUserPreferencesTopic
CourierUserPreferencesStatus
CourierUserPreferencesChannel
Brands
CourierBrand
EU and regional endpoints
Most apps use Courier’s default US API and inbox hosts. Use this section only if your workspace is on the EU datacenter. By default,CourierClient uses getCourierApiUrlsForRegion('us') when you omit apiUrls. To target EU, use:
EU_COURIER_API_URLS— frozen preset (api.eu.courier.com,inbox.eu.courier.io,realtime.eu.courier.io)getCourierApiUrlsForRegion(region)— returns a copy for'us'or'eu'(safe to tweak one host)DEFAULT_COURIER_API_URLS— US preset (same as'us')
Mint JWTs on your backend against the same region as the client: for EU, use
https://api.eu.courier.com/auth/issue-token (see Create a JWT and EU Datacenter).