Overview
Notifications surface async events from across your buyer workspace — campaign health, creative approvals, agent registrations, optimization suggestions, and more — through three channels: in-app (per-user feed), email (personal preferences plus an account address), and Slack (account-scoped webhook). Users manage their own in-app and personal email preferences. Admins manage the account email address, its event list, and Slack. The notification system gives every operator a structured event feed for things they care about — campaign health, creative approvals, agent registrations, optimization suggestions, and more. Each event is delivered to one or more channels (in_app,
email, Slack). Users can opt into supported events; always-on operational alerts
are delivered independently of those personal preferences.
Open the notification inbox in Murph
Buyer and storefront agents can open the Notifications Page in Murph. It lists a bounded page of events, lets you load older results, and keeps Read and Acknowledged as separate states. Both states apply only to the signed-in recipient: reading or acknowledging a broadcast event does not change another person’s inbox. The Page also shows the current primary-Slack settings for Product Updates and sustained source-health alerts. Changing delivery does not mark an inbox event read or acknowledged, and a successful Slack, email, or webhook attempt does not count as either action. Release history stays in the separate Release notes Page. For agent builders, v3open_page({"page":"notifications"}) returns a
persona-specific Page contract. Buyer and storefront operation aliases are
explicit; if the launch contract is missing, the Page waits instead of
silently trying another API surface.
All endpoints below are mounted under
https://api.apostra.com/api/v2/ and are
accessible to both buyer and storefront users (role-agnostic shared router).
The notification feed is filtered server-side by your in_app opt-ins plus
always-on operational event types. A user with no opt-ins can therefore still
see required storefront health and approval events.Event taxonomy
Notification types follow aresource.action taxonomy so agents can build workflows
around stable event names. The full enum lives in
apps/api/src/types/notifications.ts. A representative slice:
Campaign lifecycle
campaign.created, campaign.updated, campaign.healthy,
campaign.unhealthy, campaign.completed, campaign.deletedCreative review
creative.approved, creative.rejected, creative.changes_requested,
creative.sync_started, creative.sync_completed, creative.sync_failedAgent registry
salesagent.registered, salesagent.available, signalsagent.registered,
outcomesagent.registered, salesagent.updatedOptimization
optimization.suggestion_received, optimization.suggestion_approved,
optimization.suggestion_applied, optimization.suggestion_failedMeasurement & learning
measurement.received, measurement.stale, learning_cycle.completed,
hypothesis.proven, hypothesis.disprovenSystem & syndication
system.warning, system.error, syndication.completed,
syndication.failed, audience.syncedStorefront health & approvals (always-on)
inventory_source.unhealthy, source.action_required,
source.action_resolved, salesagent.sync_action_required,
storefront_adapter_credential.action_required,
storefront.composition_paused, storefront.products_not_traffickable,
storefront.liveness_degraded, storefront.liveness_recovered,
media_buy.approval_requested, creative.review_requested,
ad_server.approval_requested, inventory_shortfall.review_requested —
operational alerts that bypass opt-in for the in-app feed. Storefront
health/readiness, ad-server approval, and inventory-shortfall alerts use
account notification settings. Media-buy and creative-review queue alerts
use the primary or optional escalation audience configured for that approval class;
email is sent only when the routing stage enables email. Slack is the one
exception: even always-on types only post
to Slack once you’ve added that event type to your Slack configuration’s
enabled events — connecting Slack doesn’t turn these on by itself.Optimization suggestions notify you only when there’s a decision to make.
You get
optimization.suggestion_received when a suggestion proposes a budget
or bid change on a campaign and media buy that are both still active. A
suggestion that carries no budget or bid change doesn’t notify — most often a
media buy with no optimization goal, where the suggestion is pacing information
only, but also any run where the optimizer settles on your current allocation.
Neither does a suggestion whose campaign or media buy is no longer active by the
time it reaches you. In both cases the suggestion is still recorded against the
media buy and closed out, so nothing sits in your queue waiting on a decision
you can’t make.Your storefront’s liveness verdict flipping is a proactive notification.
When the
liveness.state on Get readiness
flips away from live (to live_attention or live_critical), or a further
worsening from live_attention to live_critical, you get a
storefront.liveness_degraded notification carrying the verdict’s own reason
line and fix path — you don’t have to notice the dot change color. Recovery
back to live sends storefront.liveness_recovered. A storefront still in
setup (state: "setup") never alerts — setup is not failure. Repeated sweeps
of the same unchanged state never re-notify.If the same inventory-source change also opens source.action_required or
resolves it with source.action_resolved, email recipients receive the
specific source-action email only. The storefront.liveness_* event remains
in the in-app notification history, so the storefront-level state change is
still recorded without sending a second email for the same health change.status (success, error, warning, info) and a
data object with resource IDs (campaignId, creativeId, salesAgentId, …) plus a
human-readable message.
Pending storefront review now sends a notification. When a buyer submits a
creative or media buy that’s waiting on a storefront operator’s decision, it
still appears in the operator’s Approvals queue and via Murph — and it also
notifies the configured approval audience. In-app is always on; email and Slack
follow that approval class’s routing rule. See Reviewing buyer transactions
for how operators review and act on pending items.Each approval notification opens straight to the review it is about. The
in-app entry, the email’s Review creative / Review media buy button,
and the Slack Open in Apostra link all open Approvals focused on that
review or media buy, behind your normal sign-in (
data.actionUrl carries the
same app-relative path for API consumers). A creative-review notification also
names the creative, the buyer, the creative’s format, and its size when the
creative states one (data.creativeName, data.buyerName,
data.creativeFormat, data.creativeSize, data.reviewRef). Notifications
never carry the creative itself or a preview link: the live preview is created
only when you open the review, because preview links expire after 15 minutes
and die when the creative changes.Synchronous creative sync errors
Creative sync failures are not always reported as notifications. When a media-buy create or update targets a library-only seller andsync_creatives fails before the media-buy request is sent, the API returns a synchronous error instead of continuing silently.
Handle this as an API failure and retry after correcting the creative or seller issue. The message includes the seller and cause:
Channels
Storefront health and readiness emails are always-on operational alerts. They
go to the account notification address and active account users even when those
users have no saved email opt-in. Changing or clearing a user’s opt-ins does not
disable these alerts.
Per-user preferences
Operators control which events appear in their personal feed or reach their personal email address. Each user can read and replace only their own list.1
List the user's current opt-ins
{ "optIns": [{ "notificationType": "campaign.unhealthy", "channel": "email" }, ...] }.2
Replace opt-ins (full set)
PUT /notification-preferences replaces the user’s entire opt-in list. Send up
to 200 entries.Account-level email opt-ins (admin)
Admins set the recipient address and which event types should generate email.PUT /notification-email and PUT /notification-email/opt-ins require the caller to
have the ADMIN or SUPER_ADMIN role. Pass notificationEmail: null to clear the
account-wide recipient; per-user email delivery still follows the rules above.Slack configuration (admin)
Slack delivery uses an Incoming Webhook URL. Webhooks are admin-only and stored at the account level.Murph channel delivery settings
Product Updates and source outage alerts use your account’s primary Murph Slack channel rather than the incoming-webhook event filter above. An active account member can ask Murph to show or change these settings; Murph confirms the write before applying it. You can also use the shared v2 API:List primary-channel delivery settings
Turn off Product Updates in the primary channel
Send a Slack alert after a source outage lasts 30 minutes
Email opt-ins and Slack
enabledEventTypes are independent filters. The account-level email opt-in list (/notification-email/opt-ins) controls which events generate email; the Slack enabledEventTypes list on /slack-configuration is a separate per-channel filter applied to Slack delivery only. To get a Slack alert for a given event type, that type must be present in enabledEventTypes — the email opt-in list has no effect on Slack. Configure both lists independently to route the same event to the channels you want.1
Create or update the webhook
https://hooks.slack.com/services/. Provide at least one
event type — only events on this list are forwarded to Slack.2
Send a test message
3
Read the current configuration
4
Disable Slack delivery
Reading the in-app feed
The response includes the page of notifications, plus
totalCount, unreadCount, and
hasMore for pagination.
Mark read / acknowledge
A notification has two completion states:- read — surfaced to the user; safe to demote in the UI.
- acknowledged — the user has acted on it (e.g. approved a suggestion). The feed hides acknowledged items by default.
Endpoint reference
All endpoints validate the standard buyer auth context (
customerId, userId,
userRole). Admin-only endpoints reject non-admin callers with ACCESS_DENIED.Notification subscriptions
The sections above configure channels, opt-ins, and admin-managed routing directly for each event type. A newer, more structured layer sits alongside that: a notification subscription is an authored record of what you want to hear about, when it should fire, where it should go, and who is allowed to change it.What a subscription carries
A subscription names:- scope and content: what it’s about and how it renders (an
alert, or adigestfor a recurring summary); - a trigger: a recurring schedule, or a typed condition that fires when a metric crosses a line;
- route references: which delivery destinations it’s aimed at; and
- provenance and mutability: who installed it, and exactly which parts of it you’re allowed to change.
No trigger type fires yet: neither a schedule nor a condition has an
evaluator or delivery path behind it today, so creating or patching one in is
rejected. The shape above is the ratified contract a future evaluator reads
from — an Intelligence Unit (IU)
allowance-consumption condition is the first one planned. Managing
subscriptions (inspecting provenance, mutability, and routes) is available
today through the v3 preview agent surface for
enrolled accounts; authoring one that actually fires is not available yet.
Required versus optional notices
Every subscription carries provenance (who installed it) and mutability (exactly what you’re allowed to change about it):
Your own subscriptions are fully yours: create them, edit their trigger and
routes, or turn them off, freely, once a trigger type is live. A contract-,
plan-, or system-managed notice is different. It exists because of a
commercial fact you already agreed to, not a personal preference, so it stays
visible and inspectable even when you’d rather not see it.