Notification and push API
Every endpoint on this page is under /api/v1, but it spans two identity surfaces that are not interchangeable:
The current OpenAPI reference remains the source of truth for fields, enums, and response schemas.
Prepare a trusted service
- Create an active API Client in Admin, with an expiration and optional CIDR policy.
- Grant
notify.message.submit; status queries also requirenotify.message.status.read. - An all-active-app-user audience additionally requires
notify.message.broadcast. - A
news_operationssubmission additionally requiresnotify.operations.publish. - Explicitly allow the target app for the API Client. An empty app allowlist denies all apps.
- Exchange credentials at
/auth/client-tokenfor a short-livedak-apiJWT. A Machine Principal receives no refresh token.
Submit a notification
Endpoint: /apps/{app_id}/notifications
Success returns 202 Accepted with message_id, run_id, current status, status_url, and creation time. This means the asynchronous pipeline accepted the submission—not that a provider or device received it.
Choose exactly one content union: a template or controlled bilingual inline content. The request does not accept raw tokens, arbitrary URLs, component names, scripts, or provider-specific payloads.
Idempotency and cancellation
Idempotency-Key is 8–255 characters. The current service scopes it by tenant and caller identity (the API Client for M2M), so one API Client must generate globally unique keys across every app and source it can access. The same key and normalized body return the original submission; a different body under the same key returns 409 NOTIFY.IDEMPOTENCY.CONFLICT.
- Read status:
/apps/{app_id}/notifications/{message_id} - Cancel:
/apps/{app_id}/notifications/{message_id}/cancel
Status includes recipient, evaluated, device delivery, provider accepted, failed, invalid token, skipped, and opened counts. Cancellation can stop only a notification that has not entered publishing or fanout; provider-accepted notifications cannot be recalled.
Current-user Mobile endpoints
These calls use an ak-mobile bearer token and the current app context:
A registration includes provider, platform, build variant, token, normalized locale, SDK version, and app version. Tenant, app, user, and business device identity come from the verified session and app context; the response never returns the token.
Internal Go integration
Inside the modular monolith, business modules should depend on server/internal/platform/notification.Service:
Use SubmitTx when a notification must commit atomically with a business fact. A trusted caller or authentication middleware constructs Scope; never copy tenant, app, or actor from an HTTP body. Business modules must not write notify.* tables or insert River jobs directly.
Common errors
Logs and audit events do not store access tokens, device tokens, or full message payloads. See Notification operations for runtime status and failure handling, and Notification architecture for asynchronous semantics.