CLI basics
Bookrail is booking infrastructure: availability, holds, bookings, policies and webhooks behind one HTTP API. This CLI describes a project as code and talks to that API.
The loop
Section titled “The loop”bookrail login # store a sk_test_ key, mode 600bookrail init --template padel # write bookrail.config.tsbookrail push --dry-run # see what would be createdbookrail push # create itbookrail diff # confirm the project matches the filebookrail doctor # check credentials, project, reachability, version, configThen you operate on it:
bookrail availability --service svc_... --from 2026-09-11T00:00:00Z --to 2026-09-12T00:00:00Zbookrail availability --service svc_... --from ... --to ... --explain # why an instant is not therebookrail holds create --service svc_... --start 2026-09-11T06:00:00Z --ttl 10mbookrail bookings create --service svc_... --start 2026-09-11T06:00:00Z --hold hold_...bookrail bookings cancel bk_... --yesbookrail webhooks create --url https://example.com/hooks/bookrail # the secret, oncebookrail webhooks listen --url https://<your tunnel> --port 4100 # watch deliveries landbookrail events list --follow # watch the logEverything is test until you type --live. A sk_live_ key used without --live is a
hard error, not a warning: no request built by this process can reach the live environment
unless you asked for it.
Where the key comes from
Section titled “Where the key comes from”BOOKRAIL_SECRET_KEYin the environment, if set.~/.config/bookrail/credentials.json(or$XDG_CONFIG_HOME/bookrail/credentials.json), written bybookrail loginwith mode 600.
The key is never printed. bookrail whoami and bookrail env show it masked; whoami also
names the project the key opens, its scopes and its tenant_id.
Output
Section titled “Output”Every command takes --json and prints
{ "ok": true, "environment": "test", "data": { }, "next_steps": ["..."] }and on failure
{ "ok": false, "environment": "test", "error": { "code": "...", "message": "...", "param": "...", "doc_url": "...", "fix": "..." } }Exit codes: 0 success, 1 user or configuration error, 2 authentication, 3 network or
service, 4 conflict (the state changed under you; retrying may work).
Colour and decoration are off whenever stdout is not a terminal, and always off with --json.