SurfacedBySurfacedBy Docs
DocumentationIntegrations

Realtime

The Supabase Realtime channels the dashboard uses to stay live without polling.

Ask an AI:Open in ChatGPTOpen in Claude

The SurfacedBy web app does not poll for updates. It subscribes to a small set of Supabase Realtime channels scoped to your workspace, your domain, or your user, and receives push updates whenever the backend writes data you should see. These channels are an implementation detail of the dashboard today, but they are documented here because third-party integrations may want to subscribe directly.

Channels

Channels are scoped by workspace id, domain id, or user id. The dashboard subscribes to whichever channels are relevant to what is on screen.

TopicChannel formatEvents
Scan lifecyclescan-updates:{workspace_id}scan_started, scan_progress, scan_completed, scan_failed
Tracked domainsdomains:{workspace_id}domain_added, domain_removed, domain_updated, competitor_suggested, competitor_accepted, competitor_dismissed, competitor_restored, competitor_deleted
Creditscredits:{workspace_id}credits_purchased, credits_consumed, credits_refunded, balance_updated
Integrationsintegrations:{workspace_id}collector_heartbeat_received, collector_disconnected, collector_secret_generated, collector_secret_rotated, site_id_generated, site_id_rotated, site_id_revoked, webhook_secret_generated, webhook_secret_rotated, gsc_connected, gsc_disconnected, ga4_connected, ga4_disconnected, ga4_property_set
Workspace and membershipworkspace:{workspace_id}member_invited, member_joined, member_role_changed, member_removed, workspace_renamed, workspace_deleted, subscription_changed
Plans and action itemsplans:{workspace_id}plan_created, plan_updated, plan_deleted, item_created, items_bulk_created, item_updated, item_moved, items_reordered, item_deleted, item_step_toggled, item_event_logged
Analyticsanalytics:{domain_id}analytics_refreshed
AI traffictracking:{domain_id}event_ingested and related ingest events
Content Checkercontent-checks:{domain_id}Crawl progress events
Opportunitiesopportunities:{domain_id}opportunity_dismissed, opportunity_restored, opportunities_bulk_dismissed, opportunity_resurfaced
Reportsreports:{domain_id}report_generated, report_deleted, schedule_created, schedule_updated, schedule_deleted, schedule_paused, schedule_resumed, schedule_run_now, schedule_test_sent, schedule_sent, share_created, share_revoked
Notificationsnotifications:{user_id}notification_created, notification_read, unread_count_changed, milestone_earned
Profileprofile:{user_id}profile_updated

Workspace-scoped topics swap atomically when you change the active workspace, so a single subscription per topic is enough. Domain-scoped topics swap when you open a different domain inside the same workspace. User-scoped topics travel with you across workspaces, since they carry user-personal data (notifications, profile).

Delivery semantics

Realtime is best-effort. Events are delivered at most once. If the channel is disconnected during an event, the event is lost. That is fine for a live dashboard because the dashboard falls back to fetching fresh state on reconnect. It is not fine for durable integrations.

If you need guaranteed delivery, use outbound webhooks instead. Webhooks use at-least-once delivery with retries and a dead-letter queue.

Progress events are rate-limited

scan_progress and event_ingested are rate-limited to at most one message per scan or per domain per five seconds. That keeps the dashboard smooth without flooding subscribers with micro-updates.

Public API for realtime

A customer-facing realtime SDK is not part of the v1 release. If you have a use case that cannot be served by webhooks, reach out and we will document the direct subscription path.

On this page