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?
Email ReportWhich email campaigns move money?
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.
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 9 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 9 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.
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.
email-reportEmail ReportWhat each email campaign is worth: reach revenue + causal (bought-in-session / influenced) revenue + engagement funnel (sends → clicks), and product events. Reach metrics overlap across campaigns — never sum them. Omit campaign for the ranked list; pass one for its deep-dive.
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.
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