CLI reference
Stdout is compact JSON when it is not a terminal, or with --json. --text forces a table. Errors are always JSON on stderr.
Every command accepts: --json --text --fields --all-pages --dry-run --idempotency-key --server --token
--fields a,btrims a response to those fields.--all-pagesfollowsnext_cursoron a list and prints every item as one page.--dry-runruns a mutation without writing anything.--idempotency-keyreplays a successful mutation instead of repeating it.pursuit schema <command>prints that one command’s flags as JSON;pursuit schemalists all of them.
This page is generated from pursuit --help and its subcommands. Run pursuit schema for the machine-readable form, or see the API reference for the HTTP equivalent of each command.
Exit codes
| Code | Meaning |
|---|---|
| 0 | ok |
| 1 | other |
| 2 | usage |
| 3 | not found |
| 4 | conflict |
| 5 | auth |
| 6 | validation |
Applications
pursuit list
List applications. The most common read.
pursuit list [flags]
--status filter by status (repeatable)
--status-not exclude a status (repeatable)
--company filter by company name
--fit strong, reach, or maybe
--source greenhouse, ashby, lever, workday, company_site, other
--tag filter by tag
--q search company, title, notes, location, next step
--stale only postings the link checker marked closed
--archived list archived applications instead of the default view
--limit page size, 1-200, default 50
--cursor next_cursor from the previous page
--sort field or -field, default -updated_atpursuit list --stale --fields id,company,title,link_statuspursuit apps
get, create, update, delete, transition, archive, unarchive, tag, set-field. pursuit apps list is the same read as pursuit list.
pursuit apps list --status to_apply --fields id,company,title,status
pursuit apps transition APP_ID --status interviewing
pursuit apps archive APP_IDStages and outcomes
A status is either a stage or an outcome. Stages fill the progress mark from the bottom of the ring up to the tail: to_apply (0), awaiting_review (1, Prepared), applied (2), screening (3), interviewing (4), final (5), offer (6, the gold tail). Outcomes sit on top of the current stage and never clear it: needs_input and waiting hold it (amber); failed, rejected, withdrawn and ghosted end it (red). Transition to an outcome to set it, or to the stage the application is on to clear it.
pursuit apps transition APP_ID --status rejected # stays at interviewing, outcome rejected
pursuit apps transition APP_ID --status interviewing # clears the outcome
pursuit list --status rejected # filters match the outcomepursuit interviews
Rounds within any stage — prepared, applied, screening, interviewing, final or offer — and several stages can have them at once. Each round is a sub-arc of its stage’s segment on the mark and fills when you mark it done. --stage defaults to the application’s current stage.
pursuit interviews add APP_ID --kind "System design" --when 2026-11-05 --prep-file prep.md
pursuit interviews list APP_ID
pursuit interviews set INTERVIEW_ID --notes "Went well"
pursuit interviews done INTERVIEW_ID
pursuit interviews delete INTERVIEW_IDpursuit roles / pursuit companies
Standard list, get, create, update, delete on roles and companies.
The apply pipeline
Statuses move to_apply → preparing → awaiting_review → approved → submitting → submitted. A prepare can stop in needs_input or failed.
pursuit apply
pursuit apply [<id>] --prepare | --async | --batch key=value
--prepare run the one-step prepare now
--async enqueue the work
--batch filter key=value (repeatable)
--worker worker id for a synchronous preparepursuit apply APP_ID --prepare
pursuit apply --batch status=to_apply --asyncpursuit queue
claim, heartbeat, complete — the work-stealing loop a worker agent runs.
pursuit queue claim --worker agent-1
pursuit queue heartbeat WORK_ID --worker agent-1
pursuit queue complete WORK_ID --worker agent-1 --status awaiting_reviewpursuit approve / pursuit reject
The only commands that can move an application past awaiting_review. Both require an approve-scoped token.
pursuit approve <id> [<id>...] --note "..."
pursuit reject <id> [<id>...] --note "..."approve marks the application approved and enqueues submit work — it does not submit a form. reject marks an awaiting_review application withdrawn and does not enqueue anything. A write token can prepare and can finish a submit only after an approval exists.
Company caps (e.g. “3 active per 180 days”) apply here: exceeding a cap is a conflict (exit code 4).
Postings and links
pursuit check-links
pursuit check-links --all | pursuit check-links <application-id>Re-checks that postings are still live. Prefers Greenhouse, Ashby and Lever APIs, then falls back to HTTP status and closed-posting phrase matching. Records link_status; never changes the pipeline status.
pursuit links
pursuit links [--all | --status <status> | --changed]
--all every checked posting, not only closed or changed
--status live, closed, or unknown
--changed only postings whose status changed since the previous checkpursuit links --fields company,title,status,detailEvents, tags, fields, standing answers
pursuit events list|add— timeline events per application;pursuit events --follow --timeout 25slong-polls for the next one.pursuit tags list|create|deletepursuit fields list|create|delete— custom application fields.pursuit standing list|set— reusable answers for form questions (pursuit standing set --key work_authorization --answer "Yes").
Batch
pursuit batch <file|-> posts one JSON body to POST /v1/batch and runs up to 100 requests in order as the caller:
{"requests": [
{"method": "PATCH", "path": "/v1/applications/APP?version=3", "body": {"fit": "strong"}, "idempotency_key": "fit-APP"},
{"method": "POST", "path": "/v1/applications/APP/tags", "body": {"name": "priority"}}
], "stop_on_error": false}The response is {"results": [{"status", "body"}], "failed": n}. Each item goes through its normal route, so scopes, validation, and idempotency keys apply per item, and --dry-run applies to all of them. Items are not atomic. The command exits with the code of the first failed item.
Signing in
pursuit auth login [--server URL] [--device] [--scope read,write]— opens the dashboard’s/authorizepage and listens on127.0.0.1for the callback (OAuth2 authorization code with PKCE).--device, an SSH session, or Linux with no display uses a device code instead: open/device, type the code, approve. Approving needs your own dashboard session with theapprovescope and is audited asoauth.approveoroauth.deny. The new token hasreadandwriteby default, or--scope read. It never hasapprove:--scope approveexits 2 and the server answersinvalid_scope.pursuit auth status— server, user, scopes, and where the token came from (flag,env,config, or the storedfile/macos-keychain/secret-service). Exits 5 when there is no token.pursuit auth logout— revokes the stored token on the server and deletes it locally.
Stored tokens go to the OS keyring when security (macOS) or secret-tool (Linux) is available, otherwise ~/.config/pursuit/credentials.json (mode 0600, override with PURSUIT_CREDENTIALS). PURSUIT_AUTH_SECRET_STORE=file forces the file. --token, PURSUIT_TOKEN, and a config-file token always take precedence over a stored login. Otherwise any process running as you that calls the CLI (an agent included) uses the stored login, which is at most read,write. A Keychain item written by /usr/bin/security is readable by any process running as your user, so it is no stronger than the 0600 file against a local agent. A locked or unreadable keyring is an error (exit 5), not a silent logout.
Tokens, audit, webhooks
pursuit tokens list|create|revoke— scopes areread,write(includesread),approve(includesread, notwrite). New tokens are read-only unless scopes are passed.pursuit audit listpursuit webhooks list|add|delete— event webhooks.
Import and export
pursuit import csv applications.csv
pursuit import json postings.json
pursuit import markdown notes.md
pursuit import seed
pursuit export simplify
pursuit export jsonMarkdown tables and “also live” bullets become to_apply and skip a posting URL that already exists. import seed loads the example files in internal/seed/data. CSV status Applied stays applied; Prepared becomes awaiting_review; other statuses match case-insensitively. Importing the same posting_url again updates that application. export simplify writes the Simplify Job Tracker CSV columns.
Daemon
pursuit serve # run the daemon
pursuit health # liveness
pursuit ready # readiness (503 until bootstrap finishes, and during shutdown)
pursuit version # CLI version