Campaigns
Theme-group posts and inherit channels, queue, route, slots, and caption template across every item in the group.
What campaigns are for
A campaign is a routing group — pick a theme (e.g. "Q3 product launch", "Black Friday push", "weekly tutorial series") and attach default channels, a queue, a crosspost route, a slot pattern, and a caption template. Every post you add to the campaign inherits those defaults when it reaches the composer.
Useful for related content that should all publish the same way. Stop re-picking settings for every post in a series.
Where it lives
Open Content (/content). The chip rail at the top of the page is your campaign list. Click + Campaign to create one.
Campaigns appear on the calendar as a small mint dot on event cards that belong to a campaign.
Plan availability
| Plan | Campaigns |
|---|---|
| Launch | 3 active |
| Scale | 15 active |
| Agency | Unlimited |
Campaigns are workspace-scoped — each workspace gets its own.
Step 1 — Create a campaign
- Open
/content. - Click + Campaign in the chip rail.
- Name — e.g. "Black Friday 2026".
- Default channels — which platforms posts in this campaign should fan out to.
- Default queue (optional) — adding a post to the campaign auto-queues it.
- Default route (optional) — applied to every post in the campaign.
- Default caption template (optional) — the composer pre-fills this text when you start a new post in the campaign.
- Click Save.
Step 2 — Add posts to the campaign
Three ways:
- Drag a draft onto the campaign chip in the chip rail.
- Pick the campaign in the composer — there's a campaign dropdown next to the channel picker.
- Via API —
POST /api/scheduled-postsaccepts acampaignIdand inherits defaults.
When a post joins a campaign:
- The composer pre-fills channels from
defaultChannels. - The caption field pre-fills from
defaultCaptionTemplateif blank. - The route from
defaultRouteis applied at publish time. - The queue from
defaultQueueis used for scheduling if no explicit time is set.
You can override any of these per post — campaign defaults are a starting point, not a lock.
Step 3 — Filter by campaign
- Content drafts list — clicking a campaign chip filters the drafts list.
- Calendar — the same chip click filters the calendar to that campaign's events.
- API —
GET /api/scheduled-posts?campaignId=…returns only posts in that campaign.
Per-campaign metrics
A DB trigger bumps per-campaign scheduled and published counters on every status change. The campaign detail page shows:
- Scheduled count — how many posts are queued / scheduled.
- Published count — how many have gone live.
- Last activity — timestamp of the most recent status change.
No analytics query needed — the counters are always live.
How campaigns interact with other Aidelly features
- Crosspost Routes — set
defaultRouteand every post inherits the route at publish time. - Queues — set
defaultQueueto drop campaign posts into a slot grid automatically. - Posting Sets — sets can be layered on top of campaign defaults; the set wins where they overlap.
- Analytics — campaigns appear as a filter on the analytics page for per-campaign performance.
- Auto-Post — auto-post sources can assign new items to a campaign automatically.
"Campaigns" vs "Collections"
Aidelly has media_collections for grouping uploaded media. Campaigns are a different concept — routing-group for posts, not a grouping for assets. Don't conflate them.
Step 4 — Edit or close
From the campaign detail page:
- Edit defaults — change channels, queue, route, slots, or template. Existing posts in the campaign keep their original config; only new posts inherit the new defaults.
- Close — marks the campaign inactive. Closed campaigns disappear from the chip rail but remain in analytics history.
Why one campaign per post?
A post can belong to at most one campaign. If you need cross-campaign organization, use draft tags instead. Campaigns are routing groups — having a post inherit conflicting defaults from two groups would be ambiguous, so we enforce one-per-post at the DB level.
Troubleshooting
- A draft joined the campaign but didn't get the default route — routes are applied at publish time, not on draft creation. Verify the route at publish.
- The default caption template didn't appear — the template only pre-fills when the caption field is empty. If you've typed anything, the template stays out of the way.
- Campaign counts look stale — refresh the page; counters are updated by trigger but the UI cache may be a beat behind.