npm package: @gener8v/loc8n-cli
Description: Command-line interface for the loc8n geographic data API
Latest version: 0.1.1

# loc8n

Command-line interface for the [loc8n](https://loc8n.com) geographic data API.

Look up ZIP codes, demographics, boundaries, mortgage data, employment stats, migration flows, and more — directly from your terminal.

## Install

```bash
npm install -g loc8n
```

Requires **Node.js 20+**.

## Quick start

```bash
# Authenticate
loc8n auth login

# Look up a ZIP code
loc8n zip lookup 22903

# Search ZIPs by city
loc8n zip by-city -c Austin -s TX

# Get demographics
loc8n demographics lookup 22903 --category income

# Reverse geocode
loc8n geocode reverse --lat 38.0293 --lon -78.4767

# Pipe JSON to another tool
loc8n zip search --state VA --limit 100 --json | jq '.[].city'
```

## Authentication

```bash
loc8n auth login              # Prompt for API key
loc8n auth login gd_mykey123  # Pass key directly
```

API key resolution order:

1. `--api-key` flag
2. `LOC8N_API_KEY` environment variable
3. Active profile in config file

Config is stored at `$XDG_CONFIG_HOME/loc8n/config.json` (default `~/.config/loc8n/config.json`).

### Profiles

```bash
loc8n auth login --profile staging    # Create named profile
loc8n auth switch staging             # Switch active profile
loc8n auth list                       # List all profiles
loc8n auth remove staging             # Delete a profile
loc8n auth logout                     # Remove key from active profile
```

## Output formats

| Flag        | Format  | Default when         |
| ----------- | ------- | -------------------- |
| _(none)_    | table   | Interactive terminal |
| _(none)_    | json    | Piped / redirected   |
| `--json`    | JSON    | Explicit             |
| `--csv`     | CSV     | Explicit             |
| `--geojson` | GeoJSON | Explicit             |

Format is also inferred from file extension when using `-o`:

```bash
loc8n zip search --state VA -o results.csv    # Outputs CSV
loc8n zip search --state VA -o results.json   # Outputs JSON
```

### Output options

```bash
--fields zip,city,state    # Select specific fields
--compact                  # Minified JSON
--no-header                # Omit table/CSV header row
-q, --quiet                # Data only, no metadata
-o, --output <file>        # Write to file instead of stdout
```

## Commands

### zip

ZIP code lookups, search, and distance tools.

```bash
loc8n zip lookup <code>
loc8n zip search [-s state] [-c city] [--county name] [--type standard|po_box|unique]
loc8n zip by-city -c <city> -s <state>
loc8n zip by-coords --lat <lat> --lon <lon> [--limit 5]
loc8n zip distance <from> <to> [--unit miles|kilometers] [--method haversine|vincenty]
loc8n zip radius <code> --radius <miles> [--unit miles|km] [--sort distance|zip] [--limit 100]
loc8n zip batch [codes...] [--file path]
loc8n zip matrix --origins <zips> --destinations <zips> [--unit miles|km]
```

**Fields:** `zip`, `city`, `state`, `county`, `type`, `latitude`, `longitude`, `timezone`, `areaCode`, `landArea`, `waterArea`

### demographics

Demographic data by ZIP, area, or block group.

```bash
loc8n demographics lookup <zip> [--year] [--category population|income|housing|education|employment|households]
loc8n demographics area <type> <code> [--year] [--category]
loc8n demographics compare <codes...> [--type] [--year] [--category]     # Max 10
loc8n demographics aggregate <zips...> [--method sum|average|weighted]    # Max 100
loc8n demographics trend <code> [--type] [--start-year] [--end-year]
loc8n demographics changes <code> [--type] [--year]
loc8n demographics years
loc8n demographics block-group <geoid>    # 12-digit GEOID
```

**Fields:** `zip`, `geoid`, `areaType`, `name`, `year`, `population`, `medianAge`, `medianIncome`, `perCapitaIncome`, `medianHomeValue`, `medianRent`, `homeOwnershipRate`, `vacancyRate`, `povertyRate`, `bachelorsDegreeRate`, `unemploymentRate`, `householdSize`, `totalHouseholds`

### geocode

Forward and reverse geocoding.

```bash
loc8n geocode address <address> [--limit] [--country]
loc8n geocode reverse --lat <lat> --lon <lon>
loc8n geocode validate <address>
loc8n geocode batch [addresses...] [--file path]
```

**Fields:** `formattedAddress`, `latitude`, `longitude`, `confidence`, `city`, `state`, `zip`, `county`, `country`

### boundaries

Geographic boundary data (GeoJSON).

```bash
loc8n boundaries zip <code> [--tolerance 0.0001-0.1]
loc8n boundaries county <fips> [--tolerance]
loc8n boundaries state <code> [--tolerance]
loc8n boundaries containing --lat <lat> --lon <lon> [--types zip,county,state]
loc8n boundaries contains --lat <lat> --lon <lon> --type <type> --id <id>
loc8n boundaries intersecting --type <type> --file <geojson>
```

### locations

Manage saved locations.

```bash
loc8n locations list [--type] [--tags] [--active|--inactive] [--sort] [--order] [--limit] [--page]
loc8n locations get <id>
loc8n locations create --name <name> --lat <lat> --lon <lon> [--type] [--tags] [--address] [--zip]
loc8n locations update <id> [--name] [--lat] [--lon] [--type] [--tags] [--address] [--zip]
loc8n locations delete <id> [--force]
loc8n locations nearby --lat <lat> --lon <lon> --radius <r> [--unit miles|km] [--limit]
loc8n locations search <query> [--limit]
loc8n locations bulk-create --file <path>       # JSON array, max 100
loc8n locations bulk-delete --ids <ids> [--force]
```

**Fields:** `id`, `name`, `latitude`, `longitude`, `type`, `tags`, `address`, `zip`, `city`, `state`, `active`, `createdAt`, `updatedAt`

### market

Fair Market Rent and housing market data.

```bash
loc8n market fmr zip <code> [--year]
loc8n market fmr county <fips> [--year]
loc8n market fmr metro <code> [--year]
loc8n market fmr state <code> [--year]
loc8n market trend <zip|county|metro|state> <code> [--start-year] [--end-year]
```

**Fields:** `areaType`, `code`, `name`, `year`, `efficiency`, `oneBedroom`, `twoBedroom`, `threeBedroom`, `fourBedroom`

### migration

IRS migration flow data.

```bash
loc8n migration county <fips> [--year]
loc8n migration state <code> [--year]
loc8n migration inflows <code> [--type county|state] [--year] [--limit] [--sort count|percentage]
loc8n migration outflows <code> [--type county|state] [--year] [--limit] [--sort count|percentage]
loc8n migration trend <code> [--type county|state] [--start-year] [--end-year]
loc8n migration years
```

### hmda

Mortgage lending data (Home Mortgage Disclosure Act).

```bash
loc8n hmda tract <geoid> [--year]       # 11-digit GEOID
loc8n hmda county <fips> [--year]
loc8n hmda state <code> [--year]
loc8n hmda trend <tract|county|state> <code> [--start-year] [--end-year]
loc8n hmda years
```

**Fields:** `areaType`, `code`, `name`, `year`, `applicationCount`, `originationCount`, `denialCount`, `denialRate`, `medianLoanAmount`, `medianInterestRate`, `medianPropertyValue`, `medianBorrowerIncome`, `purchasePct`, `refinancePct`

### employment

LODES employment data.

```bash
loc8n employment tract <geoid> [--perspective workplace|residence] [--year]
loc8n employment county <fips> [--perspective] [--year]
loc8n employment state <code> [--perspective] [--year]
loc8n employment inflows <code> [--type tract|county|state] [--year] [--limit]
loc8n employment outflows <code> [--type tract|county|state] [--year] [--limit]
loc8n employment compare <codes...> [--type] [--perspective] [--year]    # 2-10 codes
loc8n employment trend <type> <code> [--perspective] [--start-year] [--end-year]
```

### areas

Search for geographic areas.

```bash
loc8n areas search <query> [--type zip,county,state,cbsa,place] [--state] [--limit]
```

**Fields:** `code`, `name`, `type`, `state`

### whoami

```bash
loc8n whoami          # Text output
loc8n whoami --json   # JSON output
```

Shows current profile and validates your API key.

## Global options

```
--api-key <key>      API key (overrides profile/env)
--profile <name>     Use a specific profile
--json               Force JSON output
--csv                Force CSV output
--geojson            Force GeoJSON output
-o, --output <file>  Write to file
-v, --verbose        Show HTTP request/response details
-q, --quiet          Data only, no metadata
--fields <fields>    Comma-separated field list
--compact            Minified JSON
--no-tty             Force non-interactive mode
--no-header          Suppress table/CSV headers
```

## Batch operations

Commands that accept multiple inputs (`zip batch`, `geocode batch`, `locations bulk-create`) support three input methods:

```bash
# Arguments
loc8n zip batch 22903 10001 90210

# File
loc8n zip batch --file zips.txt

# Stdin
cat zips.txt | loc8n zip batch
```

Input files can be plain text (one per line), CSV, or JSON arrays. Format is auto-detected.

Progress is reported to stderr; data goes to stdout — safe for piping.

## Environment variables

| Variable                 | Description                                     |
| ------------------------ | ----------------------------------------------- |
| `LOC8N_API_KEY`          | API key (overrides profile config)              |
| `LOC8N_API_URL`          | Base API URL (default: `https://api.loc8n.com`) |
| `LOC8N_MAX_RETRIES`      | Max retry attempts (default: 3)                 |
| `LOC8N_RETRY_BACKOFF_MS` | Base backoff in ms (default: 1000)              |

## Retry behavior

The client automatically retries on:

- **429 Too Many Requests** — uses `Retry-After` header with exponential backoff
- **5xx Server Errors** — exponential backoff (1s, 2s, 4s...)

Non-retryable errors (401, 403, 404, 422) fail immediately.

## License

MIT