@loftyai/lofty-cli
v1.0.2
Published
CLI for the Lofty CRM API - manage leads, agents, listings, tasks, and more
Downloads
1,253
Readme
lofty-cli
CLI for the Lofty CRM API. Made with api2cli.dev.
An internal-only variant
lofty-internal-cliexists for Lofty employees. See README.internal.md.
Install
npm i @loftyai/lofty-cliAuthentication
/ 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.
export LOFTY_TOKEN_URL="https://your-auth-server.com/api/token"
export LOFTY_SESSION_ID="your_session_id"To explicitly fetch and verify:
lofty-cli auth login-session
# Or with inline flags (overrides env vars):
lofty-cli auth login-session --tokenurl https://... --sessionid your_session_idTokens 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.
lofty-cli auth login-browserThe 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
export LOFTY_CLIENT_ID="your_client_id"
export LOFTY_CLIENT_SECRET="your_client_secret"Register a developer account at Lofty Vendor Portal to obtain these.
Step 2: Configure customer key
Option A — Environment variable:
export LOFTY_CUSTOMER_KEY="eyJhbGciOiJIUzI1NiJ9..."Option B — Save to local file:
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):
export LOFTY_ACCESS_TOKEN="your_access_token"
# Optional — only used for auto-refresh when a refresh endpoint is configured.
export LOFTY_REFRESH_TOKEN="your_refresh_token"Make sure the token and
LOFTY_API_BASE_URLbelong to the same environment. Method 4 forwardsLOFTY_ACCESS_TOKENas aBearertoken verbatim — the CLI does not validate or re-issue it. A prod-issued token against a test base URL (or vice versa) will keep returning401, and withoutLOFTY_REFRESH_TOKEN+ a refresh endpoint there is no auto-recovery. Default base URL ishttps://api.lofty.com; override viaLOFTY_API_BASE_URL(e.g.https://api-test.lofty.com) to point at another environment.
Verify Authentication
lofty-cli auth status # Show authentication status (all levels)
lofty-cli auth test # Verify with a real API callEnvironment 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 (optional, only used to auto-refresh LOFTY_ACCESS_TOKEN when a refresh endpoint is configured) |
| 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_API_BASE_URL | No | Override API base URL (default: https://api.lofty.com). Must match the environment that issued your token. |
Usage
# 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 list --lead-id "lead_id"
lofty-cli calendar list --lead-id "lead_id"Note: The
tasksresource is deprecated. Usetasks-appointmentsfor task/appointment management andcalendarfor calendar/meeting management instead.
Auto-Injected Detail URLs
For convenience, leads get, leads list, transactions get, and transactions list responses include lead_detail_url and transaction_detail_url fields respectively. These URLs link directly to the corresponding object inside the CRM. The URLs use the current authenticated user's agentUserId, which is cached locally in ~/.config/lofty/me-cache.json. The cache is cleared automatically whenever you run auth login, auth login-browser, auth remove, or auth logout.
Resources
| Resource | Description |
|---|---|
| leads | Lead management (list, get, create, update, delete, etc.) |
| transaction | Transaction/deal management |
| communication | Email, SMS, and communication logs |
| tasks-appointments | Task & appointment management (replaces tasks) |
| calendar | Calendar event & meeting slot management |
| notes | Note management |
| calls | Call records |
| alerts | Alert/notification management |
| members | Team member management |
| listing | Property listing search & management (V1 + V2 APIs combined) |
| 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 |
| notifications | Notification subscriptions (V2 API) |
| sales-agents | Sales agent assignments (V2 API) |
| intelligent-features | Intelligent feature toggles |
| lead-activity | Lead activity feed |
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-cliGlobal 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:
lofty-cli leads list --contacted true # filter to contacted leads
lofty-cli leads list --contacted false # filter to non-contacted leadsOmitting 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.
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 fieldsAvailable 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.
# 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.
