Docs
Echo, in one page
Echo is an autonomous conversion-optimization platform. A tiny script applies approved variants and records anonymous analytics; the Echo Agent finds problems and drafts tests; Studio lets you build and refine variants on your live page; and the results engine tells you what to ship.
The loop: scan → build → approve → run a planned window → deploy the winner or conclude → learn.
Installation
Add one line as high as possible in the <head> of every page. Find your site key under Connectors.
<script src="https://getecho-eosin.vercel.app/echo.js" data-site="YOUR_SITE_KEY"></script>
The script is synchronous on purpose: it hides the page for at most ~900 ms on a first visit while variants load, then caches the experiment config so later page views apply changes before first paint, with no flicker. Use Verify installation on the Connectors page to confirm events arrive.
Shopify: Online Store → Themes → Edit code → layout/theme.liquid, paste right after <head>. Next.js: a plain <script> in the root layout's <head>. GTM: works, but loads later (some flicker).
Tracking purchases (Echo Pixel)
Report revenue on your order confirmation page so experiments are measured on money, not clicks:
<script>
window.echo = window.echo || [];
echo.push(["purchase", { value: 84.50 }]); // works before echo.js loads
</script>Add-to-cart is detected automatically for carts that call /cart/add (Shopify, WooCommerce, most themes). You can also switch a goal to Page visit mode in Settings → Conversions, e.g. any path starting with /checkout/thank-you.
JavaScript API
echo.track("newsletter_signup") // custom goal (event mode)
echo.track("purchase", { value: 120 }) // purchase with revenue
echo.purchase({ value: 120 }) // shorthand
echo.variant("exp_123") // → variant id this visitor sees, or null
echo.consent(true) // release events held for consent
echo.visitor // anonymous visitor id
<button data-echo-goal="size_guide_open">Size guide</button> // click goal, no JSDebug any page with ?echo_debug=1. Preview a draft variant on your live site with ?echo_preview=VARIANT_ID (Studio's Preview button generates the link and a QR code).
Targeting rules
A targeting group is a reusable set of URL rules. Each rule reads: path does / does not [operator] [value]. Combine with AND / OR and nest groups.
exact,simple: the path equals the value (query strings are always ignored)starts_with,ends_with,containswildcard:/products/*,/collections/*/saleregex: full regular expressions, case-insensitive
The reach panel estimates visits in the last 7 days and the planned window before you commit. Wider groups resolve faster.
How experiments run
Every A/B test is a fixed, even split read at the end of a planned window. The window is set from your real traffic before launch:
- 2 weeks if the pages can send ~5,000 visitors to each variant, 4 weeks if they need longer, and a 6-week ceiling.
- Figures stay hidden until every variant has 350 visitors and 50 conversions.
- No leader is named before the window completes. Peeking inflates false positives.
- Chance to beat (Bayesian, Beta-Binomial), against your winner bar (95% by default; 80, 85 or 90% in Settings): at or above the bar on conversion or on revenue per visitor is a winner, a little below is promising, and the original wins when the variant’s chance drops under 100% minus the bar.
- Revenue per visitor counts once the original and the variant both have 50 orders. A variant that converts more but earns less per visitor is never called a winner.
- A clear loser (under 1% chance to beat) can be stopped early, but only after 7 days, so weekday swings can’t trigger it.
- Lift is reported with a 95% interval. Plan against the low end, not the point estimate.
- Device and channel breakdowns appear once each segment has 500 visitors per variant. Deploy only where it won.
Assignment is deterministic (FNV-1a hash of experiment + visitor, as in GrowthBook) and sticky in localStorage, so visitors keep the same variant across pages and visits. Try the calculators to plan a test.
Studio & change types
Variants are lists of DOM operations applied on top of your original page. Your code is never modified, and pausing reverts instantly.
text replace an element's text
html replace inner HTML
style inline CSS on the element { "background-color": "#1f9d47" }
attr set an attribute href, src, aria-label…
hide hide the element
insert insert HTML beforebegin | afterbegin | beforeend | afterend
css add a global stylesheet @media (max-width: 767px) { … }
move move the element next to another
redirect split-URL testIn Studio, click to select an element, double-click text to edit it in place, or describe the change to the Experiment agent. ⌘Z / ⇧⌘Z undo and redo; changes autosave.
Personalization
Personalizations serve a tailored variant to an audience, with a holdout (default 10%) that keeps seeing the original so you can still measure lift. Audience fields: utm_source, utm_medium, utm_campaign, referrer, device, visitor (new / returning) and query.
Privacy & consent
The script stores only random identifiers and experiment assignments in first-party storage: echo_<site>_vid, _sid, _asg, _exp, _cfg. It sets no cookies and collects no personal data. Enable Wait for analytics consent to hold events until OneTrust (C0002), Google Consent Mode analytics_storage or echo.consent(true) grants it. Variants still render, so the experience stays consistent.
If you use a Content Security Policy, allow this host for script-src and connect-src.
MCP server
Ask your store questions from Claude, ChatGPT or any MCP client, and turn the answer into a draft test. Create an API key in Settings → API & MCP, then:
claude mcp add --transport http echo https://getecho-eosin.vercel.app/api/mcp \ --header "Authorization: Bearer YOUR_KEY"
Tools: list_sites, list_experiments, get_experiment_results, get_page_scorecard, get_site_analytics, list_opportunities, create_experiment (always a draft, which a human must start).
Self-hosting on the free stack
Echo is a single Next.js app. Every dependency has a free tier:
- Hosting: Vercel Hobby (or any Node host)
- Database: Neon Postgres (free tier)
- Auth: Better Auth (built in, email + password; optional GitHub/Google)
- AI: optional. The rules engine works with no key; add an Anthropic key to use Claude.
- Email: optional Resend free tier for password resets
npm install cp .env.example .env.local # set BETTER_AUTH_SECRET and DATABASE_URL (Neon) npm run dev # runs migrations against your Neon database, then starts