FullVision

Introduction

Revenue, web, and attribution analytics through a REST API and an MCP Server

FullVision joins your Stripe revenue to your web traffic, your ad spend and your Google Search Console data, then serves the joined result as ready-made reports.

Use it when you want to know which channel, page, keyword, campaign, email or form actually produced paying customers — and you don't want to build the pipeline that answers that.

Three steps to your first answer

Get data in

Add the tracker script to your site — see Install the tracker. That alone gives you traffic, channels, landing pages and search keywords. Send server-side events as well when you want product events and named people.

Connect a revenue or channel source

Connect Stripe so payments join the graph, and pass two metadata fields on your Stripe creates so every payer links back to the visitor who arrived — see Revenue Attribution.

Ask a question

Read a report over the REST API, or connect an AI agent to the MCP Server and ask in plain language.

Two hosts, two jobs

HostWhat it is for
https://db.fullvision.ioWriting. The tracker script, server-side events and person traits, and the audience endpoints under /v1/audiences.
https://data.fullvision.ioReading. Every report and entity endpoint, and the MCP Server.

Each page states the host in its examples. If a call 404s, check you are on the right one.

Reports

Each report is one REST endpoint and one MCP tool. Most have a group form (omit the addressing key and you get a ranked list of everything) and a single form (pass the key and you get one entity's deep-dive).

ReportThe question it answers
Page ReportWhich landing pages bring in the customers?
Channel ReportWhich acquisition channels bring in the customers?
Keyword ReportWhich Google searches earn revenue?
Ad ReportWhich paid campaigns pay for themselves?
Form ReportWhich forms convert, and who filled them in?
VisitorsWho is my audience — devices, countries, return rate?
PeopleWho is this person, and how did they arrive?
JourneysWhat did this person actually do, step by step?
ReportTitleDescription
page-reportPage ReportWhat one page does for the business: traffic, engagement (scroll / form funnel / outbound / dead / rage / element clicks / Web Vitals), the revenue it drove, and product events — for one page or every page ranked. Revenue + events are first-touch attribution (people whose first landing was this page), not on-page conversions. Omit page_path for the ranked scorecard; pass it for one page's deep-dive. When someone names a page in words ("the email finder tool") rather than a path, call the group form with page_search first to find its page_path.
channel-reportChannel ReportWhich acquisition channels bring visitors and paying customers: traffic + attributed new/returning customers and cash, per channel bucket, and product events. Omit channel for all 10 buckets ranked; pass one for its sources, top landing pages and outcomes. page_url_scope applies to the traffic columns only (unique_visitors / page_views / sessions): the attributed customer + cash columns, and the whole sources array, are always cross-host, because attribution keys on the person's first touch rather than on a per-request host. /page-report splits the same way. series_by=channel_category splits the series by the same 10 buckets as rows[].channel; series_by=channel splits by concrete source (Google Ads, Bing, a referrer host), the grain of sources[].channel. Under either split each point carries attributed_visitors — the attribution cohort, the same measure as sources[].unique_visitors — not the host-scoped traffic unique_visitors of rows and of the flat series (split points also carry unique_visitors as a deprecated alias of the same cohort value until 2026-11-26; read attributed_visitors). form_submits — contact-bearing, deduplicated form submissions credited to the visitor's first-touch channel, the same recipe as /page-report — rides on rows[], on sources[].form_submits at source grain, and on the series (flat and under either split). Traffic columns and the flat series come from a rollup refreshed once a day (~06:06 UTC): the current day, and the previous day until that refresh, are partial and read as a uniform drop across every channel, while attributed columns refresh on their own schedule.
keyword-reportKeyword ReportWhich search keywords earn revenue: attributed revenue + Search Console metrics (clicks, impressions, CTR, position) + striking-distance and content-gap opportunity flags, and product events. Data is our synced GSC, not live. Omit query for the ranked list; pass a query for one keyword's trend and an optional live breakdown.
seo-opportunitiesSEO OpportunitiesRevenue upside of ranking higher on Google. For each page that earns organic first-touch new-customer revenue, its top 5 non-brand Search Console queries and the extra clicks and revenue it would earn at position #1, #2 or #3 (with a low–high range), from a click-through curve that blends the workspace's own Search Console data with a published benchmark. Pages too small to size are listed in insufficient_data. Group form only: drill into one page with page-report and gsc_breakdown.
ad-reportAd ReportWhat paid campaigns spend and earn: spend-ranked leaderboard with full- and fair-window metrics (fair = excludes un-matured days), plus campaign LTV/CAC/ROAS and product events (campaign-level only). Ranked by spend, not revenue (gclid joins are thin); LTV/CAC/ROAS is Google-only. Omit entity for the leaderboard; pass an id/name for one entity. Every row carries campaign_kind (cold or retargeting, from the campaign name matching retarget/remarket/rmkt/rlsa); read retargeting rows under a multi-touch model, never first touch. landing_pages is a fixed trailing-90-day, workspace-wide Google snapshot: it ignores from/to, level, entity and account_id and is returned even when rows is empty — never reconcile it against the windowed rows. level=keyword covers keyword-matched Search traffic only (Google's keyword_view): Display-expansion (Display Network) impressions and clicks carry no keyword and are absent, so keyword rows can sum far below the campaign; level=ad_group reconciles exactly, and a keyword-vs-campaign gap means non-keyword serving, not missing data.
form-reportForm ReportHow forms convert and what they capture: starts → submits + completion rate, reach + causal revenue, product events, and (single form) the captured-submissions list. Reach metrics overlap across forms — never sum them; submissions are PII. Omit form_id for the ranked list; pass one for the funnel + submissions.
bot-trafficAI & Bot Crawls ReportsWhich crawlers and automated browsers read your site: per crawler (ChatGPT, Claude, Perplexity, Google…) the server requests your server snippet reported, how many came from the vendor's published IPs, and the page views of crawlers that run JavaScript; the most-crawled pages; a daily trend by category; the split of tracked page views into human, agent and bot: automated lists bot page views excluded from web analytics (webdriver, datacenter not rescued), agents lists AI assistants browsing for a person (daily trend and top pages); and the last server crawler hit. server_requests and tracker_pageviews are different measurements of different requests — never add them. Group form only.
youtubeYouTube ChannelYour YouTube channel from the YouTube APIs: channel totals per day (views, watch minutes, subscribers gained/lost/net, thumbnail impressions and impression-weighted CTR, subscriber count), per-video totals for the range, one video's daily trend (needs video_id), views by traffic source, the top YouTube search terms, countries and device types (the channel's calendar months overlapping the range, or one video's lifetime with video_id), the audience retention curve (one video with video_id, else the views-weighted average of long-form videos), and video_revenue: visitors, customers and revenue per video from FullVision's own tracking (visits whose utm_source holds the video URL; video_id '' is YouTube visits with no video in the link; a customer reached through two videos counts in both). Data lags 2–3 days; impressions start 30 days before the channel was connected. These are YouTube-wide numbers; plays of videos embedded on the site are the web-videos view. All blocks empty means YouTube is not connected or the first sync is still running: suggest Setup → Data sync → YouTube. Group form only.
visitorsVisitorsWho your audience is as a whole and how much traffic the site gets: site-wide traffic (page views / visitors / sessions / bounce + human-vs-agent split, one row per host scope) + visitor retention cohorts + device / browser / country splits + active-hours heatmap (all host-scoped) + new-vs-returning and engagement top-line (workspace-grain, ignore page_url_scope). Group-only — no single visitor.
peoplePeopleFind people by who they are and how they arrived: a cursor-paginated list of person rows (identifiers + journey_id pointer), or one person + their lifetime-revenue summary and acquiring campaign. Never returns the event timeline — follow journey_id to journeys. Rows are PII.
journeysJourneysThe event-by-event timeline for a person or cohort — the only surface that returns timelines. Omit journey_id + q for a cohort (event window from/to REQUIRED); pass journey_id or q for one person. Two date axes: from/to = event window, created_from/created_to = who's in the cohort. Rows are PII.

Quickstart

curl -H "Authorization: Bearer $FULLVISION_API_KEY" \
  "https://data.fullvision.io/channel-report?range=last_30_days"

On this page