Skip to Content
Pre-release — pursuit has no versioned releases yet. Everything here can change.
CLI reference

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,b trims a response to those fields.
  • --all-pages follows next_cursor on a list and prints every item as one page.
  • --dry-run runs a mutation without writing anything.
  • --idempotency-key replays a successful mutation instead of repeating it.
  • pursuit schema <command> prints that one command’s flags as JSON; pursuit schema lists 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

CodeMeaning
0ok
1other
2usage
3not found
4conflict
5auth
6validation

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_at
pursuit list --stale --fields id,company,title,link_status

pursuit 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_ID

Stages 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 outcome

pursuit 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_ID

pursuit 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 prepare
pursuit apply APP_ID --prepare pursuit apply --batch status=to_apply --async

pursuit 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_review

pursuit 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).

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 [--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 check
pursuit links --fields company,title,status,detail

Events, tags, fields, standing answers

  • pursuit events list|add — timeline events per application; pursuit events --follow --timeout 25s long-polls for the next one.
  • pursuit tags list|create|delete
  • pursuit 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 /authorize page and listens on 127.0.0.1 for 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 the approve scope and is audited as oauth.approve or oauth.deny. The new token has read and write by default, or --scope read. It never has approve: --scope approve exits 2 and the server answers invalid_scope.
  • pursuit auth status — server, user, scopes, and where the token came from (flag, env, config, or the stored file/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 are read, write (includes read), approve (includes read, not write). New tokens are read-only unless scopes are passed.
  • pursuit audit list
  • pursuit 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 json

Markdown 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
Last updated on