Campaigns

A campaign is a named marketing initiative with a goal, a date range and a set of activities (coupons, email blasts, on-site banners). Owners run their own; platform admins can run cross-property promos. Every campaign tracks impressions, clicks, bookings and revenue against a UTM tag.

Campaign vs coupon — what's the difference?

A coupon is an atomic discount. A campaign is the wrapper that gives the discount a reason for existing — a goal, a date, an audience, a way to reach them, and a way to measure if it worked. A coupon can exist without a campaign; a campaign usually has at least one coupon.

Goal presets

Pick a goal at creation time. Each preset seeds defaults (suggested coupon type, audience, reporting view).

Fill low-occupancy dates

System suggests dates with < 40 % forecast occupancy. Seeds a stay-window-scoped coupon.

Drive direct bookings

Reduce OTA dependence. Coupon excluded from OTAs by design; banner above search results.

Launch a new property

Auto-creates a feature banner + email to past guests + opening-week coupon.

Convert past guests

Audience = "stayed in last 12 months". Returning-guest coupon. Email-led.

Seasonal push

Diwali / Christmas / monsoon getaway. Date-bounded with a thematic banner template.

Custom

Blank canvas — define your own audience, activities and reporting.

What a campaign contains

ComponentHow manyPurpose
Basics1Name, goal, owner, start/end dates, optional ad budget for ROAS
Audience1Who this is for (everyone · logged-in · past-guests · custom segment)
Coupons0..NDiscount codes — pulled from Coupons module
Email blast0..1 (V1.1)Templated email scheduled to a segment
On-site banner0..1 (V1.1)Hero strip on public site or city/property pages
UTM tagsautoutm_source / medium / campaign auto-applied to outbound links
Landing page0..1 (V2)Custom slug like /offer/summer-in-manali

Lifecycle states

draftowner building
scheduledstart date in future
livecoupons active, email sent, banner up
paused
endedreporting frozen, still readable
archivedhidden from main list

Campaigns list UI

app.abc.com/marketing/campaigns
Campaigns
2 live · 1 scheduled · ₹12,40,500 attributed revenue (90d)
Summer in Manali 2026
Live
Goal · Fill low-occupancy dates · 01 Jun – 31 Aug
Bookings
42
Revenue
₹1,82,400
Coupon
SUMMER25
Welcome to ABc
Live
Goal · Direct bookings · evergreen
Bookings
118
Revenue
₹6,42,100
Coupon
FIRSTSTAY
Diwali Getaway
Scheduled · 15 Sep
Goal · Seasonal push · 15 Sep – 30 Oct
Email blast
2,140 recipients
Coupon
DIWALI500
+ Start a new campaign
Pick a goal preset to seed the defaults.

Campaign builder — 4-step wizard

  1. Basics

    Name · goal preset · start & end dates · optional ad budget. Goal seeds defaults for the rest of the wizard.

  2. Audience

    Everyone · logged-in users · past guests (last 12 m) · custom segment (filter by property, channel, lifetime value). Estimated reach shown live.

  3. Activities

    Toggle which components to include: Coupon (create new or attach existing), Email blast (pick template + send date), Banner (image, headline, CTA, target pages).

  4. Review & schedule

    Summary of all the above + a preview email + preview banner. Save as draft or schedule.

Campaign builder — step 3 (Activities)

app.abc.com/marketing/campaigns/new · step 3 of 4
1 Basics
2 Audience
3 Activities
4 Review
Coupon
Discount code redeemable at checkout
Phase 1
Email blast
One-off email to selected audience
V1.1
On-site banner
Hero strip on public homepage + Manali city pages
V1.1
Custom landing page
Branded URL: abc.com/offer/summer-in-manali
V2

Campaign detail — live performance

app.abc.com/marketing/campaigns/summer-in-manali-2026
Summer in Manali 2026
Goal · Fill low-occupancy dates · 01 Jun – 31 Aug 2026 · 42 of 90 days in
Live
Bookings
42
▲ on pace for 90 (goal 75)
Revenue
₹1,82,400
ADR ₹4,344
Discount given
−₹38,200
21 % of gross
ROAS
4.78×
Ad spend ₹30k
Bookings — daily
Jun 1Jun 15Jul 1Jul 13
Funnel
Email opens1,640
Clicked318
Reached checkout89
Booked42

Open→book conversion: 2.6 %
Attached coupon
SUMMER25
25 % off, capped ₹2k · 42 / 100 redeemed · −₹38,200 discount given

Attribution model

Every interaction picks up the campaign in one of three ways. Most specific wins.

PrioritySignalHow it's set
1 (strongest)Coupon redemptionBooking applies a coupon linked to the campaign → attributed.
2UTM in landing URLVisitor lands with ?utm_campaign=summer-manali → stored on the session and on any booking they make within 7 days.
3Banner / email clickClick recorded with campaign ID; if the same visitor books in 7 days → attributed.

Data model

campaigns
  • iduuid
  • owner_id→ users · nullable
  • nametext
  • slugtext uniq
  • goalenum
  • audiencejsonb (filters)
  • starts_attimestamptz
  • ends_attimestamptz
  • budget_inrmoney · nullable
  • utm_sourcetext
  • utm_mediumtext
  • utm_campaigntext
  • statusenum
  • created_attimestamp
campaign_assets
  • iduuid
  • campaign_id→ campaigns
  • typecoupon · email · banner · landing
  • asset_refuuid (poly fk)
  • configjsonb
  • statusenum
campaign_metrics_daily
  • iduuid
  • campaign_id→ campaigns
  • datedate
  • impressionsint
  • clicksint
  • bookingsint
  • revenuemoney
  • discount_givenmoney

API contract

POST /api/campaigns
{
  "name": "Summer in Manali 2026",
  "goal": "fill_low_occupancy",
  "starts_at": "2026-06-01T00:00:00+05:30",
  "ends_at":   "2026-08-31T23:59:59+05:30",
  "budget_inr": 30000,
  "audience": { "type": "past_guests", "within_months": 12 },
  "assets": [
    { "type": "coupon",
      "config": { "code": "SUMMER25", "discount_type": "percent", "value": 25, "max_cap": 2000 } },
    { "type": "email",
      "config": { "template": "summer_2026_hero", "send_at": "2026-06-01T09:00:00+05:30" } }
  ]
}

// Response — 201
{
  "campaign": { "id": "cmp_01HX…", "slug": "summer-in-manali-2026", "status": "scheduled" },
  "created_assets": [ "cpn_…", "eml_…" ]
}

Integration points

ModuleTouch point
CouponsCampaign creates / links coupons. Coupon redemptions roll up to campaign metrics.
EmailsEmail blasts use the same notify-svc pipeline. Each send records campaign_id for open/click attribution.
Public siteBanner zone above search results renders the active campaign's banner if rules match the visitor.
Analytics"Campaigns" tab shows mix, revenue, ROAS, top performers.
AuditEvery campaign edit (pause / resume / change dates) audit-logged with actor and diff.

MVP vs later

MVP (Phase 1)

Campaign wrapper with coupons + UTM tracking + daily metrics rollup + basic detail view.

Phase 1

V1.1

Email blast composer + on-site banner editor + audience segments + send-test.

Phase 2

V2

Custom landing pages + A/B variants on email and banner + paid-ad cost ingestion for true ROAS.

Phase 3