Activity log
Every campaign carries a per-campaign activity feed — who edited what, who reviewed an AI diff, who left a comment. It’s the audit trail for collaborative campaign work, distinct from the per-user notification delivery channel.TL;DR
- One activity log per campaign, accessible from the campaign detail “Activity” tab.
- Records edits, status promotions, AI proposals, comments, dev-task resolutions.
- Updates in real-time so multiple reviewers see each other’s actions live.
- Distinct from the Notification Center widget — the activity log is a dashboard-side feed, not a user-facing channel.
What gets recorded
Per the spec:| Activity type | Trigger |
|---|---|
| Edit | Any save on the campaign detail (orchestrator code, channel config, status, …). |
| Status promotion | Editing → Dev, Dev → Live, etc. |
| AI proposal | The codegen or dev-task resolution generated a diff. |
| AI proposal accepted/rejected | A reviewer clicked Accept or Edit/Reject on an AI diff. |
| Comment | A team member added a comment via POST /:campaignId/activity/comment. |
| Dev task | A dev task was raised, auto-resolved, or manually resolved. |
- Actor — the user (dashboard team member) who performed the action.
- Timestamp — when it happened.
- Type — one of the categories above.
- Payload — type-specific detail (the diff, the comment text, the status transition, …).
How to use it
| Use case | How |
|---|---|
| ”Who promoted to Live last Tuesday?” | Filter by status-promotion type, scroll. |
| ”What did the AI propose on this campaign?” | Filter by AI-proposal type. The diff is preserved. |
| ”Did anyone comment on this dev task?” | Open the campaign detail, scan the activity tab — comments are inline with edits. |
| ”Audit trail for compliance” | Export the activity log for a campaign (CSV from the dashboard or via the read API). |
Real-time updates
The activity tab streams updates as they happen — multiple reviewers see each other’s edits and comments live without refreshing. The mechanism is server-side; the dashboard subscribes once when the tab opens. The streaming channel is dedicated to collaborative team feeds — flat per-campaign updates, one or a few reviewers at a time. The Notification Center widget streams over a different channel optimised for per-user notification inboxes; don’t conflate the two.API endpoints
The dashboard backs onto three internal endpoints:| Endpoint | Purpose |
|---|---|
GET /:campaignId/activity | Initial fetch — paginated list of recent activity. |
POST /:campaignId/activity/comment | Add a comment. |
GET /:campaignId/activity/since | Incremental fetch — entries since a cursor. Used for re-syncing after a brief disconnect. |
Retention
Activity entries are retained per the org’s plan, typically aligning with the per-message delivery retention. Aged-out entries are archived rather than deleted — the audit trail survives for compliance even when day-to-day display drops them from the dashboard.Distinct from the Notification Center channel
A common mistake: thinking the activity log and the user-facing Notification Center are the same thing. They’re not:| Activity log | Notification Center | |
|---|---|---|
| Audience | Your team (dashboard users) | Your end users (customers) |
| Scope | Per campaign | Per user inbox |
| What it records | Edits, AI proposals, comments | Notifications delivered to a user |
| Real-time mechanism | Server-sent events | real-time stream |
| Surfaced in | Campaign detail “Activity” tab | The widget on your customer’s app |
FAQ
Don't see teammate's comment — why?
Don't see teammate's comment — why?
The real-time stream may have disconnected briefly (laptop sleep, flaky wifi). Refreshing the activity tab triggers a
GET /activity/since fetch that pulls anything missed. If the comment still doesn’t appear, check the timestamp filter — a “last hour” filter hides older entries.Activity log retention — how long?
Activity log retention — how long?
Aligned with the per-message delivery retention on your plan (typically 90 days for the standard plan). Entries older than the window are archived rather than deleted; an audit-export call can fetch them for compliance reviews.
Export for an audit?
Export for an audit?
Two paths: the dashboard’s “Export activity” button (CSV) for the active retention window, and a backend audit-export endpoint for older archived entries. Both are scoped to the campaign and respect organisation membership.
Stops streaming after a while — is that expected?
Stops streaming after a while — is that expected?
Long-lived connections occasionally drop (load balancer timeouts, idle disconnects). The dashboard auto-reconnects on visibility change and uses the
/activity/since cursor to fill any gap. If you see persistent stalls, refresh the tab.Can I subscribe to the activity log from outside the dashboard?
Can I subscribe to the activity log from outside the dashboard?
Not as a public API today — the streaming endpoints are dashboard-internal. If you have an audit pipeline that needs activity events, the right surface is a future webhook (on the roadmap); meanwhile, the periodic export covers most needs.
Comments — Markdown supported?
Comments — Markdown supported?
Plain text + emoji today. Markdown-flavored rendering is on the roadmap. The text is stored verbatim, so future Markdown support will retroactively render existing comments.
See also
Campaigns
Campaign lifecycle and versioning.
Orchestrator
AI proposals and the dev-task system.
Observability
Tracing actions across the platform.
Notification Center overview
The user-facing channel — distinct from the activity log.