Docs
SDK API

On this page
The SDK calls a versioned JSON API at /api/v1/sdk. A public key identifies the app and the environment. The client can load delivery configuration, save a device, read it back, update its push permission, list the notifications delivered to that subscriber, record one open for a delivered notification, report one click for a delivery, and record an event. A public key cannot send a notification. Sending and the rest of the product use a workspace server API key at /api/v1/public. An event can start an automation that sends to that subscriber when they are in the automation’s segment.
How it works
Routes for the client live under /api/v1/sdk. Every response uses one envelope: a request id, a status, a machine code, a message, a timestamp, and either data or error. The same request id is returned in X-Request-Id.
GET /api/v1 confirms that version 1 is available and returns the SDK and public bases. It does not require a key. GET /api/v1/sdk confirms the SDK base.
POST /api/v1/sdk/deep-links stores the routes for that app. The SDK sends them when the app starts. A later list replaces the stored one. An empty list clears them. Either public key for the app writes the same list.
GET /api/v1/sdk/client-config returns the delivery configuration for that public key. Android includes a status and, when ready, the client options the SDK uses to initialize. It is omitted until a package name is saved. iOS includes the bundle ID once Apple is connected and a bundle ID is saved. Web includes the public key. Expo, and a cross-platform app with neither side saved, returns an empty object. A public key still cannot send.
Save, read, update, and the inbox require X-Notifiable-Key. The value is the app’s development or production public key. That key chooses the environment. A missing, unknown, reset, or deleted-app key is rejected. The same device id in that app and environment updates the existing subscriber, so a retry does not create a second one. A granted permission stores the provider and token. A denied or not-yet-asked permission can be stored before a token exists. A new production subscriber at the workspace cap is rejected. Development is not capped. The first save turns notifications on only when permission is granted. A later permission change does not undo a dashboard unsubscribe. Save, read, and update include prompt_permission. It is true when the dashboard asked that device to be prompted again and permission is still not granted. Sending the same permission again leaves that request in place. Sending prompted: true, or a different permission, clears it. Reading a subscriber does not write.
The inbox lists delivery rows for one subscriber in that app and environment, newest first, 20 per page. Each row includes opened and opened_at. opened=false asks for delivered rows that have not been opened. A notification that was not delivered to that subscriber is not included. The other environment, another app, or a missing subscriber is rejected.
An open is recorded once for a delivery whose status is delivered. A failed, skipped, or pending delivery is rejected. Recording the same open again does not change the first time. The first open also stores one notification_opened event with that delivery id.
A click is one report of the delivery id from opt on that notification’s link. The first report sets clicked_at and stores one notification_clicked event. A second report does not change the first time. A delivery that is not delivered, or that belongs to another app or environment, is rejected.
An event stores a name, the subscriber, and optional properties for that app and environment. It does not send by itself. A saved automation for the same event name sends only when that subscriber is in the automation’s segment. notifiable.record({ event, attribute }) sends name and properties. A string attribute is { value }.
The reference is generated from the route declarations and rendered with Scalar at /docs/api in a local environment. The OpenAPI document is /docs/api.json. The sidebar groups SDK routes (version, client configuration, subscribers, the inbox, and events) apart from server routes (the workspace, its apps, and each app’s environment) and agents routes (platform users).
