receipt setup, approve the CLI in the page that opens, and every other command — receipt workspace, receipt tools, receipt mcp, receipt connect — has an identity to work with. It stays signed in for 12 hours.
Three commands, one session
All three also work with a leading
connect, so receipt connect setup and receipt setup are the same command. The similarly named receipt connect doctor and receipt connect check do not run setup — they run the read-only receipt doctor, which resolves your endpoint and reports the saved session without ever opening a browser.
For the hosted app there is nothing to configure — the binary resolves app.kentron.ai on its own, so a plain receipt setup on a fresh machine signs you straight in. You only pass a host when you are pointing at a dev or self-hosted origin; see Install the CLI.
What setup actually does
Exactly two things, in order:- Signs you in. It resolves which host to talk to, reuses a saved session if one matches and is still valid, and otherwise runs the browser device login below and writes a new session file.
- Installs the Claude observer, but only when the companion binary can be found. The current release does not ship that companion, so on a freshly installed CLI the step reports itself as not installed and names the reason. That is not an error and it does not stop sign-in — see Observing and importing Claude Code activity.
Flags
setup and login take the same endpoint and sign-in flags.
prod | dev | local | http(s) URL
default:"prod"
Which endpoint to use. An
http:// or https:// value, like --server-url, produces a custom target. Anything else fails with receipt connect target must be prod, dev, local, or an http(s) URL — and it fails even when you also passed --server-url, because the target word is validated before the override is applied.url
The Receipt Connect gateway to use, overriding the target. Setting it always produces a
custom session.url
The web origin that hosts the browser sign-in page, when it is not the same host as the gateway.
boolean
default:"false"
Ignore any saved session and run the device login again.
setup now detects an expired token on its own and re-runs the login for you, so you mainly need this to force a re-login while a token is still technically valid — for example when the gateway has rejected it.boolean
default:"false"
Skip sign-in entirely; the account line then reads
Receipt account: not connected (disabled by setup flag). Aliases: --skip-login, --local-only.boolean
default:"false"
Skip the Claude observer install.
setup only. Aliases: --no-observer, --no-background, --skip-claude.boolean
Print the sign-in URL instead of opening a browser.
--open=false does the same, and so does setting RECEIPT_CONNECT_OPEN_BROWSER=0 in the environment.boolean
default:"false"
Return a structured envelope instead of the status lines. It also suppresses the
Step 1 of 2 progress lines.--proxy-bin <path>, --mode and --event-log are passed through to the observer install step.
--no-open is a boolean, and this binary’s flag parser lets a boolean swallow the next word. receipt setup --no-open --json is fine; receipt setup --no-open followed by another bare word is not. Use --open=false if you need the flag anywhere but last. See the parsing rules.Session reuse
setup reuses the saved session for the target — no browser opens — only when all three of these hold:
--fresh-loginwas not passed,- the saved
gatewayUrlmatches the host you resolved to (localhostand127.0.0.1count as the same), and - the saved token has not expired.
setup does not reuse it. It runs the full device login and writes a fresh session — you no longer end up carrying a dead token forward. Any other mismatch (a different host, or no saved session at all) also runs the full login.
Whichever way it resolves, the session for the target you set up is promoted to the active ~/.receipt/session.json. So the most recent setup wins: receipt setup --target local and then receipt setup flips which environment receipt mcp, receipt workspace and receipt tools talk to — even when the later setup reused a still-valid saved session rather than signing in again.
The browser device login, step by step
1
The CLI asks for a code
It prints
Starting Receipt Connect sign-in at <authUrl>... and posts a start request to <authUrl>/api/receipt-connect/cli-login, with a 15-second timeout.The server rate-limits this: at most 10 starts per 60 seconds per client IP, and at most 3 sign-ins pending at once. Over either limit it answers HTTP 429 with {"ok":false,"error":"rate_limited","retryAfter":60}, and the CLI reports receipt connect device login failed to start: rate_limited.2
You get a code good for ten minutes
The server issues an eight-character user code in the form
XXXX-XXXX, drawn from an alphabet that leaves out the characters people misread — no I, O, 0 or 1. It expires after 10 minutes.3
The CLI prints the code and opens a browser
--no-open or set RECEIPT_CONNECT_OPEN_BROWSER=0. The URL carries only the short user code.4
You approve it in the browser
Approval needs an existing signed-in Receipt session in that browser and an active organization. What you see depends on the state:
- Not signed in — you are redirected to the sign-in page and returned to the approval page afterwards.
- Approved —
Receipt Connect is approved, withYou can return to the terminal. This page can be closed. - No active organization —
Select a workspace first, withReceipt Connect credentials are stored at the workspace level. Open Receipt, select a workspace, then run the CLI command again. - Unknown or expired code —
This Receipt Connect code is invalid or expired. - Code already used —
This Receipt Connect code was already used. Run the CLI command again.Each code is single-use.
5
The CLI polls until you approve
It polls every 2 seconds, for up to 10 minutes. While you have not approved yet, the server answers
authorization_pending and the CLI keeps waiting. An expired code ends it with receipt connect device login expired; running out of time ends it with receipt connect device login timed out.On success the CLI prints Receipt sign-in approved. and writes the session file.receipt connect device login request failed for <url>: <message> for a network or timeout problem, receipt connect device login failed to start: http_404 when the auth URL is not the web application, receipt connect device login returned an empty token, and receipt connect login did not return a workspace; select a Receipt workspace and try again. Every one of them, with its cause and fix, is in CLI troubleshooting.
Signing in only, with receipt login
receipt login runs the sign-in step above and stops there: no connector catalog, no observer install. Use it when you are switching environments or refreshing an expired token and do not want the rest of setup’s work.
It takes an optional positional target, so these are equivalent:
setup. On success it prints three lines:
already signed in instead of signed in when it reused a saved session. With --json you get ok, reused, the target and gateway URL, the identity fields, and both session file paths.
login honours setup’s skip flags. receipt login --no-login prints receipt login: skipped (disabled by setup flag) and exits 0 without signing you in.What gets written to disk
The active session is~/.receipt/session.json. The directory is created with mode 0700 and the file is written atomically — to a temporary file at mode 0600, then renamed — so it stays readable only by you.
RECEIPT_CLI_CONFIG_DIRmoves the whole directory.RECEIPT_CLI_SESSION_FILEsets the exact path of the active session file, and suppresses the per-target files entirely.
prod, dev and local targets each get their own copy: session.prod.json, session.dev.json, session.local.json. A custom target — anything reached through a URL or --server-url — writes no per-target file, only the active one.
Each file contains:
A file missing
gatewayUrl, token or organizationId, or one that will not parse, is treated as no session at all rather than as an error.
Signing out, with receipt logout
receipt logout reads the active session, deletes it and the per-target file for that same target, and prints:
receipt logout: not signed in and still exits 0. It reads no flags — there is no --target, so it always acts on whichever session is currently active. Sessions for other targets are left in place, which is what makes receipt setup --target local a safe way to come back to a local stack without losing your hosted sign-in. Deleting the files by hand works too.
The token: 12 hours, three scopes, one workspace
The token the login returns is a JWT that:- Expires after 12 hours.
- Carries three scopes:
connect:credential,connect:readandconnect:write. - Is bound at login to the organization’s Default workspace — always. You cannot choose a different workspace during sign-in; approving in the browser picks the organization, not the workspace. Changing workspace afterwards is
receipt workspace use.
setup also exports the session’s values — gateway URL, token, organization, workspace and user id — as environment variables into its own process, and only its own process. They are not exported to your shell.
What setup prints
receipt connect status.
The observer line reads Claude observer: installed (<platform> <serviceFile>) when the companion binary was found and the background service installed.
With --json you get the same information as one envelope: ok, a receiptAccount object (including whether the session was reused or skipped, the target, gateway URL, identity fields, and the session file paths), the full connectors catalog, and claudeObserver.
Next step: check your setup with receipt doctor.