npm package: @loftyai/lofty-cli
Description: CLI for the Lofty CRM API - manage leads, agents, listings, tasks, and more
Latest version: 0.3.23

# lofty-cli

CLI for the [Lofty CRM](https://www.lofty.com) API. Made with [api2cli.dev](https://api2cli.dev).


## Install

```bash
npm i @loftyai/lofty-cli
```

## Authentication
/
lofty-cli supports multiple authentication methods with automatic priority fallthrough. Choose the one that fits your use case.

### Method 1: Token URL (CI/CD & Automation — Highest Priority)

For automated environments where you exchange a session ID for tokens via a custom endpoint. Set two env vars; tokens are fetched and cached automatically.

```bash
export LOFTY_TOKEN_URL="https://your-auth-server.com/api/token"
export LOFTY_SESSION_ID="your_session_id"
```

To explicitly fetch and verify:

```bash
lofty-cli auth login-session
# Or with inline flags (overrides env vars):
lofty-cli auth login-session --tokenurl https://... --sessionid your_session_id
```

Tokens are cached in `~/.config/tokens/lofty-session-cache.json` and refreshed automatically when expired.

### Method 2: Browser Authorization (Recommended for humans)

The simplest way to authenticate — open a browser, log in, and you're done.

```bash
lofty-cli auth login-browser
```

The browser opens the Lofty login page. After you log in and authorize, the CLI saves the token locally and auto-refreshes it when it expires.

### Method 3: OAuth2 Client Credentials

For server-to-server integrations. Requires three credentials.

#### Step 1: Configure vendor credentials

```bash
export LOFTY_CLIENT_ID="your_client_id"
export LOFTY_CLIENT_SECRET="your_client_secret"
```

> Register a developer account at [Lofty Vendor Portal](https://api.lofty.com/vendor/frontend/static/index.html#/login) to obtain these.

#### Step 2: Configure customer key

Option A — Environment variable:

```bash
export LOFTY_CUSTOMER_KEY="eyJhbGciOiJIUzI1NiJ9..."
```

Option B — Save to local file:

```bash
lofty-cli auth set "eyJhbGciOiJIUzI1NiJ9..."
```

> Log in to Lofty CRM → **Settings > Integrations > API** to find your Customer Key.

### Method 4: Direct Access Token

If you already have an `access_token` (e.g., from CI/CD or another system):

```bash
export LOFTY_ACCESS_TOKEN="your_access_token"
export LOFTY_REFRESH_TOKEN="your_refresh_token"
```

### Verify Authentication

```bash
lofty-cli auth status   # Show authentication status (all levels)
lofty-cli auth test     # Verify with a real API call
```

## Environment Variables

| Variable | Required | Description |
|---|---|---|
| `LOFTY_TOKEN_URL` | For Token URL mode | Endpoint to exchange session ID for tokens |
| `LOFTY_SESSION_ID` | For Token URL mode | Session ID sent to `LOFTY_TOKEN_URL` |
| `LOFTY_ACCESS_TOKEN` | No | Direct access token (skips other auth methods) |
| `LOFTY_REFRESH_TOKEN` | No | Refresh token (used with `LOFTY_ACCESS_TOKEN`) |
| `LOFTY_CLIENT_ID` | For OAuth mode | Vendor client ID |
| `LOFTY_CLIENT_SECRET` | For OAuth mode | Vendor client secret |
| `LOFTY_CUSTOMER_KEY` | For OAuth mode | User's customer key |
| `LOFTY_BASE_URL` | No | Override API base URL (default: `https://api.lofty.com`) |

## Usage

```bash
# View all available resources
lofty-cli --help

# Examples
lofty-cli leads list
lofty-cli leads list --key "John Smith" --json  # fuzzy search by name, phone, or email
lofty-cli leads list --return-fields "leadId,firstName,stage" --json  # reduce response to specific fields
lofty-cli leads get --id "lead_id"
lofty-cli leads create --body '{"first_name":"John","last_name":"Doe"}'

lofty-cli transaction list
lofty-cli communication list
lofty-cli tasks-appointments-v2 list --lead-id "lead_id"
lofty-cli calendar-v2 list --lead-id "lead_id"
```

> **Note:** The `tasks` resource is deprecated. Use `tasks-appointments-v2` for task/appointment management and `calendar-v2` for calendar/meeting management instead.

## Resources

| Resource | Description |
|---|---|
| `leads` | Lead management (list, get, create, update, delete, etc.) |
| `transaction` | Transaction/deal management |
| `communication` | Email, SMS, and communication logs |
| `tasks-appointments-v2` | Task & appointment management (replaces `tasks`) |
| `calendar-v2` | Calendar event & meeting slot management |
| `notes` | Note management |
| `calls` | Call records |
| `alerts` | Alert/notification management |
| `members` | Team member management |
| `listings` | Property listing management |
| `webhooks` | Webhook management |
| `lead-routing` | Lead routing/assignment rules |
| `team-features` | Team feature toggles |
| `agent-org` | Agent organization management |
| `agent-user` | Agent user management |
| `log-type` | Log type definitions |
| `system-logs` | System audit logs |
| `opportunity` | Opportunity management |
| `vendor` | Vendor management |
| `listing-v2` | Property listing search (V2 API) |
| `lead-activity-v2-api` | Lead activity feed (V2 API) |

Run `lofty-cli <resource> --help` for detailed commands and options.

## Auth Commands

| Command | Description |
|---|---|
| `lofty-cli auth login-session` | Fetch and cache token via Token URL + Session ID |
| `lofty-cli auth login-browser` | Authorize via browser (OAuth PKCE) |
| `lofty-cli auth login` | Manually obtain OAuth access_token |
| `lofty-cli auth set <key>` | Save customer key to local file |
| `lofty-cli auth show` | Display current customer key (masked) |
| `lofty-cli auth show --raw` | Display full customer key |
| `lofty-cli auth remove` | Delete customer key and OAuth cache |
| `lofty-cli auth logout` | Clear all credentials (Token URL cache, PKCE, OAuth cache, customer key) |
| `lofty-cli auth status` | Show authentication status overview (all levels) |
| `lofty-cli auth test` | Verify auth by making a test API call |

## Update Notifications

lofty-cli checks for new versions in the background (at most once every 24 hours). If a newer version is available, a one-line upgrade hint is shown:

```
Update available: 0.3.1 → 0.4.0
Run: npm install -g @loftyai/lofty-cli
```

## Global Flags

All commands support:

| Flag | Description |
|---|---|
| `--json` | Output as JSON |
| `--format <type>` | Output format: `text`, `json`, `csv`, `yaml` |
| `--verbose` | Enable verbose/debug logging |
| `--no-color` | Disable colored output |
| `--no-header` | Omit table headers |

### Boolean Flags

Flags shown as `--flag <bool>` in `--help` require an explicit `true` or `false` string value:

```bash
lofty-cli leads list --contacted true    # filter to contacted leads
lofty-cli leads list --contacted false   # filter to non-contacted leads
```

Omitting the flag uses the API's default behavior. Boolean flags do **not** use `--no-flag` syntax.

### Return Fields (leads list)

Use `--return-fields` to reduce the API response to only the fields you need. This sends the `returnFields` parameter to the API and filters the response client-side.

```bash
lofty-cli leads list --return-fields "leadId,firstName,stage" --json   # 5 keys instead of 61
lofty-cli leads list --return-fields "leadId,firstName,address" --json # address expands to 4 fields
```

Available field names (mapped to API paths automatically):

| CLI Field | Response Keys | Description |
|-----------|--------------|-------------|
| `leadId` | leadId, leadUserId | Lead identifiers |
| `firstName` | firstName | First name |
| `lastName` | lastName | Last name |
| `email` | emails | Email list |
| `phone` | phones | Phone list |
| `stage` | stage, stageId | Pipeline stage |
| `source` | source, leadSource | Lead source |
| `score` | score | Lead score |
| `tags` | tags | Tag list |
| `createTime` | createTime | Creation time |
| `assignedUser` | assignedUserId, assignedUser | Assigned agent |
| `lastTouch` | lastTouch | Last interaction |
| `groups` | groups | Office groups |
| `segments` | segments | Segments |
| `address` | streetAddress, city, state, zipCode | Full address (4 fields) |
| `birthday` | birthday | Birthday |
| `leadType` | leadType, leadTypes | Lead type |
| `assignTime` | assignTime | Assignment time |
| `lastUpdateTime` | lastUpdateTime | Last update time |
| `customAttributes` | customAttributes | Custom fields |
| `inquiry` | leadInquiry | Buyer inquiry |
| `property` | leadPropertyList | Property list |
| `family` | leadFamilyMemberList | Family members |

Unmapped field names are passed through as `data.lead.{name}` automatically.

### Other Filter Flags (leads list)

`leads list` supports 37 advanced filter flags that map to `LeadFilter` fields. They are assembled into the `otherFilters` JSON query parameter at runtime.

```bash
# Buyer leads with a phone number, never contacted
lofty-cli leads list --lead-types "2" --has-phone-state 1 --never-touched true --json

# Leads registered in 2024 with price range 500K–1M
lofty-cli leads list --reg-start-time "2024-01-01" --reg-end-time "2024-12-31" \
  --min-price 500000 --max-price 1000000 --json

# Include deleted seller leads
lofty-cli leads list --lead-types "1" --with-trash true --json
```

| Category | Flags |
|----------|-------|
| Bool/toggle | `--never-touched`, `--never-reply`, `--with-new`, `--with-trash`, `--today-new-lead`, `--today-opportunities` |
| Contact state | `--has-phone-state` (0/1/-1), `--has-email-state`, `--is-phone-valid`, `--is-email-valid`, `--has-bounced-email`, `--email-opened`, `--has-mailing-address` |
| Task/alert | `--has-task-type` (0=none,1=today,2=overdue), `--has-listing-alert`, `--has-market-report` |
| Subscription | `--subscribe-smart-plan`, `--subscribe-alert`, `--subscribe-market-report`, `--email-opt-in`, `--call-opt-in`, `--text-opt-in` |
| Price | `--min-price`, `--max-price` |
| Touch/reply | `--start-day`, `--end-day`, `--reply-start-day`, `--reply-end-day` |
| Score/property | `--revaluate-score-min`, `--revaluate-score-max`, `--min-bedrooms`, `--min-bathrooms` |
| Time (auto-parsed) | `--reg-start-time`, `--reg-end-time` (ISO8601 or epoch ms) |
| List | `--lead-types` (1=Sale,2=Buy,5=Renter,6=Investor…), `--lead-sources` (2=Website,4=Zillow…), `--property-types` |

Run `lofty-cli leads list --help` for full descriptions and enum values.