---
title: "CLI workflows"
description: "End-to-end Bucky CLI recipes — find a place, create projects and assemblies, run lists, assess opportunities, run analysis, chat, and export reports."
last_updated: "2026-10-04"
---

Each recipe below is a sequence of real commands. Add `--json` for scripts and agents,
and run writes with `--dry-run` before `--yes` ([Safe writes](/docs/cli/safe-writes)).

## Find a place

Most workflows start with an address. `geo resolve` is the CLI's only address-to-
coordinates step:

```bash
bucky --json geo resolve "1541 W 12th Ave, Vancouver"
```

It returns `lat`, `lng`, the city's `geoDivisionId`, and whether the city is live and
has parcels. Feed those into the commands below. Leave out `--country` unless you know
it: a wrong country returns the closest match in that country, not an error.

The rest of the `geo` group reads what Bucky knows about that city, or finds cities by
their market:

```bash
bucky --json geo coverage <divisionSlug>     # count-only source coverage
bucky --json geo facts <geoDivisionId>       # place facts with source and period
bucky --json geo places find --market tight-rental --region ON
```

`geo coverage` takes the slug and `geo facts` takes the UUID; `geo resolve` returns
both. A missing fact is absent, not zero, and `geo places find` counts a city missing a
filtered value as unknown rather than a match.

## Projects

```bash
bucky projects list --limit 20
bucky projects get <project-id>
bucky projects create --name "Main Street" --address "12 Main St, Minneapolis" --dry-run
bucky projects update <project-id> --name "Main Street Infill" --dry-run
bucky projects archive <project-id> --dry-run
```

- **With `--address`**, Bucky geocodes the address and links the project to its city.
  An address it can't resolve fails the create.
- **With `--lat`/`--lng`**, the coordinates are saved but the project isn't linked to a
  city or lot. Run `bucky projects location set <project-id> --lat … --lng …` to fix
  that.
- **`--external-ref <system>:<id>`** records where an imported project came from, for
  example `crm:4411`. Creating again with the same ref returns the existing project.
  Find it with `projects list --external-ref crm:4411`.
- `projects archive` is a soft cancel; the project is kept.

Members, invites, share links, and the public map listing are under `projects members`,
`projects invites`, `projects share-links`, and `projects map-listing`.

## Land assembly (multi-parcel projects)

`projects create` makes a single-location project with no parcels. For a site made of
several parcels — a block assembly, a campus, a building plus its parking lot — use
`projects create-assembly`:

```bash
bucky parcels search --lat 45.004744 --lng -93.261962 --radius 120
bucky projects create-assembly --name "Holy Cross Campus" \
  --lat 45.004744 --lng -93.261962 --radius 120 \
  --parcel 1402924210178 --parcel 1402924210122 --dry-run
bucky projects attach-parcels <project-id> \
  --lat 45.004744 --lng -93.261962 --parcel 1402924220152 --role context --dry-run
```

- **The first `--parcel` is the seed lot.** It anchors the project's location. Repeat
  the flag or pass a comma-separated list; duplicates are dropped.
- Every parcel is attached with role `build`. Use `attach-parcels --role context` for
  surrounding parcels you want for context, and `parcels set-role` to change a role.
- **Two modes.** With `--lat`/`--lng`, the CLI looks the parcels up and builds the site
  outline from their geometry, so even a dry run needs you to be signed in. With
  `--input`, you supply `geoDivisionId`, `polygon`, and `parcelExternalIds` yourself;
  that's the only way to commit a non-rectangular outline.
- **Not idempotent.** A resend creates a second project, so the CLI never retries it.
  After an unknown outcome, run `projects list` and archive any duplicate.
  `bucky undo <receipt-id>` reverses a completed assembly.

Track each lot in the deal with `parcels list` and `parcels deal` (status, notes, and
asking price), and remove one with `parcels detach`. `parcels search` never returns owner
names. `parcels ownership` returns record owners for lots in your project when your plan
includes them ([Parcels](/docs/platform/parcels)).

## Buy boxes and screening

A list is a [saved search](/docs/platform/saved-searches): criteria for one city.

```bash
# 1. Find the city id
bucky --json geo resolve "Vancouver, BC"

# 2. See what this city can filter on (zone codes, neighbourhoods, overlays)
bucky --json screen options <division-id>

# 3. Turn a brief into suggested criteria, without saving anything
bucky --json screen propose --division <division-id> \
  --text "pre-1950 houses on 6,000 sf R1-1 lots, land title only"

# 4. Save the box, then count and page through matches
bucky --json screen create --input box.json --dry-run
bucky --json screen create --input box.json --yes
bucky --json screen count <box-id>
bucky --json screen lots <box-id> --limit 50
bucky --json screen lots <box-id> --cursor <nextCursor>
```

A box document looks like this. Lot areas are in **square feet**:

```json
{
  "name": "Pre-1950 R1-1 lots",
  "geoDivisionId": "<division-id>",
  "zoneCodes": ["R1-1"],
  "minAreaSqft": 6000,
  "criteria": {
    "year_built": { "max": 1949 },
    "ownership_form": { "none_of": ["strata_condo", "co_op", "leasehold", "mixed"] }
  }
}
```

- Top-level fields: `name`, `geoDivisionId`, `zoneCodes`, `minAreaSqft`, `maxAreaSqft`,
  `namedAreaIds`, `overlayKinds`, `overlayExcludeKinds`, `minAssessed`, `maxAssessed`,
  and `minHomes`. `minAreaSqm` is rejected, not converted.
- `criteria` holds the newer criteria by key, in stored units (square metres, metres,
  dollars, ratios). Use `screen propose` to get valid keys and values for a city.
- `screen count` returns the match count, the number of stored lots it is out of, the
  filters the city could not apply, and whether the box is broad.
- `screen lots` pages by cursor, 50 lots at most per page.
- `screen create` is not idempotent. Run `screen list` before retrying. `screen update`
  replaces all criteria; `screen delete` removes a box. Both can be undone.

## Opportunities

`opportunities screen` goes further than a list: it screens a city, gathers facts on
the best candidates, evaluates them against a development brief, and ranks them. It
saves the run so you can come back to it.

```bash
bucky --json opportunities screen --input run.json --dry-run
bucky --json opportunities screen --input run.json --yes   # can take minutes
bucky opportunities list
bucky opportunities show <run-id>
bucky opportunities compare <run-id> --ids <a>,<b>,<c>
bucky opportunities review <run-id> <assessment-id> --decision pursue --notes "Call broker"
```

- The input holds a `brief` (your program), `criteria` (a list for one city, with an
  explicit `limit` of 1–10 candidates), and an optional `factsLimit` (1–5).
- It's slow and synchronous. The CLI waits up to 10 minutes unless you set `--timeout`.
  It's never retried and can't be undone; after an unknown outcome, check
  `opportunities list` before running again.
- A screened candidate has passed the checks Bucky implements. It says nothing about
  whether you can buy it, get it approved, or make money on it.
- `review` records a pursue/pass decision. It appends; correct a mistake by recording
  another decision.

## Analysis and reports

```bash
bucky analysis run <project-id> --dry-run
bucky analysis wait <project-id>             # polls up to 10 minutes by default
bucky --json analysis show <project-id>
bucky feasibility preview --lat 49.2606 --lng -123.1433 --wait
bucky reports compose <project-id> --audience investor
bucky reports export <project-id> --out report.pdf --dry-run
```

`analysis run` only queues the analysis; `analysis wait` polls until it is current or
failed. `reports export` downloads a PDF and uses one export from your
[plan](/docs/resources/plans).

## Chat and knowledge

```bash
bucky conversations list --project <project-id> --limit 20
bucky chat turn --project <project-id> --message "Summarize this site" --dry-run
bucky chat turn --project <project-id> --conversation <conversation-id> \
  --message "Continue with the permit risks" --yes
bucky chat resume
bucky knowledge search --q "front setback" --limit 10
bucky references add <project-id> --section <section-id> --dry-run
bucky documents search <project-id> --q "What does the survey say about easements?"
```

Chat is text only: map control stays in the web app. Pass the `nextCursor` from
`conversations list` back through `--cursor` to page. A chat turn is never retried
across runs, because a resend would send the message twice.

## Billing

```bash
bucky billing status
bucky billing credits
bucky billing plans
bucky billing checkout plan <tier-id> --dry-run
bucky billing portal
```

Checkout and portal commands return a link to finish in your browser; the CLI never
takes payment details.


## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
