Web Push — Reference
The Web Push surface is the browser-push notification plane for SGEN. It owns the visitor subscription layer (the opt-in prompt rendered on the public frontend, the persisted per-browser subscription record, the unsubscribe path), the segment-targeting layer (the named visitor groupings a push can address), the send-scheduling layer (immediate sends and time-window scheduled sends), the click-tracking layer (the per-recipient open and click records), and the send-history archive that captures every campaign with delivery and engagement statistics. Anything that asks "send a notification to a browser the visitor previously opted into" traces back to a record managed here.
This page is a reference for platform engineers and integrators who need to understand the surface before scripting against it, extending the segment model, or scoping a re-engagement program. Customer-facing how-tos for sending pushes live in the customer docs set; this page describes the shape of the surface, not the steps to drive it.
Overview
Web Push lives under the Web Push module in SG-Admin. The module renders five primary views — the campaign list (every authored push with state, target segment, scheduled time, and delivery statistics), the campaign editor (the title, body, click-through URL, target-segment picker, and schedule controls), the subscriber list (every active per-browser subscription with segment membership and last-seen state), the segment-rules editor (the conditions that group subscribers into named segments), and the send-history archive (concluded campaigns with full delivery, open, and click counts).
The module is paired by convention with the Users, Pages, Notifications, and Activity Log surfaces. Segment rules can reference user records (when the subscriber is also a signed-in user); click-through URLs resolve against page records; the operator-side send-confirmation notification hands off to the Notifications surface; every campaign send writes an Activity Log entry. The Web Push module owns the subscription and the campaign; the consuming surfaces own the records the segment rules and the URLs point at.
A second surface — the subscription prompt and the service worker — is the public-facing contract surfaced to the frontend. The prompt renders on configured trigger conditions (page visit count, time on site, named event), the visitor accepts or declines the browser-native push permission dialog, the service worker registers and exchanges a per-browser subscription endpoint with the SGEN platform, and the platform persists the subscription record. Subsequent campaign sends are delivered through the subscription endpoint. The visitor can revoke through the browser's site-settings UI or through an in-page unsubscribe surface the module renders on configured pages.
Where it lives in SG-Admin:
- Sidebar: SG-Admin → Web Push
- URL prefix:
/sg-admin/web-push/ - View templates:
application/views/Admin/WebPush/
┌──────────────────────────────────────────────────────────────────────┐│ SG-Admin → Web Push [+ New campaign]│├──────────────────────────────────────────────────────────────────────┤│ Campaign Segment Scheduled Sent / CTR ││ ───────────────────────── ─────────── ──────────────── ──────────││ pricing-page-revisit Trial users Today 14:30 — ││ new-feature-announce All subs Yesterday 09:00 4,210 / 8% ││ abandoned-checkout-r1 Cart-leavers Scheduled +2h — ││ weekly-digest-week-21 Power users Sent 2 days ago 990 / 14% ││ ││ [⋯ Edit] [⋯ Send now] [⋯ Schedule] [⋯ Pause] [⋯ Archive] │└──────────────────────────────────────────────────────────────────────┘Actions
The Web Push surface exposes the following operations. Each is described by what it does to the data and to the campaign lifecycle, not by its internal method name.
List and filter campaigns
Returns the campaign records visible to the current operator, paginated, with title, target segment, scheduled time, lifecycle state, delivery count, and click-through-rate columns. Supports column sort, filter by state (draft, scheduled, sent, paused, archived), filter by segment, free-text search on title and body, and per-page count. Driven by the data-table contract used across SG-Admin modules — responses arrive as a row collection plus a total count, suitable for direct binding to a paged grid.
Create campaign
Opens an empty campaign form. Required fields at minimum: campaign title, notification title (the headline the visitor sees), notification body, click-through URL, target segment, and schedule (immediate or scheduled timestamp). Optional fields cover an icon image, a banner image, a per-recipient frequency cap (default: one push per visitor per 24 hours), and an expiry timestamp past which the push is no longer delivered to subscribers who were offline at send time. On submit, the surface validates that the title and body lengths fit the browser-native push constraints, that the click-through URL is well-formed, and that the segment resolves to at least one subscriber, persists the record, and returns the new identifier.
Edit campaign
Loads an existing campaign into the same form shape used for create, pre-populated. Submit replaces the stored configuration. Edits to a campaign that has already been sent are rejected — sent campaigns are immutable. Edits to a scheduled campaign that has not yet sent are allowed up until the schedule trigger fires.
Schedule campaign
Transitions the campaign from draft to scheduled. Accepts a target timestamp. The surface validates that the timestamp is in the future and that the campaign passes the final pre-send validation (segment resolves, click-through URL resolves, title and body fit constraints).
Send now
A dedicated write path that triggers immediate delivery, bypassing the schedule. Transitions the campaign from draft or scheduled to sending to sent. The surface validates the same pre-send conditions and surfaces a confirmation prompt with the resolved subscriber count before proceeding.
Pause campaign
Suspends a scheduled campaign without canceling it. The schedule timestamp is preserved but the campaign does not fire until resumed. Pause is the fast path for an operator who needs to halt a scheduled send while investigating a problem without losing the schedule.
Resume campaign
Reverses a pause. The campaign returns to scheduled state. If the original schedule timestamp has passed during the pause, the surface returns a structured rejection prompting the operator to either reschedule or send now.
Cancel campaign
Transitions a scheduled or paused campaign to archived without sending. Used when an operator decides not to ship a scheduled push.
Configure segments
Returns the segment-rules editor. Each segment is named and carries an ordered list of conditions. Conditions cover: subscription source page, subscriber's signed-in user record (if any), subscriber's last-seen-at recency, custom attribute set by an upstream module, and named-event membership (a visitor who fired a named tracking event in a recent window). The surface walks rules per subscriber — every matching subscriber is included in the segment.
List subscribers
Returns the active subscription records visible to the current operator, paginated, with subscription endpoint identifier (the browser-side opaque id, never the raw push endpoint URL), source page, segment memberships, last-seen timestamp, and signed-in user id (if any). Used by operators auditing segment composition and investigating low delivery rates.
Unsubscribe visitor
A targeted write path that marks a subscription record inactive. Used when an operator needs to honor an out-of-band unsubscribe request (typically arriving through support channels). The surface validates explicit consent — operator-initiated unsubscribe is logged with the originating support ticket reference on the Activity Log entry.
View campaign engagement
Returns the per-campaign delivery count, the per-recipient open and click records, the click-through rate, and the per-subscriber bounce-or-failure log for a single concluded campaign. Used by operators measuring campaign performance and investigating delivery failures.
Archive campaign
Marks the campaign record inactive without removing it from the database. Archived campaigns disappear from the default list view but remain queryable via the archive filter. Captured engagement data is retained.
Permanent delete
Hard-removes the campaign record. Available only after an archive. Captured engagement data is removed with the record; per-subscription bounce records are preserved (they affect future delivery decisions). This path is irreversible.
Data model
A campaign record carries the following fields. Field names below are the conceptual shape — the on-disk column names match closely but are not contractually stable across releases.
| Field | Type | Notes |
|---|---|---|
id | integer | Primary key. Stable across edits. |
slug | string | Unique. Used in the click-tracking link wrapping. |
title | string | Display name for the campaign list. |
notification_title | string | The headline the visitor sees on their device. |
notification_body | string | The body the visitor sees. |
click_through_url | string | The URL the click resolves to. Wrapped with click-tracking prior to delivery. |
target_segment_slug | string | Resolves against the segment-rules editor. |
icon_url | string | Optional. |
banner_url | string | Optional. |
lifecycle_state | enum | draft, scheduled, sending, sent, paused, archived. |
scheduled_at | timestamp | Set when scheduled. Null in draft. |
sent_at | timestamp | Set when transition to sent completes. |
expiry_at | timestamp | Optional. Past expiry, the push is not delivered to offline subscribers. |
frequency_cap_hours | integer | Per-recipient minimum gap between pushes. |
created_at | timestamp | Set on create, immutable. |
updated_at | timestamp | Touched on any edit. |
Engagement-record shape: per-campaign delivery is captured on a separate engagement record keyed by campaign id and subscription endpoint identifier. Each record carries the delivery-attempt timestamp, the delivery outcome (delivered, bounced, expired), the open timestamp if surfaced to the visitor, and the click timestamp if the visitor clicked through.
CAMPAIGN RECORD├── id integer primary key├── slug string unique click-tracking prefix├── title string internal campaign label├── notification_title string headline visitor sees├── notification_body string body visitor sees├── click_through_url string resolved + wrapped pre-delivery├── target_segment_slug string segment resolution on send├── icon_url / banner_url string optional creative├── lifecycle_state enum draft | scheduled | sending | sent | paused | archived├── scheduled_at timestamp set when scheduled├── sent_at timestamp set on completion of send├── expiry_at timestamp optional cutoff for offline-subscriber delivery├── frequency_cap_hours integer per-recipient minimum gap└── timestamps created_at, updated_at↓ per subscriptionSUBSCRIPTION RECORDper endpoint_id: source_page, user_id, last_seen_at,lifecycle_state, revocation_reason↓ per campaign × subscription on sendENGAGEMENT RECORDper (campaign_id, endpoint_id): delivered_at, outcome,opened_at, clicked_at(append-only; immutable once written)Permissions
Access to the Web Push surface is gated at two layers.
Layer 1 — admin gate. Every action under SG-Admin passes through the platform's standard admin access check at request entry. An unauthenticated request never reaches the Web Push surface. The subscription-side and click-tracking endpoints are public but rate-limited and signature-validated.
Layer 2 — per-action capability. Within SG-Admin, each Web Push action checks a capability associated with the calling operator's role. The default role configuration ships with three roles — Administrator, Editor, Viewer — and the capability map is:
| Capability | Administrator | Editor | Viewer |
|---|---|---|---|
| List campaigns | ✔ | ✔ | ✔ |
| Create campaign | ✔ | ✔ | — |
| Edit campaign (draft / scheduled) | ✔ | ✔ | — |
| Schedule campaign | ✔ | ✔ | — |
| Send now | ✔ | — | — |
| Pause / resume / cancel | ✔ | ✔ | — |
| Configure segments | ✔ | — | — |
| List subscribers | ✔ | ✔ | — |
| Unsubscribe visitor | ✔ | — | — |
| View campaign engagement | ✔ | ✔ | ✔ |
| Archive | ✔ | — | — |
| Permanent delete | ✔ | — | — |
Self-protection rules. A campaign cannot be sent to a segment that resolves to zero subscribers — the surface returns a structured rejection. A campaign cannot be sent to a single subscriber more than once within the configured frequency-cap window — the per-recipient cap is enforced at send time, not at campaign-edit time. A subscriber whose endpoint has bounced three times consecutively across distinct campaigns is automatically transitioned to revoked, and the surface emits a notification to the operator.
Audit. Every write — create, edit, schedule, send, pause, resume, cancel, configure-segments, unsubscribe-visitor, archive, delete — emits an Activity Log entry. Operator-initiated unsubscribe carries the originating support reference on the audit entry. Send events carry the resolved subscriber count and the campaign id.
CAMPAIGN.SEND_NOW (or schedule fires)│▼┌───────────────────────────┐│ Final pre-send validation │ segment resolves > 0│ │ click-through URL resolves│ │ title + body fit constraints└─────────────┬─────────────┘│ passes▼┌───────────────────────────┐│ Resolve target segment │ walk segment rules per subscriber└─────────────┬─────────────┘│ subscriber list▼┌───────────────────────────┐│ Per-recipient cap check │ drop subscribers within frequency window└─────────────┬─────────────┘│ eligible recipients▼┌───────────────────────────┐│ Wrap click-through URL │ per-recipient signed tracking link└─────────────┬─────────────┘│▼┌───────────────────────────┐│ Dispatch through browser │ per subscription endpoint│ push delivery layer │ bounces logged on subscription record└─────────────┬─────────────┘│ on visitor open / click▼ENGAGEMENT RECORD captures open_at / clicked_at│▼Activity Log entry: send completed + recipient countRelated references
- Users — Reference. Segment rules can reference signed-in user records when the subscriber is also an authenticated user. Soft-deleted users still appear on prior engagement records but no longer match new segment computations.
- Pages — Reference. Click-through URLs resolve against page records. The subscription-prompt trigger configuration and the in-page unsubscribe surface are configured per page or per site under the Pages module.
- Notifications — Reference. Send-confirmation alerts, segment-resolution warnings, and consecutive-bounce notifications hand off to the Notifications surface for operator delivery.
- Activity Log — Reference. Every campaign write emits a one-line entry. Send events carry the resolved subscriber count.
- Automations — Reference. Time-driven campaign sends (a campaign that fires after a named event) can be authored as an Automation with a send-push action — see the Automations action catalog.
- Settings — Reference. Owns the role definitions referenced by the capability map, the subscription-prompt trigger defaults, and the Activity Log retention policy that governs audit-entry lifetime.
/docs/web-push.