# MCP tool reference

> Every tool odo’s MCP server offers assistants, with what it answers and the inputs it takes, read from the server’s own definitions.

odo’s MCP server offers 44 tools. This list is read from the server’s own definitions whenever the docs are served, so it’s always the tools a connection gets, worded as assistants see them. To connect, see [AI assistants](https://odo.gg/docs/mcp).

Each tool only reads, unless it says it writes. Tools take a project by its id or name (from `list_projects`); without one they read your only project, all of your own together, or the one project a connection is limited to.

## Common inputs

Most tools take some of these, the same way each time. Under each tool they’re named, not repeated; a tool that takes one differently lists it in full.

- `project` (text). A project id or name (see list_projects). Leave it out for your only project (all of your own together when you have several), or for the one project this connection is limited to.
- `range` (`today`, `7d`, `30d`, `90d` or `12m` · default `30d`). today, or the last 7d, 30d, 90d or 12m (ending now).
- `site` (text). A website id or domain (see list_projects). Leave it out for all websites in the scope.
- `filters` (object with `channel`, `source`, `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `page`, `entry`, `exit`, `country`, `region`, `city`, `device`, `browser`, `os` and `goal`). Narrow to visits matching every filter, using values exactly as rows show them: channel (Direct, Organic Search, Organic Social, AI, Paid, Email, Referral), source (e.g. Google), page or entry/exit (a path like /pricing), country (ISO code like DE), device (desktop, mobile, tablet), browser (Chrome, Safari…), utm_campaign, goal (a goal name or id)…
- `event` (text). Count a custom event (e.g. "Signup") as converting.
- `goal` (text). Count a goal set up in odo (its name or id) as converting.
- `page` (text). Count reaching a page as converting (a path, \* as a wildcard: "/thanks", "/order/\*").
- `path` (text). Only pages matching this path (\* wildcards: "/pricing", "/checkout\*"). Leave it out for the whole site.

## Earnings

### `list_projects`

**Projects, sources and websites.** Lists the odo projects this connection can read, with each one’s earnings sources (Stripe, ad networks, stores…), their sync status, its measured websites, and the notes its team keeps for Claude (context in their own words, dated: what a product is, something paused on purpose). Start here to learn project and website ids, and what the team wants you to know.

No inputs.

### `get_earnings`

**Earnings right now.** Earnings today, this month and this year so far (confirmed, and the live counter’s estimate), compared with the same point of the previous period exactly as the dashboard compares them, with goals, the current earning pace per hour, where today should end, and each source’s share and sync status.

Takes the common `project`.

### `get_earnings_history`

**Earnings history.** Earnings per day, week or month for a date range (up to about 400 days back), optionally split by source, with the total, the average and the best period.

- `from` (text). First day, YYYY-MM-DD (your time zone). Default: 29 days before `to`.
- `to` (text). Last day, YYYY-MM-DD. Default: today.
- `group_by` (`day`, `week` or `month` · default `day`). Weeks start on Monday.
- `by_source` (`true` or `false` · default `false`). Split each period by source.

Also takes the common `project`.

### `get_source_metrics`

**Source metrics.** For each source over the last 30 days vs the 30 before: payment sources’ gross, fees, refunds, net, number of payments and average payment; ad networks’ revenue, impressions, clicks, CTR and eCPM.

Takes the common `project`.

### `get_earning_patterns`

**Earning patterns.** When money comes in: today so far vs yesterday and a typical day at this hour, average earnings by weekday (last 12 weeks) and by hour of day (last 60 days), the best day, and the streak of days with earnings.

Takes the common `project`.

### `get_recent_transactions`

**Recent transactions.** The latest payments, refunds, disputes and fees (and ad revenue increases), newest first, with the source, time and amount (and the original currency when converted).

- `limit` (whole number, 1–30 · default `20`).

Also takes the common `project`.

## Verified numbers

### `get_summary`

**Summary (verified).** One project’s earnings, visitors, conversion rate and money per visitor for a range, in its currency. Each figure says how much of it is verified (odo reads the provider itself) versus self-reported: say which when you quote one.

- `range` (`today`, `7d`, `30d`, `90d` or `12m` · default `30d`). today, 7d, 30d, 90d or 12m (the last 12 months), in the project’s time zone.

Also takes the common `project`.

### `get_channels`

**Channels (verified).** Visitors, traced revenue, conversion and revenue per visitor for each channel (Direct, Organic Search, Social…), with the verified part of each channel’s revenue.

- `range` (`today`, `7d`, `30d`, `90d` or `12m` · default `30d`). today, 7d, 30d, 90d or 12m (the last 12 months), in the project’s time zone.
- `model` (`first` or `last` · default `last`). Which visit a sale is credited to: the last that came from somewhere (last), or the first ever (first).

Also takes the common `project`.

### `get_sales`

**Recent sales (verified).** The latest sales, refunds and disputes: amount, source, its tier (verified or self-reported) and the channel the sale was traced to.

- `range` (`today`, `7d`, `30d`, `90d` or `12m` · default `30d`). today, 7d, 30d, 90d or 12m (the last 12 months), in the project’s time zone.
- `limit` (whole number, 1–100 · default `20`). How many, newest first.

Also takes the common `project`.

### `list_sources`

**Sources (verified).** Every source a project earns from (Stripe, an ad network, a webhook…), with its tier, whether it shows the Verified badge (and why not), and what it earned today, this month and this year.

Takes the common `project`.

## Traffic

### `get_traffic`

**Website traffic.** Website analytics for a range: visitors, visits, pageviews, bounce rate, time on site and attributed revenue vs the comparison span, the trend, and top channels, sources, campaigns, pages, countries, devices, events, goals and paying customers. Filters narrow everything to matching visits.

- `compare` (`previous`, `week`, `year` or `none` · default `previous`). What changes are measured against: previous (the span just before), week (today vs the same day last week), year (the same dates a year earlier), none.
- `include` (any of `channels`, `sources`, `campaigns`, `utm_sources`, `utm_mediums`, `utm_contents`, `pages`, `entry_pages`, `exit_pages`, `countries`, `regions`, `cities`, `devices`, `browsers`, `operating_systems`, `events`, `goals`, `customers` and `weekday_hours` · default `["channels","sources","pages","countries","devices","events","goals"]`). Which breakdowns to add (top rows each). goals: conversions per goal; customers: paying visitors and how they found the site; weekday_hours: visits by weekday and hour.
- `limit` (whole number, 1–50 · default `10`). Rows per breakdown.
- `series` (`true` or `false` · default `true`). Add the trend over the range (by hour, day or month).
- `credit` (`first` or `last` · default `last`). Which visit gets a payment’s credit: last (the latest visit not Direct) or first (the very first).

Also takes the common `project`, `site`, `range` and `filters`.

### `get_live_visitors`

**Visitors right now.** Who is on the websites right now: visitors online, visitors per minute over the last 30 minutes, the pages they are on, where they are, and the latest pageviews, events and payments.

- `limit` (whole number, 1–50 · default `15`).

Also takes the common `project` and `site`.

### `list_visits`

**Visits.** Individual visits in a range, newest first (a page at a time): entry and exit pages, source, campaign, location, device, engagement and revenue. Use filters to find e.g. visits from a campaign or that reached a goal.

- `before` (whole number, above 0). `next` from the previous page, for older visits.

Also takes the common `project`, `site`, `range` and `filters`.

### `get_visit`

**One visit.** One visit’s full story: every page (time spent, scroll depth), event and payment in order, what they did on its pages (clicks, rage and dead clicks, forms, script errors, sections seen, experiments shown), its UTM tags and referrer, and the same visitor’s other visits.

- `id` (text · required). A visit id.

Also takes the common `project`.

### `get_funnels`

**Funnels.** Funnels set up in odo: for each step, how many visitors reached it, what share of the first step that is, and how many dropped off since the step before.

- `funnel` (text). A funnel name or id; leave it out for every funnel.

Also takes the common `project`, `site`, `range` and `filters`.

### `get_event_details`

**Event details.** One custom event (e.g. Signup) over a range: how often it was sent, by how many visitors, and every property it carried with its most common values.

- `event` (text · required). The event name, as get_traffic lists it under events.

Also takes the common `project`, `site`, `range` and `filters`.

### `get_ad_earnings_by_country`

**Ad earnings by country.** What ad networks (Adsterra) earned per country over the range, with impressions, clicks and CPM, next to the websites’ visitors from that country and the earnings per 1,000 visitors.

- `limit` (whole number, 1–100 · default `20`).

Also takes the common `project`, `site` and `range`.

## Pages, paths and conversion

### `analyze_pages`

**Page performance.** Every page with views, visitors, entries, bounce rate (for visits that started there), exits and exit rate, engaged time, scroll depth, and how many of its viewers converted afterwards, with a 95% range and lift against the site average (and the revenue they brought). Sort by any of them: find pages that leak visitors, pages nobody reads, and pages that sell. What counts as converting: by default a payment traced to the visitor (purchase); pass goal, event or page to use that instead.

- `path` (text). Only pages matching this path (\* wildcards: "/blog/\*").
- `sort` (`views`, `visitors`, `entries`, `exits`, `exit_rate`, `bounce_rate`, `engagement`, `scroll`, `conversion_rate`, `lift` or `revenue` · default `views`). Highest first (exit_rate and bounce_rate: worst first).
- `min_views` (whole number, 1–100000 · default `10`). Leave out pages with fewer views (noise).
- `limit` (whole number, 1–100 · default `25`).

Also takes the common `project`, `site`, `range`, `filters`, `goal`, `event` and `page`.

### `analyze_page`

**One page up close.** One page (or a pattern like "/blog/\*") in depth: the page before it and after it in each visit (or entering/leaving the site), the channels and sources of visits that land on it and how often they bounce, the events sent on it (clicks, signups…), how far it’s scrolled and how long it’s read, and the same by device. What counts as converting: by default a payment traced to the visitor (purchase); pass goal, event or page to use that instead.

- `path` (text · required). The page: a path such as "/pricing", or a pattern ("/blog/\*").

Also takes the common `project`, `site`, `range`, `filters`, `goal`, `event` and `page`.

### `analyze_paths`

**Paths through the site.** The routes visits take: each visit’s first pages in order, the most common routes, and how often each converted. Narrow to visits that start on a page, pass through one, or converted. What counts as converting: by default a payment traced to the visitor (purchase); pass goal, event or page to use that instead.

- `steps` (whole number, 2–8 · default `4`). Pages of each visit to follow (longer visits end in “…”).
- `start_page` (text). Only visits that started on this page (\* wildcards).
- `through_page` (text). Only visits that saw this page somewhere (\* wildcards).
- `converted_only` (`true` or `false` · default `false`). Only visits that converted.
- `limit` (whole number, 1–50 · default `20`).

Also takes the common `project`, `site`, `range`, `filters`, `goal`, `event` and `page`.

### `analyze_conversions`

**What drives conversion.** What converters have in common: conversion rate (with a 95% range and lift) by how visitors arrived (channel, source, campaign, landing page, device, country, new or returning…), the pages and events converters see far more (or less) than others, how converters behave differently, and how many visits and how long it takes from first visit to converting. What counts as converting: by default a payment traced to the visitor (purchase); pass goal, event or page to use that instead.

- `dimensions` (any of `channel`, `source`, `referrer`, `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content`, `entry_page`, `exit_page`, `country`, `region`, `city`, `device`, `browser`, `os`, `language`, `hostname`, `visitor_type`, `weekday`, `hour` and `date` (1–10) · default `["channel","source","utm_campaign","entry_page","device","country","visitor_type"]`). How visitors arrived (their first visit in the range) to compare conversion by. Each: channel, source, referrer, utm_source, utm_medium, utm_campaign, utm_term, utm_content, entry_page, exit_page, country, region, city, device, browser, os, language, hostname, visitor_type (new/returning), weekday, hour, date
- `limit` (whole number, 1–30 · default `8`). Values per dimension, most visitors first.
- `min_visitors` (whole number, 1–100000 · default `20`). Pages and events seen by fewer visitors are left out of the lift lists.

Also takes the common `project`, `site`, `range`, `filters`, `goal`, `event` and `page`.

### `analyze_funnel`

**Funnel (any steps).** A funnel of any steps you name (pages, events or goals, in order), without setting it up first: visitors at each step, the share kept from the step before, the median time between steps, where people who stopped went next (or that they left), and optionally each step by device, channel or another dimension.

- `steps` (list of text (2–10) · required). The steps in order, e.g. \["/", "/pricing", "/signup", "Signup"\]. Each: A page path (starts with "/", \* wildcards: "/product/\*"), an event name, or "goal:\<name>".
- `within` (`visitor` or `visit` · default `visitor`). visitor: steps may span their visits in the range; visit: all steps in one visit.
- `breakdown` (`channel`, `source`, `referrer`, `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content`, `entry_page`, `exit_page`, `country`, `region`, `city`, `device`, `browser`, `os`, `language`, `hostname`, `visitor_type`, `weekday`, `hour` or `date`). Also split each step by this dimension of the visit the funnel started in.

Also takes the common `project`, `site`, `range` and `filters`.

### `analyze_engagement`

**Engagement.** How deep visits go: pages and engaged time per visit, scroll depth, how often visitors return in the range, new against returning visitors (bounce, depth, conversion), and visits and conversion by weekday and hour. What counts as converting: by default a payment traced to the visitor (purchase); pass goal, event or page to use that instead.

Takes the common `project`, `site`, `range`, `filters`, `goal`, `event` and `page`.

### `analyze_retention`

**Retention.** Weekly cohorts of new visitors and the share who came back in each week after their first visit.

- `weeks` (whole number, 2–12 · default `8`). Weekly cohorts to show, the latest last.

Also takes the common `project`, `site` and `filters`.

### `get_customer_journeys`

**Customer journeys.** The latest paying customers, each with every visit up to the payment: when, from which channel, source and campaign, the landing page, each page in order (with seconds spent) and the events they sent, plus what they paid, their lifetime revenue and how long they took to buy.

- `credit` (`first` or `last` · default `last`). Filters apply to the visit credited: last or first.
- `limit` (whole number, 1–15 · default `5`).

Also takes the common `project`, `site`, `range` and `filters`.

### `breakdown`

**Breakdown (pivot).** Visits grouped by one or two dimensions (e.g. landing page × device, campaign × country, source × visitor type, weekday × hour) with visitors, bounce rate, pages per visit, engaged time, conversions in the visit with a 95% range, and revenue. Sort by any metric. What counts as converting: by default a payment traced to the visitor (purchase); pass goal, event or page to use that instead.

- `dimensions` (any of `channel`, `source`, `referrer`, `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content`, `entry_page`, `exit_page`, `country`, `region`, `city`, `device`, `browser`, `os`, `language`, `hostname`, `visitor_type`, `weekday`, `hour` and `date` (1–2) · required). One or two dimensions to group visits by. Each: channel, source, referrer, utm_source, utm_medium, utm_campaign, utm_term, utm_content, entry_page, exit_page, country, region, city, device, browser, os, language, hostname, visitor_type (new/returning), weekday, hour, date
- `sort` (`visits`, `visitors`, `conversion_rate`, `conversions`, `revenue`, `revenue_per_visit`, `bounce_rate`, `engagement` or `pages_per_visit` · default `visits`).
- `min_visits` (whole number, 1–100000 · default `10`). Leave out groups with fewer visits.
- `limit` (whole number, 1–100 · default `25`).

Also takes the common `project`, `site`, `range`, `filters`, `goal`, `event` and `page`.

### `compare_segments`

**Compare segments.** Two to four segments side by side (each defined by filters: mobile vs desktop, campaign A vs B, a landing page vs another): visitors, bounce, depth, engaged time, conversion rate with a 95% range, revenue per visitor, and whether each differs significantly from the first. What counts as converting: by default a payment traced to the visitor (purchase); pass goal, event or page to use that instead.

- `segments` (list of object with `name`, `site` and `filters` (2–4) · required). 2–4 segments, each a name and filters (e.g. device Mobile vs Desktop, or two campaigns). The first is the baseline.

Also takes the common `project`, `range`, `goal`, `event` and `page`.

## Friction, speed and experiments

### `find_friction`

**What frustrates visitors.** What’s broken or frustrating on the site, worst first: script errors, rage clicks (the same spot clicked again and again), dead clicks (clicks that do nothing), fields forms refuse, forms started and left unsent, and slow pages. Each with its page, how many visitors it hit and what share of the page’s viewers that is, how they converted next to the page’s other viewers, and example visits to open with get_visit. Start here when asked what to fix or why visitors leave. What counts as converting: by default a payment traced to the visitor (purchase); pass goal, event or page to use that instead.

- `limit` (whole number, 1–50 · default `15`). Issues to list, worst first.

Also takes the common `project`, `site`, `range`, `filters`, `goal`, `event`, `page` and `path`.

### `analyze_clicks`

**Clicks and attention.** What people click on a page (or a pattern, or the whole site): each button, link or control with clicks, clickers and their share of the page’s viewers, rage and dead clicks, and whether clickers converted more than viewers who didn’t click (95% range, p-value); plus the parts of the page people actually saw and what they copy. Use it to check that a call to action is seen, clicked and works. What counts as converting: by default a payment traced to the visitor (purchase); pass goal, event or page to use that instead.

- `limit` (whole number, 1–100 · default `25`). Elements to list, most clickers first.

Also takes the common `project`, `site`, `range`, `filters`, `goal`, `event`, `page` and `path`.

### `analyze_forms`

**Forms, field by field.** Forms (signup, checkout, contact…): each one’s page viewers, how many started it, sent it and left it unsent, the completion rate with a 95% range, median time to send and to give up, the fields people stopped at and the fields the browser refused, the same by device, and whether starters converted. What counts as converting: by default a payment traced to the visitor (purchase); pass goal, event or page to use that instead.

- `limit` (whole number, 1–30 · default `10`). Forms to list, most starters first.

Also takes the common `project`, `site`, `range`, `filters`, `goal`, `event`, `page` and `path`.

### `analyze_errors`

**Script errors.** Script errors visitors ran into: each message and source (file:line:column) with occurrences, visitors, the pages and browsers it happens on, first and last seen, and example visits; plus how visitors who hit an error converted against those who didn’t on the same pages. What counts as converting: by default a payment traced to the visitor (purchase); pass goal, event or page to use that instead.

- `limit` (whole number, 1–50 · default `15`). Errors to list, most visitors first.

Also takes the common `project`, `site`, `range`, `filters`, `goal`, `event`, `page` and `path`.

### `analyze_performance`

**Page speed (Core Web Vitals).** Page speed as visitors got it (Core Web Vitals: LCP loading, INP responsiveness, CLS layout shift, TTFB server response) by page, device, browser, country or landing page: the 75th percentile Google judges by and the shares of good, needs-improvement and poor readings; plus bounce and conversion of visits by how fast their landing page loaded, to tell whether slowness costs. What counts as converting: by default a payment traced to the visitor (purchase); pass goal, event or page to use that instead.

- `by` (`page`, `device`, `browser`, `country` or `entry` · default `page`). Group by page, device, browser, country, or entry (each landing page’s own speed, as visits’ first page).
- `limit` (whole number, 1–50 · default `15`). Groups to list, most pageviews measured first.

Also takes the common `project`, `site`, `range`, `filters`, `goal`, `event`, `page` and `path`.

### `analyze_experiment`

**A/B experiments.** A/B experiments the site runs (odo.experiment or data-odo-experiment in its code). Without a name: every experiment seen, with its variants and visitors. With one: each variant’s visitors and conversion (95% range), lift over the control with a p-value, revenue per visitor, a sample ratio check, visitors shown more than one variant, days running, its plan (the visitors each variant needs, and how far along it is), and a verdict (winner, loser, leading, no difference, no difference yet, too early, broken) that holds the call until the evidence is past the line for how far along it is: act on that, not on a p-value. Read each experiment against the goal, event or page it was meant to move. What counts as converting: by default a payment traced to the visitor (purchase); pass goal, event or page to use that instead.

- `range` (`today`, `7d`, `30d`, `90d` or `12m` · default `90d`). today, or the last 7d, 30d, 90d or 12m (ending now). Cover the whole experiment.
- `experiment` (text). The experiment’s name exactly as the site names it (spaces count). Leave it out to list every experiment seen.
- `planned_visitors` (whole number, 10–100000000). The visitors each variant needs before the experiment is read at full significance, when it was planned for a lift other than 20% (visitorsNeededPerVariant gives them for 10% and 20%). Leave it out to plan for a 20% lift from the control’s rate.

Also takes the common `project`, `site`, `filters`, `goal`, `event` and `page`.

## What to do next

### `get_next_moves`

**Next moves.** What to do next, as odo’s dashboard shows it: up to five findings from the last 30 days (against the 30 before), biggest first, and the ones the team marked done lately (a move marked done is left off for 14 days; if odo still finds it after that, it’s back, flagged as still showing). Channels, sources or campaigns whose visitors are worth well over the average one; landing pages whose visitors rarely buy; a funnel’s biggest drop; an earnings source or channel that fell; experiments ready to call or broken; script errors, rage clicks and forms on pages buyers go through; sales not traced to a visit; a change noted on the site (a site update) that moved conversion beyond chance; a busy page where most visitors stop scrolling before its pricing, form or call to action (open it with page_attention and scroll_depth). Each has a headline, the numbers behind it, a rough monthly sum at stake it’s ranked by, and where to look in odo. A good place to start when asked what to do or focus on; dig into one with the other tools.

Takes the common `project`.

## Site updates

### `list_site_updates`

**Site updates.** Changes noted on the website (by people in odo, deploy scripts, or assistants like you): the reference points on odo’s charts, newest first. Each comes with what visitors, conversion and revenue did in the whole days after it went live against as many days just before (up to a week each side), whether a change in conversion is beyond chance, and a plain summary. Use it to see what recent changes did, and before noting one, so the same change isn’t noted twice.

- `range` (`today`, `7d`, `30d`, `90d` or `12m` · default `90d`). Updates that went live in today, 7d, 30d, 90d (default) or 12m.
- `site` (text). The website it’s about: its id or domain (see list_projects). Leave it out when the change is about the whole project, or it has one website.

Also takes the common `project`.

### `record_site_update`

**Note a site update.** Tell odo what you just changed on the website, once the change is live (deployed, published or switched on): a new or redesigned page, new copy, a pricing change, a checkout or signup fix, a new feature visitors see. odo marks it on its Overview, Traffic and Revenue charts as a reference point and works out what visitors, conversion and revenue did after it, against the days before. Call it after you ship such a change, not for work visitors never see (refactors, tests, CI, docs). One update per change a visitor would notice; a deploy with several small fixes is one update. Title: a few plain words as a person would read them on a chart, at most 120 characters ("New pricing page", "Checkout: removed the coupon field"). Details: what changed and why, plain text, at most 1000 characters. Leave `at` out when it just went live.

> This one writes: it adds a site update. Only connections allowed to note site changes have it (Note site changes, left on when you approved the app, or a key with Updates).

- `title` (text · required). What changed, in a few plain words.
- `details` (text). More on what changed and why, as plain text (no Markdown).
- `path` (text). The page it’s about, as a path (/pricing) or full address, when it’s about one page.
- `kind` (`deploy`, `design`, `copy`, `pricing` or `other`). deploy, design, copy, pricing or other.
- `at` (text). When it went live, ISO 8601 with its zone (2026-10-12T14:05:00Z). Leave it out for now.
- `site` (text). The website it’s about: its id or domain (see list_projects). Leave it out when the change is about the whole project, or it has one website.

Also takes the common `project`.

## Posts

### `list_posts`

**Posts.** Which post brought the visitors and the sales (Links for posts). Three kinds: links made for posts (tagged, exact: visitors, sales and revenue each brought in the range); posts the owner added by their link (what each did in its first 48 hours against its platform’s usual for those hours, the page it pushed and whether that’s the owner’s page, sales, and Claude’s verdict where there is one); and waves of visitors odo found by itself, each with how its visitors came (the platform’s app, a bio link, a referrer), where they landed, the post their referrers named when they did, and the added post it probably was. TikTok’s and Instagram’s apps send no referrer: a wave from them is where its visitors came from, not a known post, until the owner says which it was. Use it for “which post made the most money”.

- `range` (`today`, `7d`, `30d`, `90d` or `12m` · default `30d`). today, 7d, 30d (default), 90d or 12m.
- `site` (text). One website: its id or domain (see list_projects).

Also takes the common `project`.

## Heatmaps, scrolling and attention

### `page_heatmap`

**Page heatmap: what’s clicked.** One page’s click heatmap: everything clicked on it (buttons and links by their label, anything else by where it is: a selector to find it in the site’s code), with clicks, clickers and share of the page’s clicks, and where rage clicks (the same spot again and again) and dead clicks (nothing happened) land; on phones, tablets, desktops or all screens. Use it to check a call to action gets the clicks, to find things people expect to be clickable (many clicks on an image or a price), and what frustrates them; pair it with scroll_depth and page_attention, and compare phone with desktop.

- `path` (text · required). The page, as its path: "/", "/pricing". One page, no wildcards (a heatmap is of one layout).
- `screen` (`all`, `phone`, `tablet` or `desktop` · default `all`). Whose visits: phone (under 640 px wide), tablet (under 1024), desktop, or all. Layouts differ by width, so compare phone with desktop before suggesting a change.
- `limit` (whole number, 1–40 · default `15`). Elements to list, most clicked first.

Also takes the common `project`, `site`, `range` and `filters`.

### `scroll_depth`

**Scroll depth: how far down they get.** How far down one page its visitors scroll: the share who reach every 5% of it, the fold (how far half of them get) and the page’s height in screens, on phones, tablets, desktops or all screens. Use it to see whether what matters on a page is where people still are; if most phone visitors stop before the pricing block (page_attention says where each part sits), suggest moving it up or making the page shorter above it.

- `path` (text · required). The page, as its path: "/", "/pricing". One page, no wildcards (a heatmap is of one layout).
- `screen` (`all`, `phone`, `tablet` or `desktop` · default `all`). Whose visits: phone (under 640 px wide), tablet (under 1024), desktop, or all. Layouts differ by width, so compare phone with desktop before suggesting a change.

Also takes the common `project`, `site`, `range` and `filters`.

### `page_attention`

**Page attention: which parts they see.** Which parts of one page its visitors actually see, in the page’s order: each part (marked data-odo-section, else its header, main’s parts and footer) with the share of visitors who saw any of it and the median time it was at least half on screen, plus the fold; on phones, tablets, desktops or all screens. Use it to find key parts (pricing, a form, the call to action) most visitors never reach, and parts they skim past; suggest moving what matters above the fold.

- `path` (text · required). The page, as its path: "/", "/pricing". One page, no wildcards (a heatmap is of one layout).
- `screen` (`all`, `phone`, `tablet` or `desktop` · default `all`). Whose visits: phone (under 640 px wide), tablet (under 1024), desktop, or all. Layouts differ by width, so compare phone with desktop before suggesting a change.

Also takes the common `project`, `site`, `range` and `filters`.

## Experiments odo runs

### `list_experiments`

**Experiments.** Every experiment odo knows on the site: those registered with odo (draft, running, paused, decided, shipped, archived), each with its variants, what it's judged by, how far along it is and the verdict (winner, loser, leading, no difference, too early, broken), the decision and the analyst's read-out once called; and experiments the site's code shows that nobody registered ("found in your code"), which can be registered with create_experiment (mode code, the same name and keys). odo reads running experiments every 15 minutes and calls them itself. Two ways to run one. content: odo's script changes the page itself for each visitor's variant (no code change, works on any page with odo's script); odo can show the winner to everyone once it's called (autoPromote). code: the site's code shows the variants (odo.experiment or data-odo-experiment markup) under the same name and variant keys, so its exposures join up: put it in the code first, deploy, then register it here with start: true (or register it as a draft first: the answer has the exact snippet).

- `site` (text). The website: its id or domain (see list_projects). Leave it out when the project has one.
- `include_archived` (`true` or `false` · default `false`). Archived ones too.

Also takes the common `project`.

### `suggest_experiment_variants`

**Variants to try.** Variants to test on a page (or one element, by CSS selector) against a goal: the facts odo has (the page's last 30 days: views, entries, bounce and exit rates, time, how its viewers convert against the site; what people click on it; past experiments on the site, their outcomes and read-outs), and odo's analyst's suggestions when the plan has them (each with the exact changes, checked, and an experiment ready to pass to create_experiment). Without them, propose your own from the facts in the same shape. odo doesn't read the site's pages itself: pass current (what the element says now) for better suggestions. Judged by sales (a payment traced to the visitor) unless you pass goal, event or page: pick what the change is meant to move.

- `site` (text). The website: its id or domain (see list_projects). Leave it out when the project has one.
- `path` (text · default `*`). The page: /pricing, /blog/\*, or \* for every page.
- `selector` (text). The element, as a CSS selector.
- `current` (text). What the element says or looks like now.
- `hypothesis` (text).
- `mode` (`code` or `content` · default `content`).
- `count` (whole number, 1–4 · default `2`). Variants besides the original.
- `goal` (text). Judge it by a goal set up in odo (its name or id).
- `event` (text). Judge it by a custom event (e.g. "Signup").
- `page` (text). Judge it by reaching a page ("/thanks", "/order/\*").

Also takes the common `project`.

### `create_experiment`

**Make an experiment.** Makes an A/B experiment odo runs, reads and calls: 2–5 variants, the original first, on a page pattern, judged by a goal. Two ways to run one. content: odo's script changes the page itself for each visitor's variant (no code change, works on any page with odo's script); odo can show the winner to everyone once it's called (autoPromote). code: the site's code shows the variants (odo.experiment or data-odo-experiment markup) under the same name and variant keys, so its exposures join up: put it in the code first, deploy, then register it here with start: true (or register it as a draft first: the answer has the exact snippet). With start: true it goes live at once (content: visitors on matching pages start seeing their variant within a minute or two). odo calls it itself (winner, loser or no difference, or after maxDays, default 28) and, with autoPromote (default on), shows a content winner to everyone and tells the owner; it never acts on a broken one. Content-mode changes (odo's script makes them; each is checked, and checked again in the browser): text (an element's new text, never markup), attr (href or src: https:// or a path on the site; alt, title, aria-label, placeholder), hide, show, style (only color, background-color, font-size, font-weight, letter-spacing, padding, margin, border-radius, display, order, text-transform, with plain values: no url(), var(), calc() or !important). Selectors are plain CSS (tags, .classes, #ids, \[attr="x"\], > + ~, :first-child, :nth-child(), :not()), never the page's html, head or body, or anything that runs code. The first variant is the original and changes nothing. Judged by sales (a payment traced to the visitor) unless you pass goal, event or page: pick what the change is meant to move. At most 20 running per website. Confirm with the person before starting one: it changes what their visitors see.

> This one writes: it changes what visitors see on your site. Only connections allowed to run experiments have it (Run experiments, turned on when you approved the app, or a key with Experiments).

- `site` (text). The website: its id or domain (see list_projects). Leave it out when the project has one.
- `name` (text · required). Letters, digits, spaces and _-.: (code mode: exactly what the code passes).
- `mode` (`code` or `content` · default `content`).
- `path` (text · default `*`). Pages it runs on: /pricing, /blog/\*, or \*.
- `hypothesis` (text). What you expect, and why.
- `variants` (list of object with `key`, `label`, `description` and `changes` (2–5) · required).
- `weights` (list of number, 0–1000 (up to 5)). Traffic shares; equal by default.
- `autoPromote` (`true` or `false` · default `true`).
- `maxDays` (whole number, 7–90).
- `start` (`true` or `false` · default `false`). Start it now (else it waits as a draft).
- `goal` (text). Judge it by a goal set up in odo (its name or id).
- `event` (text). Judge it by a custom event (e.g. "Signup").
- `page` (text). Judge it by reaching a page ("/thanks", "/order/\*").

Also takes the common `project`.

### `update_experiment`

**Change or run an experiment.** Changes an experiment (by id or exact name): while it's a draft, any of its fields; once it has run, only hypothesis, autoPromote and maxDays. And actions: start (a draft), pause (everyone sees the original; content experiments stop changing the page), resume, stop (ends it: decided, the original for everyone), ship (variant: content, odo shows it to everyone from now on; code, it's in the site's code now) and archive (out of the list; its name stays taken). Ship only what the verdict called a winner unless the person asks otherwise. Content-mode changes (odo's script makes them; each is checked, and checked again in the browser): text (an element's new text, never markup), attr (href or src: https:// or a path on the site; alt, title, aria-label, placeholder), hide, show, style (only color, background-color, font-size, font-weight, letter-spacing, padding, margin, border-radius, display, order, text-transform, with plain values: no url(), var(), calc() or !important). Selectors are plain CSS (tags, .classes, #ids, \[attr="x"\], > + ~, :first-child, :nth-child(), :not()), never the page's html, head or body, or anything that runs code. The first variant is the original and changes nothing.

> This one writes: it changes what visitors see on your site. Only connections allowed to run experiments have it (Run experiments, turned on when you approved the app, or a key with Experiments).

- `site` (text). The website: its id or domain (see list_projects). Leave it out when the project has one.
- `experiment` (text · required). Its id or exact name.
- `action` (`start`, `pause`, `resume`, `stop`, `ship` or `archive`).
- `variant` (text). For ship: the variant’s key.
- `name` (text).
- `mode` (`code` or `content`).
- `path` (text).
- `hypothesis` (text).
- `variants` (list of object with `key`, `label`, `description` and `changes` (2–5)).
- `weights` (list of number, 0–1000 (up to 5)).
- `autoPromote` (`true` or `false`).
- `maxDays` (whole number, 7–90).
- `goal` (text). Judge it by a goal set up in odo (its name or id).
- `event` (text). Judge it by a custom event (e.g. "Signup").
- `page` (text). Judge it by reaching a page ("/thanks", "/order/\*").

Also takes the common `project`.
