Skip to content

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.

Terminal window
bookrail signup # get a sk_test_ key by email, stored mode 600
bookrail init --template padel # write bookrail.config.ts
bookrail push --dry-run # see what would be created
bookrail push # create it
bookrail diff # confirm the project matches the file
bookrail doctor # check credentials, project, reachability, version, config

Then you operate on it:

Terminal window
bookrail availability --service svc_... --from 2026-09-11T00:00:00Z --to 2026-09-12T00:00:00Z
bookrail availability --service svc_... --from ... --to ... --explain # why an instant is not there
bookrail holds create --service svc_... --start 2026-09-11T06:00:00Z --ttl 10m
bookrail bookings create --service svc_... --start 2026-09-11T06:00:00Z --hold hold_...
bookrail bookings cancel bk_... --yes
bookrail webhooks create --url https://example.com/hooks/bookrail # the secret, once
bookrail webhooks listen --url https://<your tunnel> --port 4100 # watch deliveries land
bookrail events list --follow # watch the log

Everything 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.

bookrail signup is the whole answer: it asks for an address, sends a link there, waits for you to open it, and stores what comes back, which is two keys, a test one and a live one. No password, and nobody to write to. --no-store prints both once instead of writing them. Before anything is sent it shows the Terms of Service and the Data Processing Agreement and asks you to accept them on behalf of your business and, separately, to approve the clauses of their Section 17; --accept-terms and --approve-clauses answer for a script.

The live key books for real, on the free plan: up to 1,000 confirmed live bookings a month, then new live bookings are refused with 402 plan_limit_reached until the next month or a paying plan. It is stored next to the test one and used only when you type --live. More keys, and revoking one, are in the dashboard at bookrail.dev/dashboard: you sign in with a link sent to the same address. A key made there goes in with bookrail login --token sk_test_..., or bookrail login --live --token sk_live_....

Once there is a key, this is where a command looks for it:

  1. BOOKRAIL_SECRET_KEY in the environment, if set.
  2. ~/.config/bookrail/credentials.json (or $XDG_CONFIG_HOME/bookrail/credentials.json), written by bookrail signup and by bookrail login with 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.

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.