Skip to content

The routingcat command

Run the command as npx routingcat <command> in your app’s folder. npx routingcat --help lists the commands, npx routingcat <command> --help shows one, and npx routingcat --version prints the version.

Conventions

Options every command takes

Option What it does
--json Prints one JSON object instead of text, described in JSON output. A line a person needs, such as a sign-in link, goes to standard error.
--site <key> The site to act on, by its key. Without it, the site routingcat.config.ts or routingcat.config.json names, found from the current folder upward; else, on a machine paired with a Shopify store from its admin, that store’s site; else your only site.
-h, --help Prints the command’s usage.

Options every write takes

The writes change something: keys, link, unlink, members, domains, connect, disconnect, pause, resume, promote, retire, revert, set, gap and push. Each also takes:

Option What it does
--dry-run Shows what the write would do, with the operation it would create, and changes nothing.
--idempotency-key <key> Makes a retry safe: a key used again returns the first result instead of acting twice. One is generated when absent: 1 to 128 letters, digits and _ . : -.
--expect <registry version> Acts only if the site has not changed since you read it, at the version status --json gives as registry_version; otherwise it fails with a version conflict.

Exit codes

Code Meaning
0 Done.
1 Rejected, denied or failed, with a message id.
2 The command or its arguments are wrong.
3 Waiting, on a person, such as approving a sign-in link, or on time, such as doctor’s checks of a deploy that has just gone out. Run the same command again once the person has acted, or a little later.
4 RoutingCat cannot be reached. Allow network access for the command, or ask the person to run it.

Addresses and ids

An address names what your code declares, by its keys: home is a page, home/hero a slot, home/hero:oneclick a variant, and home/hero:oneclick@v2 one of its versions. The commands take addresses wherever they act on what you declared.

Everything else goes by the id the output prints. show takes an address or an id. The ids you meet start with:

Prefix Names
sf_ a page
sl_ a slot
vr_ a variant
rv_ a version
ch_ a change your build or push registered
pb_ a publication: what a page serves, for revert --to
dp_ a deployment
op_ an operation: an act, or a build or push registering
cn_ a connection to a payment provider
ev_ a scorecard
run_ one of a scorecard’s results

Values

Times are UTC.

Value Written as
A share 0.1 or 10%, from 0 to 1
A duration 7d, 24h, 30m or 2w, or seconds, as 604800
A time UTC, as 2026-10-20T14:00:00Z, or a day, as 2026-10-20, which is its start; or now
A first day A day, as 2026-10-10, or a span back from today, as 7d: the last seven days, today included

Setup

init

Terminal window
npx routingcat init [--dry-run] [--agents-md | --no-agents-md] [--host <host>] [--origin <url>] [--helpers]

Sets RoutingCat up in the project of the current folder.

It checks the project and where it deploys, signs you in, and creates your site from its Vercel, Cloudflare Workers or Pages project. Then it adds the routingcat package and routingcat/nuxt to the modules of nuxt.config, writes the host’s entry where it needs one, middleware.ts on Vercel or worker.ts on Workers, writes routingcat.config.ts, and installs the skill for your coding agent. Set up RoutingCat gives each edit.

With your agreement, it adds a two-line note to AGENTS.md that points coding agents to the skill. At a terminal it asks whether to add the note, then prints the plan and asks before applying it; run by an agent, it asks nothing, and says to ask you about the note. Nothing reaches visitors until you deploy. Run again, it does only what is missing, and keeps the note up to date.

Option What it does
--dry-run Prints the plan and changes nothing.
--agents-md Adds the note to AGENTS.md without asking: your agent runs it once you agree.
--no-agents-md Leaves AGENTS.md and CLAUDE.md as they are, without asking.
--host <host> Where the site deploys, where the folder does not say: vercel, cloudflare-workers, cloudflare-pages, or none for a host that runs nothing of RoutingCat’s, which sets up the script integration. On a site routingcat.config.json sets up already, another host moves it there, its pages, variants and results kept.
--origin <url> The production address, as https://www.example.com, where neither the host nor the site’s configuration gives it: a script site’s, a site’s on Cloudflare, or a Hydrogen storefront’s on Oxygen. routingcat.config.json lists its host, and routingcat.config.ts’s config() names it as origin.
--helpers On a script site its own server renders, Laravel, Rails, Django, WordPress or PHP: writes the server helpers in its language, which set the visitor cookie and the fetch site on each page it renders, registers them where one file shows where, and declares them in routingcat.config.json.
$ npx routingcat init
routingcat 1.0.0 · <project>
Checks
✓ Nuxt 4.6.0 · pnpm
✓ Vercel project lumen · Vercel CLI signed in as emma
✓ no middleware.ts yet: init writes one
✓ signed in to RoutingCat
Detected for outcomes: Clerk (sign-in)
Plan
1 create the site lumen, bound to Vercel project lumen
2 pnpm add routingcat@1.0.0
3 nuxt.config.ts add routingcat/nuxt to modules
4 middleware.ts new: middleware() from routingcat/vercel on Node.js, and RoutingCat's matcher
5 .gitignore add .routingcat/, where the build writes RoutingCat's credential
6 routingcat.config.ts new: the site and its public key
7 the skill .agents/skills/routingcat/, copied to .claude/skills/routingcat/
Nothing reaches visitors until you deploy.
✓ site lumen created (op_01m3yesth0fjfsctr17tbq1z82), bound to Vercel project lumen
✓ routingcat 1.0.0 added · 3 files edited, 2 files and 2 folders created (see git diff)
Ask the person: "Add a two-line note to AGENTS.md so coding agents always know RoutingCat is here? (recommended)" If yes, run npx routingcat init --agents-md.
Dashboard: https://app.routingcat.com/lumen
Next: read .agents/skills/routingcat/setup.md and follow it

login

Terminal window
npx routingcat login

Signs you in on this machine. It prints a link, opens it in your browser, and waits 50 seconds for you to approve it. Approved later, run it again: it picks up the same link, and ends with exit code 3 while it waits on you.

logout

Terminal window
npx routingcat logout

Revokes the sign-in on this machine and deletes it.

doctor

Terminal window
npx routingcat doctor [--wait]

Checks the install and prints one line per check, with a message id when one fails: the latest production build registered, its deployment registered, with the runtime it reports on Vercel and its Worker’s version on Workers, the middleware or Worker runs on your production page, the /_rc path reaches RoutingCat, your pages carry the head snippet, their Content Security Policy lets RoutingCat run, RoutingCat takes the records of your production address, an arrival was recorded, and the objective’s first event, which waits for one real conversion. Locally, it checks the Nuxt version and its Nitro preset, the edits init printed, the key in routingcat.config.ts and the skill’s version.

Once a page is routed, it also checks that the page is live and that its first routed visit and render beacon arrived. It says whether AGENTS.md has the note for coding agents, which never fails a check, and it changes nothing. Troubleshooting reads each check.

Option What it does
--wait After a deploy, waits up to 5 minutes, printing each check as it passes. An agent running it gives the call a longer timeout than that.
$ npx routingcat doctor
lumen · production
✓ build registered ch_01m3yfrpt0ewpateq9yrq61xkb · objective signup · outcomes waitlist 14:19:52
✓ deployment registered dp_01m3yfn1m0exhr06xh9d10mvbr · commit 2528229 · routingcat 1.0.0 14:21:10
✓ runtime Node.js 22.18.0, as dp_01m3yfn1m0exhr06xh9d10mvbr reports it
✓ middleware on / rc_vid on lumen.so, 400 days 14:40:00
✓ /_rc reaches the collector 14:40:00
✓ head snippet 1 page carries it
✓ policy lets RoutingCat run, apply and record
✓ records ingest.routingcat.com accepts them from https://lumen.so
✓ first arrival arrivals in the pulse, last 14:39:18 14:39:18
✓ signup 2 events 14:33:59 · server · identify 14:32:05 14:33:59
✓ card on file Visa •••• 4242
· AGENTS.md has no RoutingCat note, so coding agents may skip the skill unless a request matches it; if the person wants the note, run npx routingcat init --agents-md
11 of 11 passed (exit 0)

keys

Terminal window
npx routingcat keys [server|deploy] [--env production|preview] [--branch <name>] [--rotate|--revoke]

Lists the site’s keys, or shows one. keys server shows the server events key, which your backends send events with, through the HTTP events API, and mints it on first use.

keys deploy mints the deploy key, ROUTINGCAT_DEPLOY_KEY, for builds that run without Vercel’s token, and shows it only then.

The production deploy key is bound to your production branch, so a preview build never publishes with it, even with the key in its variables. The preview deploy key is bound to no branch: on Cloudflare, one preview key in the preview environment’s variables covers every preview branch. Only the site’s owner mints, rotates and revokes keys.

Option What it does
--env production|preview The key’s environment: production, by default, or preview, whose events stay out of production results.
--branch <name> The production branch, which the production deploy key needs: the key proves production only for builds of that branch, as their CI reports it. With --rotate, the new key is bound to the branch given.
--rotate Replaces the key. The one it replaces keeps working for 24 hours.
--revoke With keys deploy, stops the environment’s deploy key at once, and the one its last rotation replaced, as for a key that leaked.

A write: it also takes the options every write takes.

$ npx routingcat keys
pantry · keys
public key pk_pantry_H7tTayds public, write-only; it names the site in routingcat.config.ts
server production: exists since 2026-07-09 · preview: not minted
deploy production: not minted · preview: not minted
Show or mint one: routingcat keys server|deploy [--env preview] [--rotate]; the production deploy key takes --branch <production branch>
Terminal window
npx routingcat link github [--branch <name>]

Links a script site to its GitHub repository, the one your origin remote names, so that the repository’s GitHub Actions workflows register the site with GitHub’s own token, and no deploy key needs keeping. The link stays pending until a workflow run of that repository proves it, within a day: a run that calls push in a job with permissions: id-token: write. From then on, runs on your production branch register production, and other runs register previews. While the link is pending, the command ends with exit code 3. Only the site’s owner links a repository. A site whose host’s middleware decides needs no link: it registers in its build.

Option What it does
--branch <name> Your production branch, as main, whose runs register production. Without it, the one routingcat.config.json names as environments.production.branch.

A write: it also takes the options every write takes.

$ npx routingcat link github --branch main
link github · done · op_01m58vb0sff5f8vmx9bg22924h · registry version 3
st_01m58vasyqevdvx3zhrfa86nsa repository quire-app/site · branch main · status pending · expires_at 2026-10-20T01:10:12Z
lumen · GitHub repository quire-app/site · production branch main · pending until Oct 20, 01:10 UTC
✗ lumen is linked to GitHub repository quire-app/site once a workflow run of it proves it: run routingcat push in a workflow of quire-app/site whose job has permissions: id-token: write, before Oct 20, 01:10 UTC. (D116, exit 3)
Terminal window
npx routingcat unlink github

Removes the site’s link to its GitHub repository. The repository’s workflows then register nothing unless they hold the site’s deploy key. Only the site’s owner removes the link.

A write: it also takes the options every write takes.

$ npx routingcat unlink github
unlink github · done · op_01m58vb6mze6xtmwxg5rp0exqm · registry version 5
st_01m58vasyqevdvx3zhrfa86nsa repository quire-app/site removed · branch main removed · status pending removed · requested_at 2026-10-19T01:10:12Z removed
lumen · no GitHub repository linked: CI's push registers with the site's deploy key

members

Terminal window
npx routingcat members [add|remove <email or principal>]

Lists the site’s members. The owner adds or removes one by email; an added member’s access starts at their first sign-in with that address.

A write: it also takes the options every write takes.

$ npx routingcat members
pantry · members
theo@pantry.app owner active since 2026-07-08
ana@pantry.app member active since 2026-07-08
sam@pantry.app member pending added 2026-10-10, until their first sign-in

domains

Terminal window
npx routingcat domains [add|remove <domain>]

Lists the domains RoutingCat accepts browser events and links from: your production domain, your Vercel hosts or, on Cloudflare, your workers.dev and pages.dev hosts, and the domains added here.

The owner adds or removes one, for routingcat.link and the browser script on another domain.

A write: it also takes the options every write takes.

$ npx routingcat domains
pantry · domains
-pantry.vercel.app hosts ending with it from the Vercel team since 2026-07-08
pantry.app with its subdomains from the production origin since 2026-07-08
pantry.cooking with its subdomains added with routingcat domains since 2026-08-01

connect

Terminal window
npx routingcat connect whop [--sandbox] [--prove] [--reconcile] [--account-key <key>]

Counts a payment provider’s payments as outcomes: purchases, renewals, trials, refunds, disputes and cancellations, each joined to the visit that led to it. connect whop creates the webhook in your Whop company with your own API key, from WHOP_API_KEY or typed at the terminal, which is never written to disk, then has Whop send its test event. Only the site’s owner connects a provider.

Option What it does
--sandbox Whop’s: connects your Whop sandbox instead of the live company.
--prove Whop’s: hands RoutingCat the key once, to prove the company is yours, and RoutingCat does not keep it. A company another site holds through its webhook’s deliveries alone then moves to this site.
--reconcile Whop’s: also hands RoutingCat the key, kept encrypted, to read back payments a webhook missed. The key then needs payment:basic:read, member:basic:read and plan:basic:read too.
--account-key <key> Where your own account ids live on the provider’s objects: a metadata key, as user_id, or customer for the provider’s customer id. On a connection the site holds, it changes only that.

A write: it also takes the options every write takes.

$ npx routingcat connect whop --sandbox --site lumen
✓ whop connected biz_8Jk4mWzR2pLs (sandbox) · signature verified

connections

Terminal window
npx routingcat connections

Lists the site’s connections to its payment providers: each one’s account, state, last delivery and outcomes today, and the tracking gaps a disconnection opened.

disconnect

Terminal window
npx routingcat disconnect <whop|shopify|cn_…>

Removes a connection, named by its provider or its id: its payments stop counting from now, and the time after is recorded as a tracking gap. It deletes Whop’s webhook where RoutingCat keeps your Whop key, and otherwise says to delete it in Whop. Only the site’s owner disconnects one.

A write: it also takes the options every write takes.

Read

status

Terminal window
npx routingcat status [page] [--since <date or cursor>]

The orientation, in under 40 lines. For each routed page: the measured gain, and each variant with its label, predicted rate, difference from the default, signal and share served. Then how conversions joined visits, the month’s visitors, where conversions came from, each place where what’s live differs from your code, warnings, and what changed since you last ran it. Give a page to see that page alone.

Option What it does
--since <date or cursor> Shows the timeline instead: deploys, changes, acts and warnings since a day or a time, or since the cursor a previous --json returned, to read only what followed.
$ npx routingcat status
inkwell · production · 2026-10-11 09:20Z · counts to 09:00Z · estimates matured to 10-11 · contract 1.0
since 2026-10-04 09:20Z: 1 deploy (dp_01m4k54960e4ma9r026sfe2he2), no acts → routingcat status --since 2026-10-04
home · objective signup, 24 h · control: the defaults, 10% · live since 10-02 · publication pb_01m4k57yc0fa9vhrhd9qpf2dm2
gain +9 conversions (signup) vs defaults, no range: too few visits · measured · 341 routed / 47 control visits · maturity 0.88
hero default write-daily · 4 live
write-daily default 2.2% [0.5, 3.9] · signal 3 Early · served 28% · 96 visits
streaks favored 2.6% [0.7, 4.5] · +19% [−100, +145] vs default · signal 3 Early · served 40% · 135 visits
prompts learning 3.3% [1.1, 5.6] · +51% [−100, +207] vs default · signal 3 Early · served 31% · 104 visits
private prior 2.7% [0.4, 5.3] · +24% [−100, +177] vs default · signal 0 New · served 2% · 6 visits
variant rates and contrasts are predicted; the measured gain compares routed visits with the control
tracking signup 19 in 7 days · joined 37% (visitor 32%, account 5%) · no routed visit 53% · no key 0% · unlinked 0% · outside window 11%
visitors 333 on routed pages in October so far, people only · 5 automated left out
variants 3 live of the 10 the Hobby account's sites share, the defaults not counted
sources 7 days, accounting: search 8 · direct 4 · social 3 · email 2 · paid 1 · unknown 1 → routingcat sources
warnings none · deployments: dp_01m4k54960e4ma9r026sfe2he2 current (commit 2d79ae7), none unregistered
more routingcat show home/hero:streaks · --json for every field

show

Terminal window
npx routingcat show <address or id> [--by <dimension>]

Any object, one hop each way: a page, slot, variant or version by its address, or anything by the id the output prints. A variant shows its version, its predicted rate and difference from the default with their ranges, its signal, counted rates, share served, scorecards, and a breakdown, by device unless --by names another. A version shows its content and how it differs from the version before. A page, a slot or a variant also lists where what’s live differs from your code, a line per place.

Option What it does
--by <dimension> The breakdown: device, traffic_source, visit, time_of_day or day_type.
$ npx routingcat show home/hero:save-time
home/hero:save-time · vr_01kx68ntc0e1j9x6dma6hjgtym · live · learning · served by dp_01m4xeq560edfb3k7r2f65mexw
version @v1 (rv_01kx68ntc0e12r1dvm2cr5xczt, 3c7ce6) since 07-10, ch_01kx68ntc0f6ws65jtkmgmd04q "Try four headlines and a call to action on the home page"
headline "Dinner, decided"
subhead "Your week of meals and your shopping list, ready on Sunday."
scores signup@1 · release rl_01m4yfavm0ey5rfmqd2d8a3anf · publication pb_01m4xettc0e9karqctc3tvjkvf · counts to 00:50Z · matured to 10-15
rate 3.8% [3.0, 4.5] · predicted
vs default −14% [−32, +4] relative · −0.6 pts [−1.4, +0.2] · predicted
signal 59 · Building · 2,171 matured visits
counted 3.7% of 2,534 matured visits · 3.8% of all 2,565, incomplete · 78.8% rendered
served 11% of hero; routing currently intends 9%
scorecards
ev_01kx68ntc0fgnbx7xqtn0wa7xx vs default current, since 07-10 · as served · +7% [−20, +34] predicted · run_01m4ygw9n0ep1t35tc0jfgwwz4
by device visits served relative counted predicted
mobile 1,222 10% 0.86 3.1% 3.1% [2.1, 4.0]
desktop 1,199 13% 1.17 4.5% 4.5% [3.3, 5.6]
other 144 12% 1.11 3.5% 3.5% [0.9, 6.2]
also --by traffic_source, visit, time_of_day, day_type
other outcomes, counted trial_started 1.0%, value 0.02 per visit · purchase 0.5%, $0.13 per visit
engagement seen 77% · 2.5 s visible · 3.0% click inside the slot
related sl_01kx68ntc0enatwx14ctrzbj6n · ch_01kx68ntc0f6ws65jtkmgmd04q · pb_01m4xettc0e9karqctc3tvjkvf · ev_01kx68ntc0fgnbx7xqtn0wa7xx → routingcat show <id>

sources

Terminal window
npx routingcat sources [page] [--since <date>] [--by source|campaign|landing]

Conversions and revenue by where visits came from: by channel, or by source, campaign or landing page. It counts where conversions came from, not what caused them. Give a page for its visits alone.

Option What it does
--since <date> The first day: a day, as 2026-10-10, or a span back from today, as 7d.
--by source|campaign|landing Groups by source, campaign or landing page instead of by channel.
$ npx routingcat sources --since 7d
pantry · production · 7 days to 2026-10-15 08:00Z · accounting, not lift · contract 1.0
channel arrivals signup rate trial_started purchase revenue
search 2,883 63 2.2% 31 11 $99
direct 1,816 39 2.1% 15 6 $129
referral 594 14 2.4% 6 3 $102
social 818 12 1.5% 7 3 $102
email 356 10 2.8% 8 0 —
ai 449 9 2.0% 10 0 —
paid 467 8 1.7% 6 1 $9
other 164 3 1.8% 2 1 $9
unknown 230 7 3.0% 0 0 —
no_arrival — 7 — 5 1 $9
total 7,777 172 2.2% 90 26 $459
top sources google 66 · newsletter 10 · producthunt.com 8 · chatgpt.com 6
top campaigns launch-thread (social) 8 · weekly-digest (email) 6 · retarget-q3 (paid) 5 · brand-search (paid) 2
top landing / 97 · /pricing 15 · /changelog 9 · /blog/meal-prep-sunday 8
channels as classified by program launch-1 · also --by source, campaign, landing

download

Terminal window
npx routingcat download <report> [--filter k=v…] [--by <dims>] [--format csv|json]

Writes a report to a file in the current folder, and prints its path, its rows and how recent it is. The reports:

Report What it holds
traffic Visits, visitors, routed page loads and arrivals, by day.
outcomes Conversions and their value, by outcome and day, and where they came from.
engagement How each slot was seen and clicked, and each page’s scrolling, time and speed.
delivery What each slot rendered, and render beacons against routed page loads.
progress The measured gain of each page, over time.
scores Each variant’s predicted rate and difference from the default.
evaluations Scorecards and their results.
diagnostics The checks behind the warnings, such as how conversions joined visits.
cells The finest grain: one row per day, page, slot, variant and breakdown.
Option What it does
--filter k=v… Selects rows, never visitors: page=, slot=, objective=, since= and until=, as --filter page=home. Repeat it, or separate pairs with commas.
--by <dims> One or two breakdowns, separated by a comma: device, traffic_source, visit, time_of_day and day_type. Or one of country or channel, which give counts only.
--format csv|json csv or json.

docs

Terminal window
npx routingcat docs [<page>] [--family <family>]

Prints a page of the documentation for the installed version, from the copy for your site’s stack: the one routingcat.config.ts or routingcat.config.json names, found from the current folder upward. Without a page, it prints the copy’s map of every page; with # and a heading’s anchor, as guides/tracking#record-a-tracking-gap, that section alone. It reads the docs the package carries, so it works offline, and on a site that runs RoutingCat through npx, with no node_modules.

Option What it does
--family <family> Another copy, by its key, among those the installed version carries: nextjs, nuxt, astro, react-router, html or script.
$ npx routingcat docs 'guides/tracking#record-a-tracking-gap'
## Record a tracking gap
Run `npx routingcat gap <outcome> --from <time>`.
```sh
# a heading inside code is not one
npx routingcat gap signup --from 2026-10-10T08:00:00Z
```
### Close it
Run the same command with `--to`.

Act now

pause

Terminal window
npx routingcat pause <variant…>

Stops serving variants, named by address. A pause holds until resume, whatever your code declares, and their scorecards close. A slot’s default cannot be paused: promote another variant first.

A write: it also takes the options every write takes.

$ npx routingcat pause home/hero:plan-week
✗ home/hero:plan-week is the default of home/hero, and every slot needs its default, so it cannot be paused or retired. Promote another variant first. (A8, exit 1)

resume

Terminal window
npx routingcat resume <variant…>

Serves paused or retired variants again, each with a new scorecard against its slot’s default.

A write: it also takes the options every write takes.

promote

Terminal window
npx routingcat promote <variant…>

Makes each variant its slot’s default, so the control sees it too. The measured gain so far is kept, and measurement continues against the new defaults. It takes the variants of one page, at most one per slot.

It holds until a production deploy changes that default in code: set default: in the page’s file to match.

A write: it also takes the options every write takes.

$ npx routingcat promote home/hero:family
promote · done · op_01m4zbfqr0fa49v710xk3sc2w2 · registry version 20
home/hero default: plan-week → family
publications pb_01m4zbfqr0fwqttp9y5atppz0f
era boundary home (pb_01m4zbfqr0fwqttp9y5atppz0f)
! home/hero: family is the default until a production deploy changes the default in routingcat/home.ts. (A22)

retire

Terminal window
npx routingcat retire <variant…>

Stops serving variants for good, keeping their history. A slot’s default cannot be retired. A retired variant returns with resume, with revert, or when it is declared again and that change goes live in production.

A write: it also takes the options every write takes.

$ npx routingcat retire home/hero:current
retire · done · op_01m4zbfqr0fa49v710xk3sc2w2 · registry version 20
home/hero:current eligibility: live → retired
welcome/checklist:tour held: true → false
change ch_01m4zbfqr0fwqttp9y5atppz0f
publications pb_01m4zbfqr0fzbb7a7j23jr4e9q · pb_01m4zbfqr0fgq9d4fhwyhfgbd7
scorecard ev_01m4zbfqr0eddsyqqmq0kgke7y opened: welcome/checklist:tour vs welcome/checklist:steps
scorecard ev_01kx68ntc0fgnbx7xqtn0wa7xx: window closed
scorecard ev_01kx68ntc0fz2tfkmdtfzpescs: window closed
scorecard ev_01ky9xn1r0ebbtkka94kcpe432: window closed

revert

Terminal window
npx routingcat revert <page> [--to <pb_…>]

Returns a page to what it served before. No version is created or lost.

Option What it does
--to <pb_…> Returns to an earlier publication instead, by its id, as status --since lists them.

A write: it also takes the options every write takes.

$ npx routingcat revert home
revert · done · op_01m4zbfqr0fa49v710xk3sc2w2 · registry version 20
home publication: pb_01m4xettc0e9karqctc3tvjkvf → pb_01m4zbfqr0fwqttp9y5atppz0f · as: none → pb_01m4dh0420fwwsmq55hmqw650q
publications pb_01m4zbfqr0fwqttp9y5atppz0f

set

Terminal window
npx routingcat set [<page or slot>] <setting>=<value>… [--confirm]

Changes routing settings. With a slot’s address, or a page’s for each of its slots: fixed_share, personalization, floor and cap; floor=auto and cap=auto return to the automatic bounds. Without an address, the site’s: control_share, random_control_share, episode_window and routing. Each is name=value, several at once; Routing settings gives each one’s range and default.

Option What it does
--confirm Says you agreed to lower control_share below 5%, which set refuses without it, with exit code 3: below 5% the measured gain is slow to come, and at 0 it can’t be computed. Your agent gives it only once you have agreed.

A write: it also takes the options every write takes.

$ npx routingcat set home/hero fixed_share=50% floor=auto
set · done · op_01m4zbfqr0fa49v710xk3sc2w2 · registry version 20
home/hero fixed_share: 0 → 0.5
publications pb_01m4zbfqr0fwqttp9y5atppz0f
scorecard ev_01kx68ntc0fgnbx7xqtn0wa7xx: support changed
scorecard ev_01kx68ntc0fz2tfkmdtfzpescs: support changed
scorecard ev_01ky9xn1r0ebbtkka94kcpe432: support changed
scorecard ev_01m1rgqs60eg4ab70xdf6s4fb7: support changed

gap

Terminal window
npx routingcat gap <outcome> --from <time> [--to <time>] [--note <text>]

Records a tracking gap: an outcome’s events were not tracked from --from to --to, so the visits in between count as unknown rather than as no conversion. Without --to the gap stays open; the same command with a --to closes it.

Option What it does
--from <time> When the gap started: a time or a day.
--to <time> When it ended. Without it, the gap stays open.
--note <text> Why, in a few words.

A write: it also takes the options every write takes.

$ npx routingcat gap signup --from 2026-10-10T08:00:00Z --note 'a deploy dropped the call'
gap · done · op_01m4zbfqr0fa49v710xk3sc2w2 · registry version 19
signup@1 from 2026-10-10T08:00:00Z · to none
gap signup@1 from 2026-10-10T08:00:00Z, open until you give --to
annotation signup (gap:signup:2026-10-10T08:00:00Z)

Deploy

plan

Terminal window
npx routingcat plan [page]

Compares the declarations in your code with production, and shows what a production deploy would make live, with each page’s limits. It validates as the build does, and exits with 1 where the build would refuse the code. Give a page to plan it alone.

$ npx routingcat plan
lumen · this code against production (dp_01m3yfqdsgfkr9jahvnyvk6gaa, commit 4be1c07) · contract 1.0
home new page · route / · objective signup, 24 h (from routingcat.config.ts)
hero new slot · default current
+ current "Edit photos like a pro" the default, which the control always sees
+ oneclick "Pro-level photo edits in one click" scorecard against current
+ studio "Your photos, studio-ready" scorecard against current
+ best "Make every photo your best one" scorecard against current
In production this goes LIVE, with routing within about 2 minutes:
the control keeps seeing the defaults · the random slice of visits is split evenly
the rest are routed toward signup, as the model learns which variant works for whom
A production deploy applies only what its code changed since the previous production deploy.
A preview deployment registers these versions and changes nothing live.
limits 4 of 100 variants · 1 of 20 slots
the site: 3 live variants, the defaults not counted, of the 10 the Hobby account's sites share
valid push will accept this (exit 0)

preview

Terminal window
npx routingcat preview <variant…> [--path <path>]

A signed link, valid for one hour, that opens the production page with the variants you name, and counts nothing in results. It takes the variants of one page, at most one per slot; the page’s other slots show their defaults.

Option What it does
--path <path> The path to open; by default, the page’s own.
$ npx routingcat preview home/hero:oneclick
https://lumen.so/?rc_preview=1.eyJieSI6InByXzAxazZnIn0.c2ln
forces home/hero:oneclick@v2
path / (its first route) · on dp_01m4xns9ggfyhra1beeb6f424r · until 10:12Z
Opened in a browser, it shows a preview badge; the visit stays out of results and leaves your own assignments as they are.

push

Terminal window
npx routingcat push [--check] [--built <dir>] [--head-only] [--dry-run] [--env production [--confirm <digest>]]

push runs in your build, after it compiles: it registers what the code changed, and a production build makes it live. Run by hand, it points you to plan.

Option What it does
--check Changes nothing, and fails while push would still edit a template, or while the head partial is out of date. Run it in CI before you deploy.
--built <dir> Also checks the pages your generator built into that folder, such as public, against your templates: each slot as they declare it, with the hashes push wrote.
--head-only Writes the head partial alone.
--env production Registers a script site’s production from your machine, with your sign-in. It prints the edits it would make and the plan, as plan shows it, then pushes that plan once you confirm it. At a terminal, it asks. Run by an agent, it ends with exit code 3 and the plan’s digest, so that the agent shows you the plan, then runs it again with --confirm.
--confirm <digest> With --env production: the digest printed with the plan, which confirms that plan. If your templates or production changed since, the plan has another digest, and nothing is pushed.

A write: it also takes the options every write takes.

$ npx routingcat push
✗ routingcat push runs inside your build, not by hand. To see what a deploy would make live, run routingcat plan. (D47, exit 2)

build

Terminal window
npx routingcat build

The build step of a site declared in routingcat.config.json whose host’s middleware decides, on Vercel or in a Cloudflare Worker: add it after your generator in the build command, as hugo && npx routingcat build. It fails while push would still edit a template or write the head partial again, registers the deployment with the build’s credential, and writes the values your middleware imports to .routingcat/. Without a credential, or with RoutingCat unreachable, the build still ships, and visitors get your defaults. On your own machine, without a credential, it writes development values instead, under which wrangler dev and vercel dev show the variants ?rc= names and record nothing. There, for a site on Cloudflare, ROUTINGCAT_ENV=production asks it for production, under your sign-in alone, a ROUTINGCAT_DEPLOY_KEY ignored: it prints the plan, as plan shows it, with a warning where your folder holds changes not committed or is on another branch than the site’s production branch, and registers that plan once you confirm it. A site another host builds is refused before the plan. At a terminal, it asks. Run by an agent, or with --json, it registers nothing and ends with exit code 3 and the plan’s digest, so that the agent shows you the plan, then runs it again with ROUTINGCAT_CONFIRM set to that digest, beside ROUTINGCAT_ENV=production.

$ npx routingcat build
routingcat LIVE home: 4 variants in hero, routing within about 2 minutes (ch_01m40j70srer495wr3vhnyvjca, pb_01m40j70srfb59gbvnmr3nv2t6)

Stability

The routingcat package follows semantic versioning for what this section lists: within 1.x, a minor or patch version only adds to it, and never removes or changes what it names. A change to any of it waits for 2.0.

  • The stable entries, each with the names it exports, values and types:
    • routingcat/next: config, ConfigDeclaration, Decided, DeclarationError, fromMinorUnits, IdentifyOptions, page, PageDeclaration, RoutingCat, routingcat, routingcatProperties, slot, SlotDeclaration, SlotResult, TrackOptions, variant, VariantDeclaration and withRoutingCat.
    • routingcat/next/proxy: proxy, ProxyHandler and ProxyOptions.
    • routingcat/browser: IdentifyOptions, InitOptions, LineItem, routingcat, routingcatProperties and TrackOptions.
    • routingcat/tracker: navigate, prepareNavigation, routingcat, routingcatProperties, start and StartOptions.
    • routingcat/outcomes: AccountOrigin, AccountSource, Ask, CancelEffectiveProperties, CancelScheduledProperties, currencyExponent, CustomerType, DEFAULT_LINK, DisputeProperties, DisputeState, Dropped, DropReason, Env, EveryOutcome, fromMinorUnits, GetRead, Item, JsonValue, LinkConfig, LinkOut, ListRead, MapContext, Mapped, Mapping, Mode, MoneyOutcome, Need, needKey, Outcome, OutcomeName, OutcomeOfName, PaymentProperties, PriorOutcome, Projected, Projection, Provider, PurchaseProperties, Read, ReadRecord, ReadResult, Reads, readsOf, RefundProperties, RenewalProperties, run, RunResult, shopify, SHOPIFY_API_VERSION, SHOPIFY_API_VERSIONS, SHOPIFY_TYPES, ShopifyDelivery, shopifyKey, ShopifyKeyInput, ShopifyOrderProperties, shopifyTrigger, stripe, STRIPE_API_VERSION, STRIPE_API_VERSIONS, STRIPE_TYPES, stripeKey, StripeKeyInput, stripeReadPath, stripeTrigger, TrialStartedProperties, Trigger, ValueBasis, versioned, VisitorLink, whop, WHOP_API_VERSION, WHOP_API_VERSIONS, WHOP_TYPES, WhopDisputeState, whopKey, WhopKeyInput and whopTrigger.
    • routingcat/vercel: ASTRO_DESCRIPTOR, FrameworkDescriptor, HTML_DESCRIPTOR, middleware, MiddlewareContext, MiddlewareHandler, MiddlewareOptions, NUXT_DESCRIPTOR and RoutingCatBuild.
    • routingcat/cloudflare: ASTRO_DESCRIPTOR, CloudflareOptions, CloudflareWorker, FrameworkDescriptor, HTML_DESCRIPTOR, NUXT_DESCRIPTOR, pages, PagesContext, PagesOptions, RoutingCatBuild, worker, WorkerContext and WorkerOptions.
    • routingcat/vue: config, ConfigDeclaration, DeclarationError, IdentifyOptions, page, PageDeclaration, routingcat, routingcatProperties, RoutingCatSlot, RoutingCatSlotProps, RoutingCatSlotScope, RoutingCatState, ServerEvent, Shown, slot, SlotDeclaration, TrackOptions, useRoutingCat, variant and VariantDeclaration.
    • routingcat/nuxt: default and RoutingCatNuxtOptions.
    • routingcat/astro: config, ConfigDeclaration, DeclarationError, default, IdentifyOptions, page, PageDeclaration, RoutingCatAstroOptions, RoutingCatLocals, Shown, slot, SlotDeclaration, TrackOptions, variant and VariantDeclaration.
    • routingcat/astro/components: RoutingCat, RoutingCatProps, RoutingCatSlot and RoutingCatSlotProps.
    • routingcat/runtime: CORE_VERSION, CoreAttributes, CoreConfig, RcState, RoutingCatPage, runCore, runPost and ViewState.
  • The files the package exports beside them, at their paths and in their formats:
    • routingcat/runtime/core.js: the browser runtime’s core, which a head partial carries inline.
    • routingcat/runtime/post.js: its post part, which a head partial loads from cdn.routingcat.com.
    • routingcat/runtime/manifest.json: their versions, hashes and sizes, format rc.runtime/1.
    • routingcat/schemas/*: the JSON Schema of each command’s output, a failure and the config.
  • The experimental entries, routingcat/react-router, routingcat/fetch, routingcat/react and routingcat/vite, are outside the promise, each as a whole: any version may change them, a patch included, until RoutingCat supports Hydrogen storefronts. Their declarations say @experimental, and a name they share with a stable entry, as the declarations, is stable through that entry alone.
  • The environment variables you may set, every other one starting with ROUTINGCAT_ being RoutingCat’s own, for its tests, which may change:
    • ROUTINGCAT_DEPLOY_KEY: a build’s credential where no Vercel or GitHub Actions OIDC token proves it, from npx routingcat keys deploy.
    • ROUTINGCAT_BRANCH: the branch a CI RoutingCat does not recognize builds.
    • ROUTINGCAT_ENV: set to production, a production build on your own machine, for a site on Cloudflare.
    • ROUTINGCAT_CONFIRM: the digest a production build’s plan printed, which confirms that plan on the next run.
    • ROUTINGCAT_CONFIG_DIR: the folder where the command keeps its sign-in when it does not use the keychain.
    • ROUTINGCAT_KEYCHAIN: set to off, the command keeps its sign-in in that folder, never the keychain.
  • Messages keep their id, as D2, and their code, as next_insecure: neither is ever reused for another message, and a code’s parameters keep their names and meaning. Their words may change, so read the id and the code, never the text (Messages).
  • The JSON contract: every --json output states contract, 1.0. Within version 1 it only grows: new fields, and new values where a field’s values are listed, never one removed, renamed or retyped. The JSON Schema of each command’s output and of a failure ships in node_modules/routingcat/schemas/, which schemas/index.json lists with the package’s and the contract’s versions (JSON output).
  • Exit codes, and no other (the command):
    • 0: done.
    • 1: rejected, denied or failed, with a message id.
    • 2: the command or its arguments are wrong.
    • 3: waiting, on a person or on time: run the same command again later.
    • 4: RoutingCat can’t be reached.