Skip to main content
trevo is the dashboard’s /v1 routes with a workspace API key instead of a browser session. Anything it does, a person could do by clicking — list what Trevo proposed, approve or dismiss, send revision instructions, ask for a fresh batch, start and end experiments.
It has no runtime dependencies and needs Node 18 or newer.

Authentication

Make a key under Settings → API access. It is shown once.
Prefer the prompt on a shared machine: a key passed as --key is visible in ps and lands in your shell history. In CI, use TREVO_API_KEY and never trevo login. The CLI sends the key only to https://api.trevosdk.com unless TREVO_API_URL says otherwise, and it refuses to send it over plain http to anything but a local address, to a URL carrying credentials, or over a scheme that is not http(s). Pointing it anywhere other than the product host prints a warning on stderr — in CI that line is the difference between a redirected key and a silent one. In CI, set TREVO_API_KEY instead — the environment wins over the stored file, so a job never writes one:
A key opens one workspace, reads everything in it, and writes only what its scopes allow. It acts as the person who made it. Scopes, refusal codes, and the routes themselves are in the API reference. tsk_live_ and tsk_secret_ SDK keys are your site’s and are refused here. TREVO_API_URL points the CLI at another host if you run one.

Commands

Dismiss reasons, comma-separated for more than one: not_relevant, too_risky, tried_before, wrong_metric, does_not_match_code, not_feasible, wrong_area. trevo proposals revise --wait blocks until the revision lands, up to ten minutes, and exits non-zero if it fails.

Declare an experiment yourself

You do not have to wait for a proposal. create takes the same body the dashboard’s custom-experiment form sends:
Splits must sum to 100, and the first conversion target is the primary metric — the others may carry "role": "guardrail". An event your site does not send yet is fine: Trevo Bot wires the track() call in the pull request. The Idempotency-Key is derived from the body, so a re-run of the same step within about ten minutes replays the first result instead of opening a second pull request. Pass --idempotency-key to choose your own.

Keep funnels in your repository

pull writes the definitions as a file to commit; apply reconciles a workspace to that file. Funnels are matched by name, so renaming one in the file creates a new funnel rather than renaming the old one.
apply creates what is missing and updates what changed, and is a no-op the second time it runs. It never deletes unless you pass --prune — a partial file must not quietly remove the funnel a running experiment is judged on.
Step order comes from the order in the file unless a step states its own stepOrder.

Following the slow ones

generate and approve both answer before the work is done — generation is minutes of model work, and a pull request means Trevo Bot cloning your repository and writing code. Each has a way to follow it.
approve --wait exits 0 with the pull-request URL, and 1 the moment generation ends at pr_failed — it does not sit out the timeout on a failure. Both waits are bounded (--timeout, in seconds; 20 minutes by default for a pull request) and print what to run next if they give up. Without --wait the same answers come from trevo runs and trevo experiments status <id>.

Wait for a status in CI

Exits 0 when the status arrives, 1 when the experiment settles somewhere it will not leave (pr_failed, rejected, …) or the timeout passes — --wait always ends.

Output and exit codes

Every command takes --json and prints the API response verbatim; without it you get a table or a line of prose. Exit codes separate the cases a script has to tell apart: So a CI job can tell a revoked key from a proposal that was not approvable:

In a script

The client the CLI uses is exported, for scripts that would rather call the routes than parse output:
Errors throw ApiError carrying status and the API’s code, so a caller can branch on SURFACE_OVERLAP rather than on prose.