Marketing
The client's numbers, where you already work
Link each client's Google Analytics 4, Search Console, Google Ads, SE Ranking and Rank Math from one button; the numbers then appear on the client's own page, in a marketing tab and in one overview across every client. A measurement profile per client turns them into a leads dashboard that answers the questions of a hand-built Looker report, and below it sits how often AI answers mention the brand. Every comparison is against the same period last year by default, and the screen says so in words.
Five sources and a container, linked from one button
A client gets its own links: a GA4 property, a Search Console site, a Google Ads account, an SE Ranking project and a Rank Math brand. They all come from one button, Bron koppelen, on the marketing tab and on the client page, and the client's Tag Manager container sits there too: not a source with daily figures, but a connection whose live tags and unpublished changes show on the panel. Several links per source are allowed, so a client with two brands keeps them apart, and each link can hang on one website of that client. The account pickers search as you type and show exactly what the signed-in colleague's connection can actually reach, and an empty list explains why it is empty and what to do next. A missing Google connection decides a sentence, never whether a button is drawn: an SE Ranking project or a Rank Math brand links fine on an install with no Google account at all.
- No Google account connected yet: the "Connect Google" button sits right there
- Missing scopes: reconnect and grant access to that one source
- Access revoked: the link reads "Connection lost"
- The API is off in the Google Cloud project: reconnecting won't help, and it says so
- Google Ads without a developer token: the screen points you at Instellingen → Marketing
- Rank Math without a finished WordPress setup: a checklist naming the missing step, with a button to the right place in wp-admin
On the client page, in a tab, across every client
Every client page carries the Marketing panel: the last 30 days against the same 30 days last year, KPI rows with the delta, sparklines, and the linked accounts as chips with "Open in Google Analytics" behind them. That panel reads entirely from our own database and makes zero calls to Google, so it opens as fast as the rest of the record. To look further, the client's marketing tab offers the leads dashboard, longer ranges, the drilldowns and AI visibility; the Marketing page in the sidebar renders the same dashboard with a client picker above it, so it is one screen with two entrances. Overzicht → Marketing puts one row per linked client beside it, sortable server-side, so over coffee you can see who needs attention. The built-in assistant answers the same questions: six read tools give a client's figures with the compared span, the table behind a tile, what is linked and the cross-client grid, each behind the same permission as the screen. Licence the reporting module too and marketing supplies twelve of the chapters in the monthly client report.
- Client panel: 30 days against the same 30 days last year, with sparklines and account chips
- Client tab: leads dashboard, longer ranges, drilldowns, AI visibility and the layout editor
- Overzicht → Marketing: sources, sessions, clicks, avg. position, spend, conversions and key events per client
- A dashboard tile for the team, and a tile on the client's own portal dashboard
KPIs you can open up
Each source contributes its own KPI row, with the change beside it and the figure it was measured against ("−20.6% vs € 1,211.73"). You pick the range: last 30 days, this month, last month, this quarter, last 90 days, the last 12 months, a month or quarter from the picker, or a span of your own with a start and an end date. Under the tiles sit the drilldowns, fetched from the source rather than synced along: top pages, channels, devices and key events per event from Analytics; top queries, top pages and the biggest movers from Search Console; campaigns from Ads; and keywords, keyword groups, the site audit and AI-search visibility from SE Ranking. An answer from Google is kept for a day, and early each morning a job reads every client's tab the way a colleague would open it, so whoever starts at nine does not wait on Google. The tiles themselves come from the daily figures pulled overnight, so switching range costs no Google quota.
- Analytics: sessions, users, new users, key events, conversions, engagement, revenue and channels
- Search Console: clicks, impressions, CTR and average position, plus impressions in AI once the Generative AI report's export has been uploaded
- Google Ads: spend, clicks, impressions, conversions and conversion value
- SE Ranking: average position, Top 3, Top 10, Top 30, ranking and tracked keywords
A leads dashboard per client, without a Looker report per client
An agency built one Looker Studio report per client: five pages of the same fourteen questions, asked in that one client's event names. What differs per client is never the dashboard but the vocabulary: which event is a request, which parameter carries the service, and what internationaal-transport is called on screen. That vocabulary is the client's measurement profile: seven roles (request, form started, form submitted, form error, phone click, e-mail click, application) mapped to that client's GA4 events, the dimensions the dashboard may group by with a label per value, which form types count as a quote, which Google Ads conversion action belongs to which service, and the dates the measurement changed. The editor picks everything from the client's own property and Ads account, so nothing is typed from memory. The questions themselves are a fixed catalog: requests, quotes, phone and e-mail contact, by service, by day, by channel, by page, started versus submitted, failed submissions, and an advertising half with cost, conversions and missed impressions per campaign. A second client is configuration, not a new report.
- A click on a service or a row filters the whole page through the URL, so a filtered dashboard is a link and the back button undoes the click
- A widget the profile cannot answer is withheld and named, never drawn as zero: "no funnel" and "100% dropout" are different sentences
- A sampled answer, thresholding, an unregistered dimension or a week with traffic and not a single request sits beside the figures as a warning
- GA4 events and ad costs are never joined on a date; every figure names the one report it came from
- Tables sort, page and export as CSV
How often AI answers mention the client
Below the sources sits visibility in AI search engines, from SE Ranking's AI Search figures: brand mentions, links to the site, average position and AI opportunity traffic, across ChatGPT, Perplexity, Gemini and Google's AI Overviews and AI Mode, last month against the month before with a six-month chart. Every read spends units of your own SE Ranking Data API plan, so it is off by default and the price is on every control that spends it: the house setting, the client and Opnieuw ophalen. A month is read once and stored, even when two colleagues open it at the same moment. When SE Ranking has not published the month yet, or does not know the site, the screen says so in words rather than as a row of dashes. Search Console shows how often a site appears in AI Overviews and AI Mode too, but returns that figure through no API: the card says so plainly, links to the Generative AI report and takes its export, after which impressions in AI becomes an ordinary tile with a trend and a comparison. A period with no upload stays empty and is never zero.
- Brand, domain, country database and engines per client, with the house setting as the default
- A separate Data API key is allowed, because SE Ranking issues one key per API
- In the portal the client reads the figures under the name you gave the source, with no vendor name and no notes about your setup
You compose what the client sees, and what it is called
You edit a client's dashboard the way you arrange your own My Day: hit "Edit layout" and you drag tiles to reorder them, hide what this client does not need (hidden tiles wait in a strip below), rename them in place in Dutch and English, switch drilldowns on or off, pick the default chart, or hide a whole source for this client. Everything saves immediately, and the layout is exactly what a portal login sees. Hiding happens server-side: a hidden tile drops out of the data the panel, the tab and the overview receive — it is not merely pushed out of view in the browser. Until you touch it nothing changes, because no layout simply means: show everything. That same editor is where a conversion gets a name of its own, because GA4 calls it whatever a developer once created it as.
- GA4 says generate_lead; the client reads "Website enquiries"
- Your own name per key event, per language, typed in the row where that event sits
- The GA4 event name stays the reference underneath, so the figures keep adding up
- An event not measured this period is added by its raw GA4 name
- Rather not share conversion figures? Switch the key-events tile off for this client
A graph that goes stale says so
Every link carries its own status: Synced, First sync running, Sync error or Connection lost, with "Last synced …" beside it. Where a link runs through a colleague's Google account and that connection drops, the screen names the person: that is who to ask. Overnight a job per organisation pulls the daily figures and re-pulls the last week while it is at it, because Search Console only finalises two to three days later and Analytics attribution keeps shifting for a while. For Google Ads that is thirty days: Google credits a conversion to the click's day until the conversion window closes, and a month re-read for only a week stood year over year with too few conversions against a year-ago month that had long since settled. Each link runs independently, so one broken connection never stops the rest. Creating a link kicks off a backfill of roughly thirteen months, committed month by month, so sparklines and year-over-year work from day one. Unlinking erases nothing: the link is deactivated, the synced history stays, and relinking switches it back on.
Keys, permissions and licence
Marketing rides on your agency's own Google connection: you register your own Google Cloud project and the marketing scopes are asked for in that same consent screen, so a colleague does not walk through Google three times. Under Instellingen → Marketing you set the SE Ranking API key (one key for the whole agency, which every client project is attached to), optionally a separate SE Ranking Data API key for AI visibility, and the Google Ads developer token; they are stored encrypted and never handed back, the screen only reports that a key is on file. Checking the key costs nothing and says per API whether the key gets in and how many Data API units are left. Under Namen van bronnen you give a source your own name, and that name then appears on the marketing page, the client page and in the portal, down to the sentences around it; a client never reads your supplier's name. Permissions are separate from one another: reading the figures is a default for every team member, creating links is admin work, and the cross-client overview is a management screen. The core of schakl. is open source (AGPL); marketing is an extension module and needs a licence key. When one expires the module goes read-only: linking and settings refuse and the nightly sync stands down, while the panel, the tab and the overview keep showing the figures already pulled.
- Read marketing metrics: default for every team member, narrowable if you treat ad spend as sensitive
- Manage marketing links: admins, like the Google settings themselves
- Read the marketing overview: the cross-client screen, managers by default
- A portal login only ever sees the dashboard you composed for that client, with no links into Google and no colleagues named
A period is a name, not a number of days
The question an agency actually gets is "how did July go?", and counting thirty days back from today does not answer it: that is 11 July to 9 August, which is not a month anybody reports on. So one token names the span: a trailing window, a rolling preset like this month or last quarter, a frozen period like 2026-07, or a span of your own from date to date, so a measurement breakpoint can be where a link starts. A tab then still means "last month" next month, while a link you paste into a chat keeps showing the month you were looking at. The label is decided by the dates rather than by the word you picked. The comparison works the same way: a percentage is a claim about two spans, so both are on the screen, in words ("compared with the same period last year (23 Aug - 21 Sep 2025)") rather than as "vs previous period". Last year is the default, because seasonality makes the month before meaningless; you can have the dashboard compare against the previous period instead, with a per-client override.
- A period-to-date with no complete day falls back to the previous whole one; 1 August has no August to show
- A period you named yourself is never silently substituted
- The cross-client overview deliberately ignores the per-client override, because percentages with different denominators rank nothing
Want to know more?
The documentation describes every module in detail, from installation to permissions.