To trace organic search to revenue, join three systems on the landing page path. Search Console gives you the queries and clicks per page over 90 days. GA4 gives you sessions, conversions and, for self-serve or ecommerce sites, revenue per landing page filtered to the organic medium. For sales-led businesses, HubSpot gives you contacts whose analytics source is organic search, grouped by the first page they landed on, and closed-won deals from that source. Stripe or Dodo Payments add direct revenue only when checkout stored the UTM or referrer in metadata. Normalise every URL to a path, join, and the result is revenue or pipeline per organic page, revenue per click, and the top queries behind each money page. Keep GA4 revenue and HubSpot revenue in separate columns, because they attribute differently and adding them double counts. An AI agent with authenticated access to each system runs the whole join in minutes.
TL;DR
| Question | Answer |
|---|---|
| Why an SEO tool cannot answer this | Revenue lives in GA4, the CRM or the payment provider, none of which know the query |
| Join key | Landing page path, after stripping origin, query string and trailing slash |
| Path A (self-serve) | Search Console to GA4 totalRevenue and ecommercePurchases |
| Path B (sales-led) | Search Console to HubSpot contacts and closed-won deals with source ORGANIC_SEARCH |
| Path C (payments) | Stripe or Dodo, only if checkout stored attribution in metadata |
| Never | Add GA4 and HubSpot revenue together |
| Playbook | organic-traffic-to-revenue |
This is the question a dedicated SEO tool cannot answer, because the answer lives in three systems: what people searched for, what they did on the site, and what they paid or became. Joining them is what turns an SEO number into a business number.
Every SEO has been asked "what did organic actually make us?" and answered with clicks. This guide is the procedure that answers with money. It is the same procedure Sequel's organic-traffic-to-revenue playbook hands to an agent.
What organic-to-revenue attribution is
Organic-to-revenue attribution is the join between search demand (queries and clicks per page) and business outcomes (conversions, pipeline, revenue) at the level of the landing page. It answers which organic pages earn money, how much per click, and which queries sit behind the money pages.
It is query-to-page-to-revenue, not query-to-revenue. No system records which query a paying customer typed. The page is the bridge, and the honest report says so.
Step 1: pick the revenue path
| Business | Where revenue lives | Path |
|---|---|---|
| Self-serve SaaS, ecommerce | GA4 ecommerce events | A |
| Sales-led B2B | HubSpot deals | B |
| Both | Both, kept separate | A and B |
| Checkout captured UTMs | Stripe or Dodo metadata | C, as a supplement |
Ask which applies if it is not obvious. Running path A against a sales-led site returns zeros and a wrong conclusion.
Step 2: pull the organic side
Two Search Console pulls over 90 days ending three days ago:
google_search_console.querywithdimensions: ["page"],rowLimit: 500google_search_console.querywithdimensions: ["query", "page"],rowLimit: 5000
Ninety days, not 28. The path from search to money is longer than the path from search to click.
Step 3, path A: revenue in GA4
google_analytics.run_report with dimensions: ["landingPage"], metrics: ["sessions", "conversions", "totalRevenue", "ecommercePurchases"], the same dates, and a dimensionFilter on sessionMedium equal to organic.
Join to Search Console on the normalised path. Compute revenue per organic click per page. The Search Console and GA4 join has its own four failure modes, and the agent handles the URL normalisation that breaks most spreadsheet versions.
If totalRevenue is zero everywhere, stop. The site is not sending purchase events. That is a tracking gap, and no amount of SEO analysis will fill it.
Step 3, path B: pipeline in HubSpot
HubSpot stores the original traffic source on every contact and, in most portals, on deals. The property names are usually hs_analytics_source, hs_analytics_first_url and hs_analytics_source_data_1, but portals differ. Call hubspot.list_properties for contacts and deals first rather than hardcoding.
Then:
hubspot.search_contactsfiltered to the source property equal toORGANIC_SEARCHandcreatedateinside the window, requesting email, create date and first URL. Group by the path of the first URL and join to Search Console pages. This gives leads per organic page.hubspot.list_pipelinesfor deals to learn which stage ids mean closed won.hubspot.search_dealsfiltered to the organic source and closed won inside the window, requesting amount, close date and the first-URL property if deals carry one. This gives revenue from organic at the account level even where deal-to-page attribution is missing.
Page through until exhausted. A partial pull silently understates everything.
The agent prompt:
Which organic landing pages created the most HubSpot contacts in the last 90 days, and how much closed-won revenue came from organic search?
If you have not connected HubSpot yet, the HubSpot and Claude Code guide covers it.
Step 3, path C: Stripe or Dodo Payments
A payment provider has no idea where a customer came from unless the checkout stored it. Ask whether UTM or referrer values are written to customer, subscription or payment metadata.
If they are: stripe.search with a metadata query on the organic value gives revenue directly. Dodo returns metadata on every row of dodo_payments.list_payments but cannot filter on it, so pull the window with status: "succeeded" and filter the metadata column in the workbench.
If nothing was captured, skip this step and say so. Guessing here is worse than a gap. The Stripe and Claude Code guide explains what the Stripe connector can and cannot see.
Step 4: attribute queries
For the top revenue pages, take their query rows from step 2 and report the queries as the demand behind the revenue. Keep the distinction in the write-up: this is query-to-page-to-revenue. The page earned the money; the queries are why the page had visitors.
Step 5: report
Top ten organic pages by revenue or pipeline, one row each:
| Column | Source |
|---|---|
| Page | Search Console |
| Clicks | Search Console |
| Sessions | GA4 |
| Conversions or contacts | GA4 or HubSpot |
| Revenue or closed-won amount | GA4, HubSpot or Stripe, in separate columns |
| Revenue per click | Computed |
| Top three queries | Search Console |
Then the share of total revenue or pipeline that organic accounts for, the pages with real traffic and no revenue, and the one or two queries most worth defending.
Gotchas that double count or understate
- Different systems attribute differently. HubSpot's source is first touch by its own tracking cookie. GA4's is session-scoped and defaults to last non-direct click, per Google's attribution documentation. Present each as what it is. Adding them double counts.
- HubSpot's
ORGANIC_SEARCHis HubSpot's classification, based on referrer. It includes all search engines and misses visitors whose referrer was stripped. - Sales cycles outlast the window. A deal closed this quarter came from a search last quarter. Use the contact's create date for lead attribution and the close date for revenue, and say the windows differ.
- Stripe amounts are in minor units. Divide by 100 once, and report per currency. Dodo does the same.
- Join on the path. Strip origin, query string and trailing slash from every system's URLs before joining, and report the unmatched share. A silent 30% unmatched rate is a wrong answer dressed as a right one.
Running it with an agent
Nobody does this join by hand more than once a quarter, because it means four exports and a fragile spreadsheet. That is why SEO reports stop at clicks.
An agent with authenticated access to each system does the join on demand and follows the same rules every time. Sequel supplies the connections over MCP, Search Console, GA4, HubSpot, Stripe and Dodo Payments in one place, and the playbook so the agent keeps GA4 and HubSpot in separate columns without being told. Our marketing analytics agents guide covers why cross-source joins are where agents earn their keep.
npm install -g @sequelsh/cli@latest
sequel install claude-codeThen ask:
Which organic pages made us money last quarter, and what were people searching for when they found them?
The agent reads organic-traffic-to-revenue through sequel_read_skill, picks the revenue path from what is connected, and returns the table. Follow it with organic-landing-page-conversion for the pages that get traffic and earn nothing, and paid-and-organic-overlap for the queries you are paying for twice.
Clicks are an SEO metric. Revenue per click is a business one. Get started free and report the second.
