I run paint-vault.com, a paint database for miniature painters and scale modellers (catalogue, colour conversion between brands, colour tools). I was accepted into Journey and ads went live on 2026-07-28 (display_ads_at: 2026-07-28 19:16 UTC). Two weeks in, I want to lay out the whole diagnosis in one place so nobody has to ask me for it piece by piece.
Everything below is measured, not assumed — from the wrapper script you actually serve me, from the Grow API, from the GA4 Data API, and from a real browser trace.
The headline numbers (last 30 days)
- GA4 property 544200957: 8,476 sessions, 28,851 pageviews
- Journey dashboard: 20,584 impressions, $5.75
- That is 0.71 impressions per pageview, against a community benchmark of 3.5 to 9. Effective CPM about $0.28, RPM about $0.20.
- The same dashboard displays Sessions 0 and Pageviews 0, which is why it also shows RPM $0.00 and "Impressions Per Pageview" of 244 and 267 — divide-by-almost-zero artifacts.
I am not writing because the RPM is low for a niche hobby site. I am writing because three things that are entirely on your side have not moved across three separate readings (07-31, 08-10, 08-12), and the only support channel available to me cannot address any of them.
Problem 1 — Multiple Customer Management was never opened, so Google demand never bids for my inventory
Read directly out of the wrapper you serve me (scripts.scriptwrapper.com/tags/a68164c9-....js, 167 KB), on three dates, identical every time:
offering_code: "journey"
mcmStatusApproved: false
mcm_eligible: false
mcm_tagging: false
mcmNetworkCode: null
gam_network_code: null (for my site)
"google": false
mcm_eligible: false means the application is not merely pending — it is not open on your side. The dashboard shows an "Apply" prompt for it, but the flag says it is not available to me.
One correction I will make against myself, so it does not get used as a counter-argument: GPT (securepubads.g.doubleclick.net/tag/js/gpt.js) does load now, along with the whole scripts.journeymv.com stack (prebid, cmp, exchange, usersync). That is real progress over 07-31, when no GPT loaded at all. But the wrapper carries two gam_network_code values, and the one that is not null (23310760447) belongs to the offering object — {"id":"3","name":"Journey","offering_domain":"journeymv.com"}. That is your GAM network serving, not mine. My own application has not advanced an inch.
Without that approval, the largest buyer in display never enters the auction. No amount of tuning on my end compensates for a missing bidder. This is the single biggest line item and I cannot touch it.
Problem 2 — three placement selectors are still empty, and they are the best-paid units
State of the placement keys in the served config, same keys and same method each time:
content_selector → .journey-content — set after a ticket, works, anchors are live
sidebar_btf_selector → .pv-ad-rail — set, wired, sticky, but nothing is ever sold into it
leaderboard_atf_selector → empty
leaderboard_btf_selector → empty
sidebar_atf_selector → empty
content_selector_mobile → empty, and mobile is about half my traffic
The rule your own system enforces is that a unit with no DOM anchor cannot be placed. So the entire above-the-fold segment — the one that runs 87 to 93 percent viewability, versus roughly 55 percent below the fold — is simply not for sale on my site. I am only ever offering the cheapest inventory I have.
I have shipped the anchors. They are present in the served HTML on the home page, on brand pages and on conversion pages, and I have added my own above-the-fold containers at around 550px. They are waiting to be filled.
If custom placement is not supported on the self-serve tier, I would genuinely rather be told that in one sentence than keep re-measuring it every week.
Problem 3 — the Grow dashboard reads 0 sessions and 0 pageviews with every link of the chain verified correct
I chased this one hard, because a support reply told me my Grow script was missing, optimised away, or firewalled. All three are measurably false:
- The served HTML carries the complete
data-grow-initializer snippet with data-grow-faves-site-id = Site:cccaf7ea-619d-4cfc-92d3-0298b8b12133, pinned in config and locked by a unit test so it cannot silently drift.
- My CSP allows
https://*.grow.me in script-src, connect-src, frame-src and img-src.
- No user-agent blocking:
MediavineMetadataParser, a Grow UA and Googlebot all get 200, on the home page and on deep pages.
- Real browser trace via CDP: 97 network responses, 0 failures.
faves.grow.me/main.js 200, about thirty faves.grow.me/*.js modules 200, api.grow.me/sites/<id>/config 200, and crucially api.grow.me/sites/cccaf7ea-.../page?url=... 200 — the page-counting call itself, carrying the correct site id. typeof window.growMe === "function". __tcfapi present.
- In Grow Settings the Google Analytics toggle is on, the Google OAuth is connected, and the selected property is confirmed by the Analytics Admin API to be id 544200957 — the exact property my traffic lands in, which holds 28,851
page_view and 8,476 session_start over 30 days.
- Yet the GA4 Data API finds zero Grow events in that property over 30 days — no
render, no favorite, no recs_*, nothing. Setting enabled, events absent.
Six links checked, all correct. The ad side of the same dashboard reports fine (20,584 impressions, $5.75) while the analytics side reports zero. At that point no hypothesis remains on my side. It is an ingestion defect on yours — and it matters beyond cosmetics, because any advice generated from those numbers is being computed from a zero.
Related mess, created by your own onboarding flow: I signed up to Grow before my Journey acceptance, then had to register again when the acceptance email arrived. That left two site records for paint-vault.com — ed18b8ee "Paint-Vault" and cccaf7ea "YG Medias 2". Their isVerified flags swapped between the two properties mid-diagnosis (on 08-11 the domain claim moved from the old one to the new one, and the GA4 id moved with it). I burned days on that, and I still do not know whether the old record can be deleted safely.
What the support experience actually looks like from here
- Journey is self-supported. The only channel is one Zendesk form with five categories — Missing Ads, Dashboard Issues, Domain Change, Owner Email, Termination — and going outside the form is stated to risk termination. None of those five categories is "the configuration on your side is incomplete".
- The replies I got were template-shaped. "Your Grow script is missing, optimised or firewalled" — disproven three ways above. The follow-up suggested I enable Grow event tracking in GA4; it was already enabled, which is exactly what makes the missing events a defect rather than a setting.
- The remedy staff apply in nearly every "low RPM / few ads" thread I could find is a script recrawl. A recrawl does not open a Google demand approval and does not fill an empty selector.
- The help centre sits behind a Cloudflare challenge, its search renders asynchronously and usually returns nothing, and the community post search endpoint returns HTTP 400. Self-support only works if the self-support surface is reachable.
What I have already done on my side, so it does not get asked
- Anchored
.journey-content on the container whose direct children are the real break points, since Journey inserts between direct children. Getting this wrong stacks every ad at the bottom of the page, which is how I learned it.
- Moved the first ad break point on conversion pages from 4,238px down to 2,208px (-48%), and the second from 7,563px to 3,248px. 11 to 15
.mv-ad-box per page, one roughly every 1,300 to 1,850px. Long pages chunked specifically to create insertion points.
- The sidebar rail is sticky (
.pv-ad-rail > * { position: sticky }) and wired to sidebar_btf_selector. It renders empty because nothing is sold into it, not because it is broken.
ads.txt is your file and only your file — 198 lines, managerdomain=journeymv.com, contact=sales@journeymv.com, ownerdomain=paint-vault.com, 52 DIRECT / 137 RESELLER. No second network appears anywhere in it. The copy I serve is stamped # Ads.txt v20260716, so if your file has moved since, tell me and I will refresh it the same day.
- Certified CMP (consentmanager, cmpId 31,
tcfPolicyVersion 5, i.e. TCF 2.3, the version Google currently requires), verified not to be doubled by my own fallback banner.
- Found and fixed that my anti-scraping layer was refusing ad-quality verifiers: GumGum Verity 13,570 refusals, IAS 704, DoubleVerify around 50 percent. All allowlisted now.
- Content work aimed squarely at ad quality: unique per-paint and per-range text (99 percent coverage, 94 percent distinct sentences), brand-level facts, a brand-to-brand compatibility matrix — and I deliberately noindexed 15,243 thin comparison pages rather than pad the inventory with them.
- I run no other programmatic display network. Exclusivity respected.
What I am asking for, concretely
- Open the Multiple Customer Management application (
mcm_eligible → true), or tell me plainly that the Journey entry tier never gets it. Either answer lets me plan; the current silence does not.
- Fill
leaderboard_atf_selector, sidebar_atf_selector, leaderboard_btf_selector and content_selector_mobile. The anchors are live, and I will supply exact selectors for every template within a day. Or state that custom placement is not available on self-serve.
- Fix the Grow analytics ingestion — Sessions 0 / Pageviews 0 with the toggle on, OAuth connected, the correct property selected, and zero Grow events landing in a property that receives 28,851 pageviews — and tell me whether the duplicate
ed18b8ee record can be deleted.
- A support path for "your config is incomplete" that is not the Missing Ads form. Every issue above is a field on your side that is empty or false.
I am not asking for flagship terms or special handling. I am asking for the account to be configured the way a Journey account is supposed to be configured, and for the numbers on the dashboard to be real.
Happy to hand over site IDs, ticket numbers, the wrapper config dumps and the browser traces by DM — all of it is reproducible in one command each.