Skip to main content

Ads Domain Overview

High Level Domain

Ads Domain Diagram

What is the Ads Domain?

The Ads domain allows Org::Company (employers) to purchase sponsored placements on the Jod platform — showing image-based creatives on prime real estate on the website (home hero banner, job list banner, etc.).

It is a self-serve advertising platform with an admin moderation gate before any ad goes live. Ads are priced in Placement Credits (Visibility Credits) — the shared credit pool managed by the ::Billing domain.


Three Contexts

The Ads domain exposes functionality across three distinct contexts, each serving a different actor.

ContextActorResponsibility
employersOrg::UserProfile (employer)Build campaigns, upload creatives, submit for review
marketplacePublic / Identities::UserAd is served to job seekers browsing the platform
teamIdentities::AdminManage placement inventory (slots & packages); review, approve, or reject campaigns

Core Concepts

Campaign (Ads::Campaign)

A campaign is the top-level container created by an employer. It has a name, status, and a submission/approval workflow. A campaign has no dates of its own — dates belong to individual placements, since each placement can run for a different duration.

Placement (Ads::Placement)

A placement defines a named slot on the website where an ad can appear (e.g. home_hero, job_list). Placements are managed by admin and define the required image dimensions. This is the supply side.

KeyNameRequired SizeDescriptionPrices
home_heroHome Page - Hero Banner1024x342Premium placement at the top of the home page, appearing above the fold for maximum visibility.3 Days (3d / 3 credits)
Weekly (7d / 5 credits)
10 Days (10d / 7 credits)
home_after_heroHome Page - After Hero Banner1024x683Strategic placement positioned right after the hero section on the home page.3 Days (3d / 2 credits)
Weekly (7d / 4 credits)
10 Days (10d / 6 credits)
home_middle_rectangleHome Page - Middle Rectangle1024x683Large format placement within the main content area of the home page.3 Days (3d / 2 credits)
Weekly (7d / 4 credits)
10 Days (10d / 6 credits)
home_bottom_bannerHome Page - Bottom Banner1024x342Retention-focused banner at the bottom of the home page.Weekly (7d / 2 credits)
job_list_inlineJob List - Inline Banner1024x683Native-style ad appearing between listings in job search results.Weekly (7d / 3 credits)
10 Days (10d / 5 credits)
job_detail_inlineJob Detail - Inline Banner1024x683High-engagement banner placed within the job description and details page.Weekly (7d / 3 credits)
10 Days (10d / 5 credits)
contact_us_heroContact Us - Top Banner1024x342Header placement on the Contact Us landing page.Weekly (7d / 2 credits)
faq_topFAQ - Top Banner1024x342Header placement at the top of the FAQ and support section.Weekly (7d / 2 credits)

Placement Price (Ads::PlacementPrice)

A placement price defines a deal for a given placement: how many days it runs and how many placement credits it costs. Admin manages prices per placement. Examples:

PlacementPriceDurationCredit Cost
home_hero3 Days3 days3 credits
home_heroWeekly7 days5 credits
home_hero10 Days10 days7 credits
job_listWeekly7 days3 credits

Creative (Ads::Creative)

A creative is a reusable image asset uploaded to S3 by the employer. It belongs to a company and can be reused across multiple campaigns — the employer's creative library.

CampaignPlacement (Ads::CampaignPlacement)

The join between a campaign, a placement package, and a creative. Represents one concrete ad unit within a campaign — e.g. "run our February creative on the home hero banner using the Weekly package." It owns:

  • the snapshotted credit cost (frozen at booking time)
  • the actual start/end datetimes (start_time / end_time, set at admin approval)
  • its own status (pending → scheduled → active → completed)
  • destination URL, headline, and description

Relationship to Billing

Ads are priced in Placement Credits (placement_credits) — the same pool used by Careers job postings and Job Boost.

Billing EventTriggerDetails
GrantCompany tops up placement creditsVia Billing::Product purchase + invoice payment
ReserveCampaign submitted for reviewOne hold per CampaignPlacement, locked until approved/rejected
ReleaseCampaign rejected or cancelledReserved credits returned to available
ConsumeDaily, while placement is activecredit_cost_snapshot / duration_days credits/day per active CampaignPlacement

Credits are reserved at submission (not at campaign creation, not at approval). This prevents overspend during the approval window — the company's credit balance is locked the moment they commit a campaign for review.

See Billing Overview for the full credit ledger lifecycle.


Glossary

TermDescription
CampaignTop-level advertising container owned by an Org::Company
PlacementA named ad slot on the website (supply side), managed by admin
Placement PriceA duration + credit cost deal for a placement (e.g. home_hero × 7 days = 5 credits)
CreativeA reusable image asset uploaded by the employer
CampaignPlacementA concrete ad unit: one creative running on one placement price within a campaign
Credit Cost Snapshotcredit_cost copied from ads_placement_prices onto ads_campaign_placements at booking time — frozen for the campaign's lifetime
Requested Start DateThe employer's desired start datetime for all placements — stored as 00:00 SGT of the chosen date (employer inputs date only). Minimum: MIN_START_DATE_LEAD_TIME days (2) from today. If omitted, placements go live DEFAULT_START_DAYS_AFTER_APPROVAL day(s) after admin approves at 00:00 SGT. If admin approves after this datetime has passed, placements go live immediately at approval time.
ImpressionRecord created each time a CampaignPlacement is served to a page visitor
Viewed ImpressionAn impression where the ad entered the user's viewport (tracked via IntersectionObserver beacon)
ClickRecord created when a user clicks an ad and is redirected to destination_url
Fair RotationServing algorithm that picks the ad with the oldest last_served_at, ensuring equal exposure
CTRClick-through rate: (total_clicks / total_impressions) × 100
View Rate(viewed_impressions / total_impressions) × 100 — how often an ad actually entered the viewport