Topics and realtime
Publish messages on topics and subscribe to topics and row-changed feeds over server-sent events.
Base URL: your app's origin ($APP_ORIGIN): the published host, a custom domain, or the platform origin for the builder preview. Errors answer { ok: false, error: { code, message } } unless noted. Add x-appbricx-env: dev or prod to pick the database explicitly; otherwise the host decides (preview means dev, a published host means prod).
Authentication
- App key + data marker
- A project API key (dpk_c_… in browsers, bound to the app's origins; dpk_s_… on servers) or the builder preview token, plus the data-API marker header. With an app session (the header, or the appbricx_app_session cookie) the call acts as that user under row-level security; without one it acts as a guest. A server key may assert x-appbricx-app-user, x-appbricx-app-role and x-appbricx-app-org.
Authorization: Bearer $APP_KEYx-appbricx-data-api: 1x-appbricx-app-session: $APP_SESSION (optional: acts as that user)
Endpoints
Publish on a topic
POST/__appbricx/topics/:name/publish
Publish a message to every subscriber of a topic. app:* and free-form names take any authenticated caller; row-changed:* takes server keys only.
- Auth
- App key + data marker:
Authorization: Bearer $APP_KEYx-appbricx-data-api: 1x-appbricx-app-session: $APP_SESSION (optional: acts as that user)
Path parameters
| Name | Type | Description |
|---|---|---|
:namerequired | string | Letters, digits and _ : . - (e.g. app:kitchen). |
Body
| Name | Type | Description |
|---|---|---|
payloadoptional | any JSON | The message. |
Response
{
"ok": true
}Errors
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHORIZED | Missing or invalid Authorization bearer ("Missing Authorization: Bearer <token>", "Invalid API key"). |
| 400 | PARAMS_INVALID | The x-appbricx-data-api: 1 header is missing. |
| 403 | ORIGIN_NOT_ALLOWED | A browser key used from an origin it isn't bound to (ORIGIN_REQUIRED when there is no Origin at all). |
| 429 | RATE_LIMITED | The project's per-minute request budget is spent (600 for preview tokens and browser keys, 1200 for server keys by default). |
| 400 | TOPIC_INVALID | Bad name. |
| 403 | TOPIC_PUBLISH_FORBIDDEN | row-changed:* without a server key. |
curl -X POST "$APP_ORIGIN/__appbricx/topics/app:kitchen/publish" \
-H "Authorization: Bearer $APP_KEY" \
-H "x-appbricx-data-api: 1" \
-H "x-appbricx-app-session: $APP_SESSION" \
-H "content-type: application/json" \
-d '{"payload":{"order":"1042","status":"ready"}}'const res = await fetch(`${APP_ORIGIN}/__appbricx/topics/app:kitchen/publish`, {
method: "POST",
headers: {
Authorization: `Bearer ${APP_KEY}`,
"x-appbricx-data-api": "1",
"x-appbricx-app-session": APP_SESSION,
"content-type": "application/json",
},
body: JSON.stringify({
"payload": {
"order": "1042",
"status": "ready"
}
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? data.error ?? res.statusText);Source: services/api/src/app-runtime/http/topics-routes.ts:81
Subscribe to a topic
GET/__appbricx/topics/:name/subscribe
A server-sent event stream: event: message with the JSON payload, and a ping every 15 seconds. Browsers' EventSource can't set headers, so this route also takes access_token and app_session as query parameters and doesn't need the data marker.
- Auth
- App key + data marker:
Authorization: Bearer $APP_KEYx-appbricx-data-api: 1x-appbricx-app-session: $APP_SESSION (optional: acts as that user)
Path parameters
| Name | Type | Description |
|---|---|---|
:namerequired | string | app:*, a free-form name, or row-changed:<table> (needs read access to the table). |
Query parameters
| Name | Type | Description |
|---|---|---|
access_tokenoptional | string | The app key, for EventSource. |
app_sessionoptional | string | The user's session, for EventSource. |
Response
text/event-stream.
event: message
data: {"event":"created","table":"tickets"}
event: ping
data:Errors
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHORIZED | Missing or invalid Authorization bearer ("Missing Authorization: Bearer <token>", "Invalid API key"). |
| 429 | RATE_LIMITED | The project's per-minute request budget is spent (600 for preview tokens and browser keys, 1200 for server keys by default). |
| 403 | TOPIC_FORBIDDEN | Unknown namespace, or no read access to the table. |
curl -N "$APP_ORIGIN/__appbricx/topics/row-changed:tickets/subscribe" \
-H "Authorization: Bearer $APP_KEY" \
-H "x-appbricx-data-api: 1" \
-H "x-appbricx-app-session: $APP_SESSION"const res = await fetch(`${APP_ORIGIN}/__appbricx/topics/row-changed:tickets/subscribe`, {
headers: {
Authorization: `Bearer ${APP_KEY}`,
"x-appbricx-data-api": "1",
"x-appbricx-app-session": APP_SESSION,
},
});
const reader = res.body!.getReader(); // text/event-streamSource: services/api/src/app-runtime/http/topics-routes.ts:97