Preferences
The event catalog, and muting or rerouting each event per channel.
Preferences answer one question per event: should this fire for me, and on which channels? Defaults are sensible — critical failures email you, routine progress stays in-app — and everything overridable can be muted or rerouted.
The event catalog
The catalog is the machine-readable list of every event you can customize, plus the categories, severities, and channels to render them with. It's what the Settings page is built from — build your own UI from the same call:
curl "$API_BASE/v1/notifications/preferences/catalog" \
-H "Authorization: Bearer $TOKEN"from predictai import PredictAI
client = PredictAI(token="pa_live_…")
data = client.notifications.get_notifications_preferences_catalog()
import { PredictAI } from "@predictai/sdk";
const client = new PredictAI({ token: "pa_live_…" });
const data = await client.notifications.getNotificationsPreferencesCatalog();
{
"data": {
"categories": [
{ "key": "data", "label": "Data", "icon": "cloud_upload", "description": "Imports, ingestion, schema drift" },
{ "key": "modeling", "label": "Modeling", "icon": "model_training", "description": "Training runs, foundation models, adapters" },
{ "key": "deployments", "label": "Deployments", "icon": "rocket_launch", "description": "Model deployment, inference health" },
{ "key": "alerts", "label": "Goal Alerts", "icon": "notifications_active", "description": "Your custom alert rules on goal forecasts" },
…
],
"severities": [
{ "key": "info", "color": "info", "icon": "info" },
{ "key": "success", "color": "success", "icon": "check_circle" },
{ "key": "warning", "color": "warning", "icon": "warning" },
{ "key": "critical", "color": "error", "icon": "error" }
],
"events": [
{
"event_code": "training.failed",
"category": "modeling",
"severity": "critical",
"transactional": false,
"user_can_override": true,
"default_channels": ["in_app", "email"],
"title": "Training failed",
"description": "stopped: ."
},
{
"event_code": "billing.balance_exhausted",
"category": "billing",
"severity": "critical",
"transactional": false,
"user_can_override": true,
"default_channels": ["in_app", "email"],
"title": "Credit balance exhausted",
"description": "Your credit balance is at zero. Trainings, inferences and subscriptions are paused until you top up."
},
…
],
"channels": [
{ "key": "in_app", "label": "In-app", "requires_setup": false },
{ "key": "email", "label": "Email", "requires_setup": false },
{ "key": "websocket", "label": "WebSocket", "requires_setup": false },
{ "key": "slack", "label": "Slack", "requires_setup": true },
{ "key": "teams", "label": "Microsoft Teams", "requires_setup": true },
{ "key": "pagerduty", "label": "PagerDuty", "requires_setup": true },
{ "key": "webhook", "label": "Webhook", "requires_setup": true }
]
}
}A few things to know about the shape:
- Only overridable events appear. Transactional and security-critical events (payment receipts, sign-in links, new-device alerts) always deliver on their defaults and are omitted — there's nothing to toggle.
descriptionis the event's message template with its variable placeholders stripped, so some read as fragments ("stopped: ."). Treat it as a rough summary, not display copy.requires_setup: truechannels only actually deliver once you've configured an endpoint of that type. Enabling one without an endpoint is a harmless no-op.
Get your preferences
Returns every overridable event with your overrides merged over the defaults — one round-trip renders a complete settings page:
curl "$API_BASE/v1/notifications/preferences" \
-H "Authorization: Bearer $TOKEN"from predictai import PredictAI
client = PredictAI(token="pa_live_…")
data = client.notifications.get_notifications_preferences()
import { PredictAI } from "@predictai/sdk";
const client = new PredictAI({ token: "pa_live_…" });
const data = await client.notifications.getNotificationsPreferences();
{
"data": {
"events": {
"training.completed": { "enabled": true, "channels": ["in_app"] },
"training.failed": { "enabled": true, "channels": ["in_app", "email", "pagerduty"] },
"deployment.promoted": { "enabled": true, "channels": ["in_app"] },
"billing.balance_low": { "enabled": false, "channels": ["in_app", "email"] },
"alerts.goal_alert_critical": { "enabled": true, "channels": ["in_app", "email", "slack"] },
…
}
}
}Each entry is per-event and per-channel: enabled is the kill switch
for the event, channels is where it goes when it fires.
Update your preferences
PUT the same shape back. The body replaces your stored overrides — round-trip the full map from GET, mutate what you want, and send it back:
curl -X PUT "$API_BASE/v1/notifications/preferences" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"events": {
"training.completed": { "enabled": false },
"training.failed": { "enabled": true, "channels": ["in_app", "email", "pagerduty"] }
}
}'from predictai import PredictAI
client = PredictAI(token="pa_live_…")
data = client.notifications.put_notifications_preferences(json={
"events": {
"training.completed": {"enabled": False},
"training.failed": {
"enabled": True,
"channels": ["in_app", "email", "pagerduty"],
},
},
})
import { PredictAI } from "@predictai/sdk";
const client = new PredictAI({ token: "pa_live_…" });
const data = await client.notifications.putNotificationsPreferences({
json: {
events: {
"training.completed": { enabled: false },
"training.failed": {
enabled: true,
channels: ["in_app", "email", "pagerduty"],
},
},
},
});
| Field | Meaning |
|---|---|
events required | A map of event_code → override. Each override takes enabled (the kill switch, defaults to true) and channels (where it delivers; omitted means the event's default_channels). |
The response is your complete merged preference map — identical in shape
to GET /preferences — so you can re-render immediately.
Validation is forgiving by design: event codes that aren't in the catalog, events you can't override, and channel names the platform doesn't recognize are silently dropped rather than rejected. If a toggle doesn't seem to stick, diff your PUT body against the catalog.
Omitted fields fall back per event: no channels means the event's
default_channels; no enabled means true.

