@bentonow/bento-cli
v0.1.5
Published
Command-line interface for Bento email marketing. Manage subscribers, tags, events, and broadcasts from your terminal.
Maintainers
Readme
Bento CLI
Command-line interface for Bento email marketing. Manage subscribers, tags, events, and broadcasts directly from your terminal.
Installation
# Recommended: Run with npx (always uses latest version)
npx @bentonow/bento-cli --help
# Or install globally
npm install -g @bentonow/bento-cli
# Or with Bun
bun install -g @bentonow/bento-cliTip: Using
npxis recommended when possible—it always fetches the latest version, requires no installation, and is ideal for CI/CD pipelines.
Quick Start
# 1. Authenticate with your Bento credentials
bento auth login
# 2. Verify your connection
bento stats site
# 3. Start managing your subscribers
bento subscribers search --email [email protected]
bento tags listAuthentication
The CLI uses your Bento API credentials. Get them from Settings > Teams in your Bento dashboard.
# Interactive login (prompts for credentials)
bento auth login
# Non-interactive login (for CI/scripts)
bento auth login \
--publishable-key "your-publishable-key" \
--secret-key "your-secret-key" \
--site-uuid "your-site-uuid"
# Or run directly with npx (no install required)
npx @bentonow/bento-cli auth login \
--publishable-key "your-publishable-key" \
--secret-key "your-secret-key" \
--site-uuid "your-site-uuid"
# Check authentication status
bento auth status
# Log out (removes stored credentials)
bento auth logoutMultiple Profiles
Manage multiple Bento accounts (e.g., production, staging):
# Add a named profile
bento profile add production
bento profile add staging
# Switch between profiles
bento profile use staging
# List all profiles
bento profile list
# Remove a profile
bento profile remove stagingCredentials are stored securely at:
- macOS:
~/Library/Application Support/bento/config.json - Linux:
~/.config/bento/config.json - Windows:
%APPDATA%/bento/config.json
Commands
Dashboard
# Open the Bento dashboard for your active profile
bento dashboard
# Target a specific profile
bento dashboard --profile staging
# JSON mode still opens the browser but prints machine-readable output
bento dashboard --jsonSubscribers
# Look up a subscriber
bento subscribers search --email [email protected]
# Look up + check if they have a tag
bento subscribers search --email [email protected] --tag vip
# Look up + check field value
bento subscribers search --email [email protected] --field plan=pro
# Import subscribers from CSV (email column required)
bento subscribers import contacts.csv
bento subscribers import contacts.csv --dry-run # Preview first
bento subscribers import contacts.csv --limit 100 # Import first 100
# Add/remove tags from subscribers
bento subscribers tag --email [email protected] --add vip
bento subscribers tag --email [email protected] --remove trial
bento subscribers tag --file users.csv --add customer,active --confirm
# Unsubscribe (stop email delivery)
bento subscribers unsubscribe --email [email protected]
bento subscribers unsubscribe --file unsubscribes.csv --confirm
# Re-subscribe (restore email delivery)
bento subscribers subscribe --email [email protected]Tags
# List all tags
bento tags list
# Search tags by name
bento tags list news # Fuzzy match on tag name
# Create a new tag
bento tags create "new-feature-announcement"
# Delete a tag (via web interface - API limitation)
bento tags delete "old-tag"Custom Fields
# List all custom fields
bento fields list
# Search fields by key or name
bento fields list company # Fuzzy match on field key + name
# Create a new field
bento fields create company_sizeEvents
Track custom events to trigger automations:
# Track a simple event
bento events track --email [email protected] --event signed_up
# Track with details
bento events track \
--email [email protected] \
--event purchase \
--details '{"product": "Pro Plan", "amount": 99}'Broadcasts
# List all broadcasts
bento broadcasts list
# Paginate results
bento broadcasts list --page 1 --per-page 10
# Notes:
# - `--page` by itself uses Bento's API pagination (25 results per page, minimal memory).
# - Adding `--per-page` tells the CLI to fetch the full list once and slice locally, so prefer
# smaller values here when you have very large broadcast histories.
# Create a broadcast draft
bento broadcasts create \
--name "January Newsletter" \
--subject "What's new this month" \
--content "<h1>Hello!</h1><p>Here's our update...</p>" \
--type html \
--include-tags "newsletter,active"Sequences
# List all sequences
bento sequences list
# Create a sequence email with inline HTML
bento sequences create-email \
--sequence-id sequence_abc123 \
--subject "Welcome to Bento" \
--html "<h1>Hi there</h1>" \
--delay-interval days \
--delay-count 7
# Create from an HTML file
bento sequences create-email \
--sequence-id sequence_abc123 \
--subject "Day 2 follow-up" \
--html-file ./emails/day-2.html
# Update an existing sequence email template
bento sequences update-email \
--template-id 12345 \
--subject "Updated Welcome Subject"
# Update subject + HTML inline
bento sequences update-email \
--template-id 12345 \
--subject "Refined Subject" \
--html "<h1>Updated body</h1>"
# Update HTML from file
bento sequences update-email \
--template-id 12345 \
--html-file ./emails/updated-welcome.htmlMaintainer release order for this feature:
- Ship the API endpoint in
bento. - Publish a
bento-node-sdkversion that includescreateSequenceEmail. - Release
bento-cliagainst that SDK version.
Current API limitation: sequence email updates support subject and html fields only.
Statistics
# View site-wide stats
bento stats siteOutput Modes
| Flag | Description |
|------|-------------|
| (none) | Human-readable tables with colors |
| --json | Machine-readable JSON for scripting |
| --quiet | Minimal output (errors only) |
# Default: pretty tables
bento subscribers search --email [email protected]
# JSON for scripting
bento subscribers search --email [email protected] --json | jq '.data[].email'
# Quiet for automation (exit code only)
bento tags create "test-tag" --quiet && echo "Created!"JSON Response Format
All --json output follows a consistent schema:
{
"success": true,
"error": null,
"data": { ... },
"meta": {
"count": 10,
"total": 100
}
}Safety Features
Bulk operations include safety flags to prevent mistakes:
| Flag | Description |
|------|-------------|
| --dry-run | Preview what would happen without making changes |
| --limit <n> | Only process the first N items |
| --sample <n> | Show N sample items in the preview |
| --confirm | Skip interactive confirmation (for scripts) |
# Preview an import without executing
bento subscribers import big-list.csv --dry-run
# Import only the first 10 rows to test
bento subscribers import big-list.csv --limit 10
# Tag subscribers non-interactively (CI/scripts)
bento subscribers tag --file users.csv --add customer --confirmEnvironment Variables
| Variable | Description |
|----------|-------------|
| BENTO_CONFIG_PATH | Override config file location |
| BENTO_API_BASE_URL | Override API endpoint (for testing) |
| BENTO_AUTO_CONFIRM | Set to true to skip all confirmations |
| DEBUG | Set to bento for verbose SDK logging |
CSV Format
For Subscriber Imports
CSV files must have an email column (case-insensitive). The CLI recognizes these special columns:
| Column | Description |
|--------|-------------|
| email | Required. Subscriber email address |
| name | Optional. Subscriber display name |
| tags | Optional. Tags to add (comma or semicolon separated) |
| remove_tags | Optional. Tags to remove (comma or semicolon separated) |
| (other) | Any other columns become custom fields |
Basic import with custom fields:
email,first_name,last_name,plan
[email protected],Alice,Smith,pro
[email protected],Bob,Jones,starterImport with inline tag assignment:
email,name,tags,remove_tags,company
[email protected],Jesse Hanley,"customer,mql",lead,Acme Inc
[email protected],Alice Smith,"newsletter,active",,Widgets CoFor Email Lists (tag/unsubscribe operations)
A simple CSV with an email column:
email
[email protected]
[email protected]Or a plain text file with one email per line (no header needed):
[email protected]
[email protected]Note: Email lists are automatically deduplicated and normalized to lowercase.
Exit Codes
| Code | Meaning | |------|---------| | 0 | Success | | 1 | General error | | 2 | Invalid arguments or usage | | 6 | CSV parsing error |
Examples
CI/CD: Sync subscribers from your database
#!/bin/bash
# Export active users and sync to Bento
psql -c "COPY (SELECT email, name FROM users WHERE active) TO STDOUT CSV HEADER" \
> /tmp/active-users.csv
# Using npx (no install required)
npx @bentonow/bento-cli subscribers import /tmp/active-users.csv --confirm --json
# Or if installed globally
bento subscribers import /tmp/active-users.csv --confirm --jsonScripting: Tag users based on activity
#!/bin/bash
# Tag users who haven't been active
# Check if a subscriber has the "inactive" tag
bento subscribers search --email [email protected] --tag inactive --json \
| jq -r '.data[].email' \
| while read email; do
bento subscribers tag --email "$email" --add "needs-reengagement" --confirm
doneAutomation: Track events from webhooks
# In your webhook handler
curl -X POST https://your-server.com/webhook -d '{"email": "[email protected]", "event": "purchase"}'
# Handler script
bento events track \
--email "$WEBHOOK_EMAIL" \
--event "$WEBHOOK_EVENT" \
--details "$WEBHOOK_DETAILS"Development
# Clone the repository
git clone https://github.com/bentonow/bento-cli.git
cd bento-cli
# Install dependencies
bun install
# Run CLI locally
bun run dev
# Run tests
bun test
# Lint and format
bun lint
bun formatClaude Code Skill
This repository includes a Claude Code skill that provides guidance for using the Bento CLI. The skill teaches Claude about all available commands, safety patterns, and best practices.
Installing the Skill
To install the bento-cli skill for Claude Code:
# Navigate to your Claude Code skills directory
cd ~/.claude/skills
# Clone the skill (or symlink from your local clone)
git clone https://github.com/bentonow/bento-cli.git bento-cli-repo
ln -s bento-cli-repo/skill bento-cli
# Or copy directly
cp -r /path/to/bento-cli/skill ~/.claude/skills/bento-cliAlternatively, if you're working within the bento-cli repository, the skill is automatically available at skill/SKILL.md.
What the Skill Provides
- Command reference: All CLI commands with options and examples
- Safety-first philosophy: Guidance on
--dry-run,--limit, and--confirmflags - Anti-patterns: Common mistakes to avoid with bulk operations
- Workflows: CI/CD integration, scripting patterns, safe import validation
Requirements
Support
- Documentation: docs.bentonow.com
- Issues: GitHub Issues
- Community: Discord
License
MIT License - see LICENSE for details.
Built with love by the Bento team.
