Overview
Ads by ROR is a serving engine: your site asks for an ad, the engine picks the best one and records the impression. The key idea is that code touches the site exactly once. Developers embed a slot; from then on editors create, schedule, swap, and retire ads from the dashboard, and the live site follows instantly — no deploys, no CMS edits.
Three concepts to know:
- Ads — text, image, or video creatives, grouped into campaigns that carry priority, schedule, and targeting.
- Sites & slots — a slot is one placement on a page, identified by a short key. Slots decide what they serve and how.
- The pool — the public campaign library shared across accounts (see below).
Quick start
- In the dashboard, open Sites & Slots, create a site, then add a slot. Each slot card shows its embed code.
- Paste the two snippets into your page:
<!-- once per page, before </body> -->
<script async src="https://YOUR-ADS-HOST/embed.js"></script>
<!-- one per ad placement -->
<div class="rr-ad" data-slot="YOUR-SLOT-KEY"></div>That’s the whole integration. The loader finds every .rr-ad div, fetches a creative for its slot key, and renders it in a sandboxed iframe sized to the creative — ads can never affect your page’s styles or scripts.
If nothing is eligible to serve and no house ad is set, the slot collapses to nothing — your layout never shows an empty box.
Managing ads (no code)
After the embed, everything happens in the dashboard:
- New ad — build a text, image, or video creative with a live preview.
- Campaigns — group ads, set priority (1–10), schedule start/end windows.
- Moderation — ads serve only after approval, so nothing off-brand goes live.
- Swap or retire — pause a campaign or delete an ad and the site updates on the next request.
The engine re-decides on every request, so changes are live immediately — there is nothing to rebuild, purge, or redeploy.
Public campaign library
Any campaign can be made public, which shares it to the pool. Other accounts browse the pool in Ad pool and add a shared campaign to their own slots with one click — its approved ads then rotate on their sites, with clicks landing on the campaign owner’s destination URLs.
This is how one team’s campaign (a program, a book release, an event) reaches every participating website without anyone copying creatives around.
Slots & sources
Each slot chooses what feeds it:
- My own ads (default) — all of your approved ads rotate.
- Campaigns — specific campaigns, yours or from the public library.
- Specific ads — hand-picked creatives.
- A mix — campaigns plus individual ads, each with its own weight.
Slots don’t fix the ad’s size — each creative keeps its own dimensions (capped to a safe maximum), and the iframe sizes to the creative.
Themes & rotation
Text ads render inside the slot’s theme — card, minimal, dark, festive — so they belong on the page. Rotation decides how the engine picks among eligible ads:
- Weighted (default) — campaign priority leans the dice; everything still gets exposure.
- Random — uniform pick.
- Sequential — a deterministic cycle.
A slot can also loop in place: set a loop interval and the embed fetches a fresh creative every n seconds.
Targeting
Campaigns carry region and language lists; ads carry a language tag. The serve request narrows by them:
<!-- the embed passes these automatically when you add them -->
GET /api/serve?slot=KEY®ion=africa&language=enregion— must match the campaign’s region list (empty list = everywhere).language— falls back to the slot’s language preference; untagged ads are universal.
House ad & fallback
The house ad is your fallback creative, set in Settings. It serves whenever a slot has nothing else eligible — scheduling gaps or targeting misses — so a placement is never blank.
If no house ad is set and nothing else matches, the slot collapses to nothing rather than showing an empty box.
Serve API (JSON)
Building a native app or a custom renderer? Ask for JSON instead of HTML:
GET /api/serve?slot=YOUR-SLOT-KEY&format=json
{
"filled": true,
"impressionId": "cmq7…",
"ad": { "id": "cmq1…", "title": "Healing Streams" },
"slot": { "key": "YOUR-SLOT-KEY", "width": 300, "height": 250 }
}Render the creative yourself, and send users through the click URL (below) so tracking still works. CORS is open on this endpoint, so it’s callable from any origin.
Tracking & analytics
Every serve logs an impression; every click routes through /api/click/:impressionId and 302-redirects to the ad’s destination. The Analytics page shows totals, a 30-day trend, and per-ad performance with CTR.
Every creative is labelled with an “Ad” badge and a “Sponsored” watermark, so served content is always disclosed.