Skip to content

Command reference

roost is a single roost binary with subcommands. Every global flag and every stay flag can appear anywhere on the command line, before or after the subcommand and its arguments — global and stay flags are attached to each command directly, and their values are merged across the context chain. roost search kyoto --json and roost --json search kyoto behave identically.

These attach to every command, including roost itself. They implement the agent-CLI contract shared across a fleet of tools. Several are inert no-ops in roost — present so the flag surface stays identical across tools that do mutate, even though roost never does.

FlagTypeDefaultBehavior
--formatjson | plain | tsvplainOutput format.
--jsonflagoffShorthand for --format=json.
--no-colorflagoffDisable colored output (color is only ever applied to plain output on a TTY anyway).
--allow-mutationsflagoffInert no-op. roost is read-only and never books; present for contract uniformity.
--dry-runflagoffPrint the request plan without fetching. Only dates gives this real meaning (it prints the sweep plan and exits 0 without an upstream call); on other commands it has no effect.
--yesflagoffInert no-op. Nothing in roost ever asks for confirmation.
--forceflagoffInert no-op. There are no safety checks to bypass.
--no-inputflagoffNever prompt; fail with exit 13 (INPUT_REQUIRED) instead.
--limitint50Max items returned for list-shaped output.
--selectstringnoneComma-separated dot-path field projection.
--conciseflagon (default)Inert no-op. Accepted for contract uniformity; roost’s output shape doesn’t currently change based on this flag.
--detailedflagoffInert no-op. Accepted for contract uniformity; roost’s output shape doesn’t currently change based on this flag.

search, rates, and dates all take the same stay flags — the shape of the trip you’re asking about. Like the global flags, these can appear anywhere on the command line.

FlagTypeDefaultBehavior
--backendgoogle | serpapigoogleData backend. google is keyless; serpapi needs an API key. Overridable with ROOST_BACKEND.
--check-inYYYY-MM-DDtodayCheck-in date.
--check-outYYYY-MM-DD--check-in + --nightsCheck-out date. If both --check-out and --nights are given, --check-out wins.
--nightsint2Length of stay when --check-out is omitted. Must be at least 1.
--adultsint2Adult guests. Must be at least 1.
--childrenint0Child guests.
--currencystringUSDISO currency code for rates.
--brandstringnoneComma-separated brand/chain ids — see roost brands.
--waitflagoffSleep through the politeness throttle instead of failing fast with exit 7.
--max-waitfloat30.0Cap, in seconds, on how long --wait will sleep.
--no-throttleflagoffSkip the local politeness throttle entirely. Use sparingly — it exists to keep roost welcome upstream.
--no-wrap-untrustedflagoffDisable untrusted-text fencing (on by default — see Politeness).
Terminal window
roost search LOCATION [OPTIONS]

Search available properties for a location and stay. The core command: what is available in LOCATION for these dates, and at what rate.

Argument

NameRequiredDescription
LOCATIONyesFree-text place to search, e.g. "kyoto" or "chicago".

Options (in addition to the global flags and stay flags)

FlagTypeDefaultBehavior
--classintnoneMinimum hotel class in stars (2-5).
--min-ratingfloatnoneMinimum guest rating.
--max-pricefloatnoneMaximum nightly rate.
--free-cancellationflagoffOnly properties offering free cancellation. Rejected on the google backend with exit 2 / UNSUPPORTED_ON_BACKEND — Google’s result cards carry no cancellation signal, so honoring it would return an empty set that reads as “none offer it”. Use --backend serpapi.
--amenitystringnoneComma-separated amenities that must ALL be present (substring, case-insensitive match).
--property-typestringnoneComma-separated property-type filters.
--sortrelevance | price | rating | reviewsrelevanceResult ordering.

On the google backend, --class, --min-rating, --max-price, --free-cancellation, --amenity, and --property-type are applied client-side over the page of results Google returned — they narrow, they don’t search deeper. --brand is not applied server-side on google at all (Google’s brand filter ids are only exposed via serpapi); results still span all chains. Either case sets scope.partial: true and adds an explanatory note. See Comparing rates across backends.

Terminal window
roost search "chicago" --backend serpapi --brand hyatt,marriott --free-cancellation --json

Exit codes: 0 ok, 2 usage (bad date/nights), 3 empty results, 4 auth required (serpapi backend, no key), 5 not found (LOCATION couldn’t be resolved to a place), 7 rate limited, 8 retryable, 20 blocked, 21 schema drift.

Terminal window
roost rates PROPERTY_ID --location LOCATION [OPTIONS]

Per-source rate breakdown for one property — brand-direct vs each OTA.

Argument

NameRequiredDescription
PROPERTY_IDyesThe property to price, as returned by roost search.

Options

FlagTypeDefaultBehavior
--locationstringRequired. The location to look the property up in — rates are date + place scoped.

Plus the global flags and stay flags.

Depth differs by backend. serpapi exposes the full per-source list. google reports what the search surface carries — its property page is client-rendered and its rate matrix comes over an RPC roost declines to call — and sets scope.partial: true with a note pointing at --backend serpapi. It never silently returns less without saying so.

Terminal window
roost rates "Sakura Cross Hotel" --location kyoto --nights 3 --json

Exit codes: 0 ok, 2 usage, 3 empty results (the location matched no properties at all for the stay), 4 auth required, 5 not found (unknown PROPERTY_ID, or --location couldn’t be resolved to a place), 7 rate limited, 8 retryable, 20 blocked, 21 schema drift.

Terminal window
roost dates LOCATION [OPTIONS]

Sweep check-in dates to find when a stay is available and cheapest. The only command that issues more than one upstream request per invocation — so it is hard-capped by --max-requests and always reports requestsIssued.

Argument

NameRequiredDescription
LOCATIONyesFree-text place to search.

Options

FlagTypeDefaultBehavior
--windowint30How many days forward to sweep. Must be at least 1.
--stepint1Days between sampled check-in dates. Must be at least 1.
--max-requestsint8Hard cap on upstream requests. Must be at least 1.

Plus the global flags and stay flags.

--dry-run prints the request plan (window, step, maxRequests, requestsPlanned, sampledDates) and exits 0 without fetching anything — use it to see the cost of a sweep before spending requests.

Terminal window
roost dates "lisbon" --window 30 --nights 2 --dry-run

When not dry-run, the response envelope’s dates key carries one entry per sampled date, plus cheapest (the lowest-priced available date, or null), requestsIssued, and truncated (true when --max-requests capped the sweep short of the full window). See Finding cheap dates.

Exit codes: 0 ok, 2 usage (bad --window/--step/--max-requests, or bad date/nights), 4 auth required, 5 not found (LOCATION couldn’t be resolved to a place — this fails the whole sweep, since every sampled date depends on the same place lookup), 7 rate limited (only if the very first sampled date hits it — after that, a mid-sweep block or rate limit is instead recorded as a row with available: null and the sweep stops there, see output schema), 8 retryable, 20 blocked (same first-date caveat as 7), 21 schema drift. Unlike the other two commands, dates never itself exits 3 — a date with no availability is reported as a row with available: false, not a command failure.

Terminal window
roost brands [OPTIONS]

List the hotel chain/brand filter ids usable with --brand. On the default google backend this is bundled data — the command makes no network request. brands has no --backend flag of its own, but it still honors the ROOST_BACKEND environment variable; setting ROOST_BACKEND=serpapi makes it fetch the live brand taxonomy from SerpApi instead, which needs a key configured (see Configuration).

Options

FlagTypeDefaultBehavior
--searchstringnoneFilter brands by name substring.

Plus the global flags.

On the google backend, listed brands carry id: null — Google’s brand filter ids are only exposed via serpapi, so google returns a curated chain list for reference, not filter ids that take effect server-side.

Terminal window
roost brands --search hyatt

Exit codes: 0 ok (the default google backend). On the google backend this command is offline and takes no stay flags, so none of the network/auth/usage failure modes apply; via ROOST_BACKEND=serpapi it can also exit 4 (auth required, no key), 7/8 (rate limited/retryable from SerpApi), same as the other commands on that backend.

Terminal window
roost doctor [OPTIONS]

Diagnose setup — backend reachability, throttle and circuit-breaker state, and auth/keyring status. Emits {"ok": ..., "checks": [...]}, one entry per check (name, ok, detail).

Plus the global flags.

Exit codes: 0 all checks passed, 10 config error (one or more checks failed — see the failing check’s detail). If ROOST_BACKEND=serpapi is set with no key configured, doctor exits 4 (auth required) immediately instead of running its checks — the same backend resolution every command uses (see Configuration) applies before doctor’s own diagnostics get a chance to report the missing key as just another check.

Terminal window
roost auth login --token-stdin
roost auth status
roost auth logout

Manage the optional SerpApi backend key. The default google backend needs none of this.

FlagTypeDefaultBehavior
--token-stdinflagoffRead the API key from stdin — the only supported path.

The key is read from stdin, never from argv, so it never leaks into ps, /proc, shell history, or an agent’s own command log. Omitting --token-stdin fails with exit 13 (INPUT_REQUIRED); so does an empty or all-whitespace stdin read, or a TTY stdin combined with --no-input.

Terminal window
echo -n "$SERPAPI_KEY" | roost auth login --token-stdin

There is no auth refresh — the key is static, not a token that expires.

Exit codes: 0 ok, 13 input required.

Show authentication status. The key itself is redacted in the output.

Exit codes: 0 ok.

Remove the stored SerpApi key. Idempotent — succeeds whether or not a key was present, and reports existed: true|false. Removes the local copy only; it does not revoke the key upstream.

Exit codes: 0 ok.

Terminal window
roost schema [OPTIONS]

Print the machine-readable command schema as JSON: tool, version, schemaVersion, a conformance block (spec name, version, level), the full commands tree, the exit_codes table, a safety block, a boundary block (allowed_paths, disallowed_paths, evasion policy), and the current throttle snapshot for the active backend.

Plus the global flags.

Exit codes: 0 ok.

Terminal window
roost agent [OPTIONS]

Print the bundled agent SKILL.md to stdout — the reference doc written for an LLM agent driving roost.

Plus the global flags.

Exit codes: 0 ok.

Terminal window
roost version [--check] [OPTIONS]

Print the installed version, or with --check, also report whether a newer release exists.

FlagTypeDefaultBehavior
--checkflagoffCheck for a newer release: network call, short timeout, fail-silent.

Plus the global flags.

--check never mutates anything — it only reports the upgrade command (uv tool install --upgrade roost, or an override via ROOST_RELEASES_URL) for a human or package manager to run; roost never self-updates. If the version check can’t reach a release source, latest is null and a note explains it — this never fails the command.

Exit codes: 0 ok (always, --check failures degrade gracefully rather than erroring).

CodeNameMeaning
0okSuccess.
1generic_errorUnclassified failure.
2usageBad arguments/flags (e.g. malformed date, --nights < 1).
3empty_resultsThe request succeeded but matched nothing.
4auth_requiredThe serpapi backend is selected (via --backend or ROOST_BACKEND) with no key configured — including on commands with no --backend flag of their own, since they still honor ROOST_BACKEND.
5not_foundA specific lookup failed — a LOCATION couldn’t be resolved to a place, or a rates PROPERTY_ID doesn’t exist.
6permissionPermission denied.
7rate_limitedLocal politeness throttle — wait or pass --wait.
8retryableTransient upstream failure; retrying may help.
10config_errorSetup problem, e.g. roost doctor found a failing check.
12mutation_blockedDefined but unreachable — roost has no mutating operations to block.
13input_requiredA prompt was needed but input is disabled or stdin was empty.
20blockedUpstream served a challenge or soft block. Stop; do not retry immediately.
21schema_driftUpstream response no longer parses as expected. Retrying never helps — the tool needs an update.
130cancelledUser interrupted (Ctrl-C).