Publisher docs
Add the ads script to your site, place an ad, and earn
Add the script
Paste this right before </head> on any page you want ads on. Grab it from your site's page — it already has your site key baked in, so it's ready to use as-is.
<script src="https://anything-advertising.com/ads/embed/YOUR-SITE-KEY.js" async></script>
Example — dropping it into a plain page:
<!DOCTYPE html>
<html>
<head>
<title>My Speedrun Guide</title>
<script src="https://anything-advertising.com/ads/embed/YOUR-SITE-KEY.js" async></script>
</head>
<body>...</body>
</html>
If your site runs off a shared layout — a WordPress header.php, a Jinja base.html, a Next.js layout.tsx — drop it in there once and every page picks it up. It renders whatever default spots you've saved for the site, so turning ads on or off later is a settings change, not a deploy.
Default page ads
Every site gets six floating spots it can fill on every page automatically: a banner stuck to the top, one stuck to the bottom, and a card in each of the four screen corners. Turn any of them on and the script places them without you touching a single page — a reader can close any of them at will.
Tick the spots you want when you register a site, or flip them any time from its settings. Leave all six unticked and the script won't place anything on its own — you'll only get ads where you put a container by hand (next section).
Place ads by hand
One page can override its saved default spots by adding an attribute to its script tag. data-aa-spots takes a comma-separated list of spot names:
<script src="https://anything-advertising.com/ads/embed/YOUR-SITE-KEY.js"
data-aa-spots="top-banner,bottom-right" async></script>
Or drop a container straight into your markup — any empty element becomes a slot. Give it a real size, since an ad has nothing to fill inside a collapsed, zero-height <div>:
<div data-aa-ad style="width: 300px; height: 250px; margin: 24px auto;"></div>
Add as many as you like. Each one loads independently once it scrolls near the viewport, so a container near the bottom of a long page never delays the ones above it.
Corner overlays are transparent, image-only cards by default. Any hand-placed container can restyle its card: data-aa-radius rounds the corners from 0 to 32px, and data-aa-shadow changes the card shadow.
<div data-aa-ad="overlay" data-aa-radius="12" data-aa-shadow="none"></div>
data-aa-shadow takes none to drop the shadow, a number for the shadow's blur radius, or any CSS box-shadow value — for example data-aa-shadow="0 4px 16px rgba(0,0,0,.3)".
| You add | Where the ad appears |
|---|---|
| Script only | Your saved default spots |
data-aa-spots | Overrides the saved spots on that page |
<div data-aa-ad></div> | In the page, sized to its container |
<div data-aa-ad="banner"></div> | Sticky bar at the bottom of the screen |
<div data-aa-ad="top-banner"></div> | Sticky bar at the top of the screen |
<div data-aa-ad="overlay"></div> | Floating card in the bottom-right corner |
data-aa-radius="12" | Rounds the ad's corners from 0 to 32px |
data-aa-shadow | none drops the card shadow, a number sets its blur radius, and any other value is used as a CSS box-shadow |
<div data-aa-ad="top-left"></div> | Floating card in that corner: top-left, top-right, bottom-left or bottom-right |
data-aa-keywords | Overrides the topics inferred from the page for that page load |
Ads are matched to the page they sit on. The loader reads the page's title, meta keywords and top headings into a few topics, and a suitable creative is preferred; set data-aa-keywords="minecraft, anarchy" on the script tag when a page needs to say it itself. Your saved site keywords cover pages that report none, and what each page reported is listed under your site settings.
More containers mean more revenue, but the rate per ad tapers fast — two or three well-placed slots typically out-earn a page crammed with eight.
Once a slot resolves, its container gets data-aa-ad-status set to loading, filled, empty, closed, limit or error — style around a dead slot instead of leaving an awkward gap:
[data-aa-ad-status="empty"] {
display: none;
}
If you add containers after the page has already loaded — an infinite-scroll feed, a client-side route change — call window.AAAds.refresh() so the script notices them.
Older snippets that use data-ogc-* attributes or window.OGCAds still work, but those names are deprecated. Switch to data-aa-* and window.AAAds.
Creative sizes for advertisers
A creative is placed by shape, so upload one of these sizes and it drops into its slot pixel-perfect:
| Size | Best for |
|---|---|
| 728 × 90 px | Top and bottom bars |
| 970 × 250 px | Top and bottom bars |
| 320 × 100 px | Top and bottom bars |
| 320 × 50 px | Top and bottom bars |
| 468 × 60 px | Top and bottom bars |
| 300 × 250 px | Corner cards |
| 336 × 280 px | Corner cards |
| 250 × 250 px | Corner cards |
| 200 × 200 px | Corner cards |
| 1200 × 400 px | In-page units |
| 300 × 600 px | In-page units |
| 160 × 600 px | In-page units |
Off-size creatives still run — they're just scaled to fit, which can shrink a 300 × 250 down to something closer to 250 × 208 on a tight corner card. Keep at least ~10px of clear margin around any text or logo so it survives that scaling and stays legible.
Campaigns are created and managed in the Advertise tool, where you pick a pricing model and set your bid. That auction is the next section.
Bidding for delivery
Every campaign pays per impression and per click together. A CPM bid is the most you'll pay for 1,000 impressions; a CPC bid is what a clicked view costs instead of its impression. Set both, upload your artwork, and the campaign runs on its own. Bids are entered in US dollars with up to two decimal places and are validated on the server, so the numbers you type are the numbers the auction actually uses.
Every time a slot is about to render, the eligible campaigns are scored on expected payout — a CPM bid stands as-is, and a campaign's CPC bid adds the click premium it's expected to earn, weighted by its predicted click-through rate — and the highest score wins the slot. Ties are broken at random.
Example. You bid $3.00 CPM and $0.60 CPC, with a predicted 1.5% click-through rate. Your expected payout is $3.00 + ($0.60 − $0.003) × 0.015 × 1,000 ≈ $3.90 per 1,000 impressions.
An impression is charged your CPM bid divided by 1,000: a $2.00 CPM bid costs $0.002 for a view that isn't clicked. When a visitor clicks, that same view is charged your CPC bid instead of its CPM cost, so a clicked view always costs exactly the click bid — not both. Your CPC bid must cover at least the per-impression cost it replaces, so a click can never make a view cheaper than an impression.
A click only bills when it's verified: the embed saw a real pointer or keyboard interaction on that ad, following an actual on-screen view of that same placement. Automated, replayed, or impossibly fast clicks — say, one that lands 4ms after the ad renders — get logged for review and are never charged.
Every campaign uses this combined model. Campaigns created before it were upgraded automatically, keeping their remaining budget and their bids.
A bid alone doesn't win a slot. To even enter the auction, a campaign needs:
- An account in good standing
- To be active, approved, and inside its own schedule and targeting
- A creative that fits the placement
- A bid that clears the effective floor for its pricing model — for a combined campaign, both the CPM and CPC floors — the network minimum or the publisher's own floor, whichever is higher
- Package units, package budget, and daily budget still left to spend
Miss any one of those and the campaign simply sits out that auction. A bid is a ceiling on what you'll pay, never a guarantee of delivery.
The network floor sits at $0.50 per 1,000 impressions for CPM and $0.05 per click for CPC — no campaign can bid below the relevant minimum, enforced server-side rather than left to the browser. A network ceiling applies too, so a fat-fingered extra zero can't commit an absurd amount.
The package is bought up front at your CPM bid, rounded up to whole cents: 1,000 impressions at a $2.00 CPM bid costs $2.00. Click charges are paid from that same package budget, so a click-heavy campaign finishes its budget sooner. A daily budget caps what the campaign spends in a UTC day; once it's hit, the campaign sits out auctions until the next day starts. The campaign stops for good once its purchased impressions or package budget run out, and closing it early refunds only what it never delivered.
Losing an auction costs you nothing — that impression just goes to whoever won it. The same bid can deliver steadily on one site and barely show up on another, so raising it is how you compete for the auctions you're currently losing. Campaigns running since before bidding existed kept the flat rate they were bought at as their starting bid.
Page targeting
By default, every page on your site can show ads. In the site's settings you can narrow that with two lists. Each line is a path, where * matches any run of characters and ? matches exactly one.
| List | Effect |
|---|---|
| Only these paths | When set, only matching pages may show ads. Blank means every page. |
| Never these paths | Matching pages never show ads, even when the allow list matches. |
Example — open every guide and download page, but keep the staff-only guides ad-free:
/guides/*
/downloads/*
/guides/staff-only/*
/guides/staff-only/setup matches the allow list above, but the block list still wins — that page never shows ads no matter what the allow list says. You can paste a full page address; only its path is used. Saved changes apply to new page loads within a few minutes.
Ad categories
Every creative is tagged with a category when it's submitted. In the site's settings you can keep your pages to a set of categories, or rule categories out entirely.
| List | Effect |
|---|---|
| Allowed categories | When set, only creatives in these categories are served. Blank allows any. |
| Blocked categories | These are never served to your pages, even when allowed. |
Names are comma-separated: gaming, software, hardware, crypto, finance, education, entertainment, shopping, services, travel, health, privacy & VPN, dating, casino & betting, adult, other. New creatives are reviewed before they can serve.
Example. Allowed is set to gaming, software, crypto and Blocked is set to crypto — a crypto creative never serves to your site, even though it's also sitting in the allow list. Same rule as page targeting: the block list always wins.
Addresses and keys
List every address your site runs on, one per line — including both the bare domain and www if you answer to both, since browsers treat them as different origins:
yoursite.com
www.yoursite.com
Only pages on those addresses can load ads or report activity — the list is what stops another site from taking your embed and using it as its own. A site whose list is empty serves nothing.
Your site key is public: it's right there in the embed snippet, so anyone who views page source can read it. That's expected — the address list, not the key, is what actually protects you. If a key is ever abused, rotate it from the site's settings and update the snippet; the old key stops working immediately.
Pausing a site stops it serving and reporting straight away. You can register up to five sites per account — delete one to free a slot.
How ads are served
- Each container gets one creative, and the same spot tends to favour a different one on the next visit — so a reader doesn't see the same ad every time.
- Paid campaigns compete for the slot on expected payout, and the highest one wins. A campaign pays its CPM bid for each impression, and a click upgrades that view to its CPC bid. A campaign that doesn't clear both floors can't win at all. If no paid campaign clears the floors, the container just stays empty and reports that.
- A view only counts once at least half the ad has been on screen for a full second — a hidden, tiny, or off-screen container earns nothing, and a click on a placement that was never actually viewed isn't billed either.
- The creative runs isolated from your page: it can't read or change your content, and your page's styles can't break it.
- Every ad carries a close control and a report link. Closing one hides it for that page view only — a reload can bring it back, which is what keeps a slot's value steady over time. Reports go through this site and require an account, so they're attributable.
Set your floors
By default your site accepts any campaign that clears the network minimum. If you'd rather not run cheaper ads, set your own floor from the site's settings — one for CPM, one for CPC — in US dollars with up to two decimal places. Clear a field to remove that floor.
A floor is checked before an ad is even chosen: a campaign must clear both your CPM floor and your CPC floor. Anything under an effective floor simply doesn't run on your site — it's not shown as a cheaper fallback. The effective floor is always the higher of the network minimum and your own, so setting yours below the network minimum has no effect.
Example. The network minimum is currently $0.50 CPM. Set your own floor to $0.30 and nothing changes — $0.50 wins as the effective floor either way. Set it to $1.50, and only campaigns bidding $1.50 CPM or higher can compete for your inventory. Changed floors apply to new page loads; no change to your pages is needed.
It's a real trade-off. A higher floor pays more per unit when it fills, but fewer campaigns clear it, so fill rate can drop and more slots stay empty. Starting near the network minimum and raising it only once your pages fill reliably is usually the safer move.
Earnings and cash-out
Every served ad earns money for the site's owner. Your balance shows in your chosen display currency, and the earnings page breaks it down: earned in the window, pending, this month, and lifetime.
Your balance cashes out in Bitcoin from the earnings page, which shows the minimum and your progress toward it. Payouts are requested in BTC and reviewed before they're sent.
You earn a fixed share of the winning charge on whatever your pages serve — 70% by default. At that rate, a $2.00 CPM impression pays you $1.40, and a $0.20 verified click pays $0.14. More traffic and better-placed ads earn more; the analytics page's RPM figure (earnings per thousand impressions) is what lets you compare pages and time ranges on equal footing.
Track performance
The analytics page covers the last 7, 14, 30 or 90 days. A few terms come up there:
- Impressions
- Ads delivered to your pages.
- Views
- Ads that were actually seen, as a share of impressions.
- Clicks and CTR
- Clicks through to an advertiser, and clicks as a share of impressions.
- RPM
- Earnings per thousand impressions in the selected range.
You'll also find a per-site breakdown, earnings by placement, your top-earning creatives, and the hours and weekdays when visitors engage most (all times in UTC).
If an ad doesn't show
- Check the script sits in the
<head>of the page. - Check the embed URL ends with the key shown on your site's page.
- Make sure the site is active and the page isn't ruled out by page targeting.
- Check the address you're viewing is on the site's address list.
- In-page ads load once they scroll near the viewport — scroll down before assuming one is broken.
- Check the container's
data-aa-ad-statusvalue in devtools to see what actually happened to it. - Open the browser console and network tab for a blocked or failed request — a CSP violation shows up there immediately.
- If your pages use a Content-Security-Policy, allow this script's host in
script-src,img-srcandconnect-srcso the loader, its creative, and its requests can all load:
script-src 'self' https://anything-advertising.com;
img-src 'self' https://anything-advertising.com;
connect-src 'self' https://anything-advertising.com;
- Changes to your saved setup can take a few minutes to appear. Give it a moment, then hard-refresh a test page.
FAQ
How long do changes take to appear?
Saved settings reach your pages within a few minutes. Give it a moment after saving, then hard-refresh a test page before checking the result.
Do I need to replace the script when I change default spots?
No — the embed already reflects your site's saved setup, so the same script keeps working. The only time you need to swap it out is after rotating your site key.
Why is one of my containers empty?
Check the site is active, the page is allowed by page targeting, and the address you're viewing is on the site's list. A blocked category can also leave a slot with nothing eligible to serve. If the ad sits below the fold, scroll it into view so loading can even begin.
Can I round a default corner ad?
Default corner placements are intentionally square and image-only. Add your own data-aa-ad="overlay" container with data-aa-radius when you need a custom radius.
What does the close button do?
It hides that one creative for the current page view, for that reader only. A reload may bring the spot back, and no other visitor is affected.
Can I use this on a site I don't own?
No. We verify a site by fetching a page from one of its listed addresses and checking that your embed is on it — something only someone who controls the page can arrange. Verification runs automatically when you open your dashboard after adding the embed, and changing the listed addresses clears it until the next check. Accounts that abuse this get removed.
An ad shows as empty with no error. Why?
The slot loaded fine, but nothing was eligible to fill it: campaigns may be out of budget or impressions, no bid may clear your floor, or your category rules ruled everything out. The slot stays empty until a campaign becomes eligible — it should fill again as new campaigns come in.
Can I place several ads on one page?
Yes. Every container fills on top of your default spots, but the rate tapers after the first few, so a page earns more per ad when it isn't crowded. There's a ceiling on how many placements count per page — anything past it reports limit.
No sections match your search.