npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@loftyai/lofty-cli

v1.0.2

Published

CLI for the Lofty CRM API - manage leads, agents, listings, tasks, and more

Readme

lofty-cli

CLI for the Lofty CRM API. Made with api2cli.dev.

An internal-only variant lofty-internal-cli exists for Lofty employees. See README.internal.md.

Install

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.

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_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.

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

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_URL belong to the same environment. Method 4 forwards LOFTY_ACCESS_TOKEN as a Bearer token verbatim — the CLI does not validate or re-issue it. A prod-issued token against a test base URL (or vice versa) will keep returning 401, and without LOFTY_REFRESH_TOKEN + a refresh endpoint there is no auto-recovery. Default base URL is https://api.lofty.com; override via LOFTY_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 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 (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 tasks resource is deprecated. Use tasks-appointments for task/appointment management and calendar for 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-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:

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.

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.

# 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.