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

@sendly/cli

v3.37.0

Published

Sendly CLI - Send SMS from your terminal

Downloads

384

Readme

@sendly/cli

Official command-line interface for the Sendly SMS API.

Installation

# npm
npm install -g @sendly/cli

# or Homebrew (macOS / Linux)
brew install SendlyHQ/tap/sendly

Staying up to date

The CLI checks npm once a day and prints a one-line banner after your command if a newer version is out. Run sendly upgrade to update — it auto-detects your install path (Homebrew vs npm) and runs the right command. Use sendly upgrade --check to see what it would do without executing.

Banner is silent in CI (CI=true) and offline-safe.

Quick Start

# Login to your Sendly account
sendly login

# Send an SMS
sendly sms send --to "+15551234567" --text "Hello from Sendly CLI!"

# Check your credit balance
sendly credits balance

Authentication

The CLI supports two authentication methods:

Browser Login (Recommended)

sendly login

This opens your browser to authenticate via Sendly's secure login flow. After authorization, your credentials are stored locally.

API Key Login

sendly login --api-key sk_test_v1_your_key

Or interactively:

sendly login -i

Check Authentication Status

sendly whoami

Logout

sendly logout

Commands

SMS Commands

Send a Message

sendly sms send --to "+15551234567" --text "Hello!"

# Send from a number you own (E.164) — see Numbers Commands below
sendly sms send --to "+15551234567" --text "Hello!" --from "+447111111111"

# Or an alphanumeric sender ID (international)
sendly sms send --to "+447700900000" --text "Hello!" --from "MyBrand"

List Messages

sendly sms list

# Filter by status
sendly sms list --status delivered

# Limit results
sendly sms list --limit 10

Get Message Details

sendly sms get msg_abc123

Send Batch Messages

# From a JSON file
sendly sms batch --file messages.json

# From a CSV file (phone-only with shared text)
sendly sms batch --file phones.csv --text "Your order is ready!"

# Multiple recipients inline
sendly sms batch --to "+15551234567,+15559876543" --text "Hello everyone!"

# Preview before sending (dry run) - validates without sending
sendly sms batch --file messages.json --dry-run

# Dry run output includes:
# - Per-country breakdown with credit costs
# - Blocked messages and reasons
# - Your messaging access (domestic/international)
# - Credit balance check

Send a Group MMS

Send to 2-8 recipients (US & Canada only) in a single group thread — everyone sees the group and replies fan out to all participants. Group messaging is an A2P 10DLC capability, so the sending number must be an MMS-enabled, 10DLC-registered number you own (omit --from to use your default sender).

sendly sms group --to "+14155551234,+14155555678" --text "Team sync at noon?"

# Attach media
sendly sms group --to "+14155551234,+14155555678" --media-url https://example.com/flyer.jpg

# Marketing (applies quiet-hours rules; group MMS defaults to transactional)
sendly sms group --to "+14155551234,+14155555678" --text "Sale!" --type marketing

Schedule a Message

sendly sms schedule --to "+15551234567" --text "Reminder!" --at "2025-12-25T10:00:00Z"

List Scheduled Messages

sendly sms scheduled

Cancel a Scheduled Message

sendly sms cancel sched_abc123

Numbers Commands

Buy international phone numbers and send from them. (US & Canada use toll-free verification instead — they can't be bought.)

Search Available Numbers

sendly numbers search --country GB --type mobile

Buy a Number

sendly numbers buy --country GB --type mobile

The buy is asynchronous: the number starts as provisioning and becomes active once the carrier confirms it. Some countries need documents or business details first — you'll get a hosted link to complete them. See How to buy a number.

List Your Numbers

sendly numbers list

Pass the phoneNumber of any active number as --from on a send to send from it (see Send from a number you own):

sendly sms send --to "+15551234567" --text "Hi!" --from "+447111111111"

Show a Number

sendly numbers get num_abc123

Includes whether it's your workspace default sender and any scheduled release.

Update a Number

Make a number your default sender, or cancel a scheduled release. At least one of --default / --keep is required:

# Make this number the workspace default sender (must be active)
sendly numbers update num_abc123 --default

# Cancel a scheduled release and keep the number
sendly numbers update num_abc123 --keep

Release a Number

sendly numbers release num_abc123

Paid purchases are scheduled to release at the end of the billing period (undo with sendly numbers update <id> --keep); everything else releases immediately. Add --yes to skip the confirmation prompt.

10DLC Commands

Register your brand and messaging campaigns for carrier review so you can send from US local (10-digit) numbers. The flow is brand → qualify → campaign → assign number. Requires a live API key.

Register a Brand

sendly 10dlc brands create --legal-name "Acme Inc" --ein "12-3456789" --website https://acme.com

Check Brand Status

Carrier review starts as pending and becomes verified (or failed). Running get refreshes the status:

sendly 10dlc brands list
sendly 10dlc brands get <brandId>

Qualify a Use Case

Pre-check that a use case is accepted for your brand before creating a campaign:

sendly 10dlc qualify <brandId> MIXED

Create a Campaign

Once the brand is verified:

sendly 10dlc campaigns create \
  --brand <brandId> \
  --use-case MIXED \
  --description "Order updates and promotions" \
  --message-flow "Customers opt in at checkout" \
  --sample "Your order has shipped!" \
  --sample "20% off this weekend"

Poll until the campaign is active:

sendly 10dlc campaigns get <campaignId>

Assign a Number

Attach a US local number you own to the active campaign to make it sendable:

sendly 10dlc campaigns assign <campaignId> --number "+15551234567"
sendly 10dlc assignments list

Then send from it:

sendly sms send --to "+15559876543" --text "Hi!" --from "+15551234567"

API Key Commands

List API Keys

sendly keys list

Create a New Key

sendly keys create --name "Production Key" --type live

Revoke a Key

sendly keys revoke key_abc123

Rotate a Key

Generate a replacement key while keeping the old one valid for a grace period (24-168 hours, default 24), so you can roll deployments over before the old key expires:

sendly keys rotate key_abc123

# Keep the old key alive for 48 hours
sendly keys rotate key_abc123 --grace-period 48 --yes

The new sk_… secret is shown once — store it immediately.

Credit Commands

Check Balance

sendly credits balance

Output includes:

  • Current balance
  • Reserved credits
  • Estimated messages remaining

View Transaction History

sendly credits history

# Limit results
sendly credits history --limit 20

Webhook Commands

List Webhooks

sendly webhooks list

Listen for Webhooks Locally

Start a local tunnel to receive webhook events during development (similar to Stripe CLI):

sendly webhooks listen

# Forward to a specific URL
sendly webhooks listen --forward http://localhost:3000/webhook

# Listen for specific events
sendly webhooks listen --events message.delivered,message.failed

This creates a secure tunnel and displays:

  • Tunnel URL
  • Webhook secret for signature verification
  • Real-time event stream

Create Webhook

sendly webhooks create --url https://myapp.com/webhook --events message.delivered,message.failed

# With description and mode
sendly webhooks create \
  --url https://myapp.com/webhook \
  --events message.delivered,message.failed,message.bounced \
  --description "Production webhook" \
  --mode live

Get Webhook Details

sendly webhooks get whk_abc123

Update Webhook

sendly webhooks update whk_abc123 --url https://newdomain.com/webhook

# Update events
sendly webhooks update whk_abc123 --events message.delivered,message.bounced

# Disable webhook
sendly webhooks update whk_abc123 --active false

Delete Webhook

sendly webhooks delete whk_abc123

# Skip confirmation
sendly webhooks delete whk_abc123 --yes

Test Webhook

sendly webhooks test whk_abc123

View Delivery History

sendly webhooks deliveries whk_abc123

# Show only failed deliveries
sendly webhooks deliveries whk_abc123 --failed-only --limit 20

Rotate Webhook Secret

sendly webhooks rotate-secret whk_abc123

Note: Old secret remains valid for 24 hours during migration.

Verification (OTP) Commands

Send OTP

sendly verify send --to "+15551234567"

# With custom app name
sendly verify send --to "+15551234567" --app-name "MyApp"

# With template
sendly verify send --to "+15551234567" --template tpl_preset_2fa

# Custom code length and timeout
sendly verify send --to "+15551234567" --code-length 6 --timeout 300

Check OTP Code

sendly verify check ver_abc123 --code 123456

Get Verification Status

sendly verify status ver_abc123

List Recent Verifications

sendly verify list

# Limit results
sendly verify list --limit 10

Resend OTP

sendly verify resend ver_abc123

Template Commands

List Templates

sendly templates list

Get Template Details

sendly templates get tpl_abc123

# Get a preset template
sendly templates get tpl_preset_2fa

Create Template

sendly templates create --name "My OTP" --text "Your code is {{code}}"

Supported variables: {{code}}, {{app_name}}

Publish Template

sendly templates publish tpl_abc123

Delete Template

sendly templates delete tpl_abc123

# Skip confirmation
sendly templates delete tpl_abc123 --force

List Preset Templates

sendly templates presets

Link Commands (URL Shortening)

Mint branded, owned-domain short links for your destination URLs. Branded short links improve deliverability (carriers filter public shorteners) and give you per-link click analytics. URL shortening is gated behind the url_shortener rollout flag — until it's enabled for your account these commands return not_enabled.

Create a Short Link

sendly links create https://example.com/spring-sale

List Your Short Links

Newest first, with click counts:

sendly links list

# Paginate
sendly links list --limit 20 --offset 20

Disable / Re-enable a Short Link

The per-link kill switch — a disabled link's redirect returns 404:

sendly links disable Ab3xY7

# Re-enable
sendly links disable Ab3xY7 --enable

Logs Commands

Tail Logs

Stream real-time API activity:

sendly logs tail

# Filter by status
sendly logs tail --status error

Configuration Commands

Get Configuration Value

sendly config get baseUrl

Set Configuration Value

sendly config set baseUrl https://sendly.live

List All Configuration

sendly config list

Diagnostics

Run diagnostics to check your setup:

sendly doctor

This checks:

  • Authentication status
  • API connectivity
  • Configuration validity
  • Network issues

Utility Commands

Account Status Dashboard

sendly status

Shows account overview including:

  • Verification status and tier
  • Credit balance
  • Active API keys and webhooks
  • Recent messages

Trigger Test Event

For testing with webhooks listen:

sendly trigger message.delivered
sendly trigger message.bounced

Environment Variables

Override CLI configuration with environment variables:

| Variable | Description | |----------|-------------| | SENDLY_API_KEY | API key for authentication | | SENDLY_BASE_URL | API base URL (default: https://sendly.live) | | SENDLY_OUTPUT_FORMAT | Output format: text or json | | SENDLY_NO_COLOR | Disable colored output | | SENDLY_TIMEOUT | Request timeout in milliseconds | | SENDLY_MAX_RETRIES | Maximum retry attempts |

Output Formats

Text (Default)

Human-readable formatted output with colors.

JSON

Machine-readable JSON output for scripting:

sendly sms list --json
sendly credits balance --json

CI/CD Usage

For non-interactive environments:

# Set API key via environment variable
export SENDLY_API_KEY=sk_live_v1_your_key

# Or pass directly
sendly sms send --api-key sk_live_v1_your_key --to "+15551234567" --text "Hello!"

# Use JSON output for parsing
sendly credits balance --json | jq '.balance'

Configuration Storage

Configuration is stored in:

  • macOS/Linux: ~/.sendly/config.json
  • Windows: %USERPROFILE%\.sendly\config.json

Webhook Signature Verification

When using sendly webhooks listen, verify signatures in your app:

import crypto from 'crypto';

function verifyWebhook(payload, signature, secret) {
  const expectedSig = 'v1=' + crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSig)
  );
}

Requirements

Documentation

Support

License

MIT