Layers

Notification Catalog

The shape of a notification and the registered actions it can execute.

View as Markdown

Layers does not ship a dotted-code catalog ("ads.wallet.floor_hit" / etc.) today. Notifications are free-form rows with a source_type tag, a title, a body, and an optional action_config pointing at an allow-listed action.

Notification fields

Every notification is a row in the notifications table with:

  • scopeuser, project, or organization.
  • user_id / project_id / organization_id — depending on scope.
  • typebroadcast, confirmation, selection, input.
  • title, body — plain text for the bell.
  • icon — optional; one of bell, info, alert, warning, success, message, star, heart, zap, gift, calendar, users, settings. If omitted, a priority-based default is used.
  • prioritylow, normal, high, urgent.
  • source_type, source_id, source_metadata — free-form tagging for traceability. Conventional values include system, workflow, content, billing, ugc.
  • action_config — required for non-broadcast types; see below.

Registered actions

Interactive notifications can only execute actions in the immutable ACTION_REGISTRY. Current entries:

action_keyEndpointMethodRequired paramsBody template
approve_content/api/content/{content_id}/approvePOSTcontent_id
reject_content/api/content/{content_id}/rejectPOSTcontent_id
adjust_spend_cap/api/projects/{project_id}/spend-capPATCHproject_id{ amount: "{input.value}" }
acknowledge/api/notifications/{notification_id}/acknowledgePOSTnotification_id

Adding a new action is a code change — the allow-list is enforced to prevent open-ended side effects from notification responses.

Fan-out

When a notification is created, one inbox row is written per recipient. The bell UI subscribes to inbox updates over a realtime channel, so new and updated notifications appear without a page refresh.

Response handling

For confirmation / selection / input, the frontend posts the user's answer to Layers' API, which:

  1. Validates inbox access and idempotency.
  2. Writes the response to notification_responses.
  3. Executes the registered action (builds the URL from buildActionUrl, body from buildActionBody).
  4. Records the outcome on the response row (pendingexecutingcompleted or failed).
  5. Marks the notification read for the responding user.

For the canonical implementation guide, see the internal engineering doc docs/notification_system_usage.md.

On this page