JSON output
Every command takes --json, and then prints one JSON object on standard output instead of its text. The text is a view; the JSON is the contract, and an agent should read it. A line a person needs, such as a sign-in link, goes to standard error. Times are RFC 3339 in UTC, written with Z.
The envelope
Every output starts with these fields. The command’s own follow at the same level: a read returns what it read, and a write the operation it made, or would make with --dry-run.
| Field | Type | Meaning |
|---|---|---|
contract |
string | The contract’s version: 1.0. It only grows: see The contract’s version. |
command |
a command’s name, or null | The command; null when it was unknown, or none was given. |
site |
string, or null | The site’s key; null before there is a site, as in login. |
env |
production or preview, or null |
The environment; null when the command concerns neither. |
exit |
integer | The exit code the command ends with, as the command reference lists them. |
{ "contract": "1.0", "command": "domains", "site": "lumen", "env": "production", "exit": 0, "domains": [ { "match": "domain", "value": "lumen.so", "source": "production_origin", "added_at": "2026-10-02T14:19:52Z" }, { "match": "suffix", "value": "-lumen.vercel.app", "source": "vercel", "added_at": "2026-10-02T14:03:20Z" }, { "match": "domain", "value": "lumen.app", "source": "api", "added_at": "2026-10-07T12:00:00Z" } ]}Failures
A command that fails prints the envelope, with exit from 1 to 4, and the message that says why.
| Field | Type | Meaning |
|---|---|---|
error |
object | The message, as Messages and warnings describes it. |
errors |
list of object | Every check that failed, when there are several, as a build’s can be; error is the first. |
{ "contract": "1.0", "command": "login", "site": null, "env": null, "exit": 3, "error": { "id": "D30", "code": "sign_in_pending", "message": "Sign in to RoutingCat: https://app.routingcat.com/device?code=KQ7M-2PXD. Not approved after 50 s. Once approved, run the same command again.", "params": { "link": "https://app.routingcat.com/device?code=KQ7M-2PXD", "seconds": 50 } }}Messages and warnings
Every error and warning is a message from the catalogue that Messages lists:
| Field | Type | Meaning |
|---|---|---|
id |
string | The message’s id, such as D14: Messages lists each one, with its fix. |
code |
string | The form’s code, such as no_objective_event. |
message |
string | The text, filled in. |
params |
object | The values filled in, by name. Numbers stay numbers. |
A warning, as status lists them, adds:
| Field | Type | Meaning |
|---|---|---|
severity |
error, warning or information |
How serious it is. |
address |
string, or null | The lowest object it concerns, by address; null for the site. |
object |
id, or null | The same object’s id; null for the site. |
since |
time | When it started. |
Figures
Every figure that comes with a range or a kind is an object with the same fields, in this order, wherever it appears. This one is a scorecard’s difference, from show:
{ "quantity": "lift_vs_comparator", "value": 0.14, "interval": [-0.01, 0.3], "basis": "modeled", "design": "as_served", "units": "relative", "n": 4650, "n_eff": null, "maturity": 0.86, "outcome": "signup@1", "role": "headline", "watermark": "2026-10-16T09:00:00Z", "maturity_as_of": "2026-10-15T00:00:00Z", "issuer": "routingcat", "verification": "verified", "method": "evaluate@1.0", "pre_registered": true, "concurrency": "full", "stale": null, "unavailable": null}| Field | Type | Meaning |
|---|---|---|
quantity |
string | What the figure is, by name: see Names. |
value |
number, or null | The figure. Null when it cannot be produced yet, and unavailable says why. |
interval |
[lower, upper], or null | The 95% range. Null without one, and unavailable says why. |
basis |
randomized, modeled or descriptive |
Which kind of number it is: see Bases. |
design |
as_served, control_share, random_control or fixed_share, or null |
How the visits behind it were assigned: see Designs. |
units |
relative, absolute, rate, share, conversions or score |
What value is in: see Units. |
n |
integer, or null | How many visits it rests on. |
maturity |
number, or null | The share of those visits whose window has closed, from 0 to 1: at 1, every outcome is known. |
outcome |
string, or null | The objective or outcome it is about, with its version: signup@1. |
role |
headline or secondary, or null |
headline, the figure a result leads with, or secondary. |
watermark |
time, or null | Counts run to this time; later events are not in yet. |
maturity_as_of |
time, or null | Predictions are made from visits matured up to this time. |
issuer |
routingcat |
Who made the figure: RoutingCat. |
verification |
verified or unverified |
Whether RoutingCat vouches for the decisions behind the figure: verified, or unverified where some were made in visitors’ browsers, which RoutingCat checks against what each browser had, but cannot prove, as with any event a browser sends. |
method |
string | The method and its version, as evaluate@1.0. A change that alters a figure’s meaning changes the version. |
pre_registered |
true or false, or null | Whether the comparison was set up before its outcomes were known, as a scorecard opened when a change went live is. |
concurrency |
full, partial or none, or null |
For a comparison: whether both sides ran at the same time. See Comparisons. |
stale |
publication_changed or release_pending, or null |
A prediction waiting to be recomputed, and why; null otherwise. See Stale figures. |
unavailable |
object, or null | Why value or interval is missing: reason, and for not_matured the date it matures. See Missing values. |
covariance |
ignored |
ignored marks a range that ignores how the figures it combines depend on each other; absent otherwise. |
method_details |
list of approximation_weak |
The method’s notes on this estimate: approximation_weak when too few conversions, or one visitor weighing too much, make the range less reliable. |
Names
| Value | Meaning |
|---|---|
unconditional_score |
A variant’s predicted rate. |
contrast_with_default |
A variant’s difference from its slot’s default, relative or absolute. |
signal_strength |
Signal: how much evidence backs a variant’s predicted rate, from 0 to 100. |
program_share |
The share of its slot’s routed visits that routing currently intends for a variant. |
lift_vs_comparator |
A scorecard’s difference: its variant or version against what it is compared with. |
era_contrast |
Routed visits against the control, per visit, within one era. |
banked_gain |
One era’s extra conversions, from routed visits against the control. |
cumulative_gain |
The measured gain: the eras’ extra conversions, summed. |
control_share_observed |
The share of new visitors observed in the control, or in the random slice. |
matured_rate |
A counted rate over the visits whose window has closed. |
incomplete_rate |
A counted rate over all visits so far, which reads low. |
Bases
The basis says which of the three kinds of number a figure is: counted, predicted or measured. Only the measured gain counts as a gain.
| Value | Meaning |
|---|---|
randomized |
Measured, from a randomized comparison: routed visits against the control, or a fixed share’s even split. |
modeled |
Predicted, from the model’s current belief. |
descriptive |
Counted: what happened. |
Designs
| Value | Meaning |
|---|---|
as_served |
As routing served the visits. |
control_share |
Routed visits against the control. |
random_control |
The random slice, split evenly. |
fixed_share |
A fixed share’s even split. |
Units
Rates, shares and differences are fractions, never percentages.
| Value | Meaning |
|---|---|
relative |
A relative difference: 0.12 is +12%. |
absolute |
A difference in points of rate: 0.005 is half a point. |
rate |
A rate, from 0 to 1. |
share |
A share, from 0 to 1. |
conversions |
A count of conversions. |
score |
A score, as signal is, from 0 to 100. |
Comparisons
| Value | Meaning |
|---|---|
full |
Both sides ran over the same time. |
partial |
Their times overlap in part. |
none |
One after the other, as an edited variant’s versions are: a before and after. |
Stale figures
| Value | Meaning |
|---|---|
publication_changed |
What the page serves changed, by a deploy or an act, since it was computed. |
release_pending |
It waits for the next day’s learning. |
Missing values
A missing value always says why. Never read a missing value as zero.
| Value | Meaning |
|---|---|
no_data |
Nothing yet. |
no_reference_traffic |
No prediction yet: no visits have reached the page. Signal reads New. |
no_control |
No measured gain yet: no visits in the control. |
no_control_episodes |
No measured gain yet: no control visit whose outcome is known. |
not_matured |
The first visits mature on date; the figure follows. |
insufficient_n |
Too few visits for a range: the value shows without one. |
unresolved_baseline |
The default’s own rate is too uncertain for a relative difference: the difference in points shows instead. |
no_support |
The two sides never had visits in common, so they cannot be compared. Never read it as zero. |
no_model |
No prediction: the model doesn’t cover it yet. |
window_closed |
A comparison that ended, at its latest values. |
stale |
A prediction waiting to be recomputed, at its last value. |
Cursors
A list cut short, and the timeline of status --since, return a cursor: an opaque string. Pass it back, as npx routingcat status --since <cursor>, to read only what followed.
The contract’s version
contract is 1.0. Within version 1, the contract only grows: new fields, and new values where a field’s values are listed. Read what you know and ignore the rest; a field added later has a stated value on records made before it.
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,VariantDeclarationandwithRoutingCat.routingcat/next/proxy:proxy,ProxyHandlerandProxyOptions.routingcat/browser:IdentifyOptions,InitOptions,LineItem,routingcat,routingcatPropertiesandTrackOptions.routingcat/tracker:navigate,prepareNavigation,routingcat,routingcatProperties,startandStartOptions.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,WhopKeyInputandwhopTrigger.routingcat/vercel:ASTRO_DESCRIPTOR,FrameworkDescriptor,HTML_DESCRIPTOR,middleware,MiddlewareContext,MiddlewareHandler,MiddlewareOptions,NUXT_DESCRIPTORandRoutingCatBuild.routingcat/cloudflare:ASTRO_DESCRIPTOR,CloudflareOptions,CloudflareWorker,FrameworkDescriptor,HTML_DESCRIPTOR,NUXT_DESCRIPTOR,pages,PagesContext,PagesOptions,RoutingCatBuild,worker,WorkerContextandWorkerOptions.routingcat/vue:config,ConfigDeclaration,DeclarationError,IdentifyOptions,page,PageDeclaration,routingcat,routingcatProperties,RoutingCatSlot,RoutingCatSlotProps,RoutingCatSlotScope,RoutingCatState,ServerEvent,Shown,slot,SlotDeclaration,TrackOptions,useRoutingCat,variantandVariantDeclaration.routingcat/nuxt:defaultandRoutingCatNuxtOptions.routingcat/astro:config,ConfigDeclaration,DeclarationError,default,IdentifyOptions,page,PageDeclaration,RoutingCatAstroOptions,RoutingCatLocals,Shown,slot,SlotDeclaration,TrackOptions,variantandVariantDeclaration.routingcat/astro/components:RoutingCat,RoutingCatProps,RoutingCatSlotandRoutingCatSlotProps.routingcat/runtime:CORE_VERSION,CoreAttributes,CoreConfig,RcState,RoutingCatPage,runCore,runPostandViewState.
- 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, formatrc.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/reactandroutingcat/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, fromnpx routingcat keys deploy.ROUTINGCAT_BRANCH: the branch a CI RoutingCat does not recognize builds.ROUTINGCAT_ENV: set toproduction, 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 tooff, the command keeps its sign-in in that folder, never the keychain.
- Messages keep their id, as
D2, and their code, asnext_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
--jsonoutput statescontract,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 innode_modules/routingcat/schemas/, whichschemas/index.jsonlists 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.