Skip to content
Talk to our solutions team

Notifications API

Omni-channel dispatch, the in-app inbox, notification lists and templates.

For concepts and configuration see the block documentation.

EndpointPurpose
POST /notification/{type}/syncInline send; returns the provider receipt
POST /notification/{type}/asyncQueue to the outbox; a daemon delivers
POST /notify/{type}/syncAs above, alternate path
POST /notify/{type}/asyncAs above, alternate path
POST /notify/multiSend to a user, resolving their channel preferences
POST /notify/listSend to a saved list
{
"templatename": "welcome-onboarding",
"data": { "firstname": "Alex" },
"provider_context": {
"to": [{ "name": "Alex", "email": "[email protected]" }]
},
"idempotency_key": "optional-caller-supplied-key"
}
FieldRequiredNotes
templatenameyesThe template to render
datanoValues substituted into the template
provider_context.to[]for direct sendsExplicit recipients
userfor /notify/multirealm:user-ulid; preferences decide the channel
listfor /notify/listSaved list id
idempotency_keyno, but use itA retry without one is a second real message
EndpointPurpose
PATCH /inapp/userPaginated list of unseen notifications
GET /inapp/user/newUnseen count
PUT /inapp/userMark as seen, by id

GET /inapp/user/new is the one to poll for a badge — it returns a number rather than a page of records. These routes are user-scoped and need an end-user JWT; a service key cannot read another user’s inbox.

EndpointPurpose
POST /notificationlistCreate
GET /notificationlistList
PUT /notificationlistUpdate
DELETE /notificationlist/{id}Delete
GET /template?name=…One template
GET /templateAll templates

Routes accept a service API key, for service-to-service callers authorised through the platform’s agent and bot configuration, or an end-user JWT. The in-app routes require the latter.

Every request carries the platform tenancy headers — X-Kis-Tenant, X-Kis-Product and X-Kis-Environment. They are the partition key for storage, quotas and audit, so a request without them is rejected rather than served against a default tenant.

Errors use the platform’s structured error body: a stable code, a human-readable message, and the request id to correlate against logs and audit.

Send routes accept either credential — an API key or a bearer token:

X-Api-Key: <key>
Authorization: Bearer <token>

The API key is tried first and falls through to the token when absent, so a caller may present whichever suits it. The metadata and in-app routes (/template, /notificationlist, /inapp/user) take a bearer token only.

Send routes are rate limited under named profiles, and the fan-out route has its own:

RoutesProfile
/notify/:type/sync, /notify/:type/async, /notify/multinotify_send
/notify/listnotify_send_fanout
/notificationlist, /template readsnotify_metadata_read
/notificationlist, /template writesnotify_metadata_write
/inapp/user readsnotify_inapp_read
/inapp/user writesnotify_inapp_write

Fan-out is separated deliberately: one /notify/list call can expand into many deliveries, so it is budgeted apart from single sends. A limited response carries retry_after_seconds — honour it. See API conventions.

The four CPET headers scope templates, notification lists and delivery. /notification/* is an alias for /notify/* and behaves identically.

StatusMeaning
400Request parse or validation failure, or an unknown template
401Missing or invalid credentials, as plain text
429Rate limited — read retry_after_seconds
500Unexpected server error, or a delivery provider failed