Skip to content

bentonow/bento-cli

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

134 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Bento CLI

Command-line interface for Bento email marketing. Manage subscribers, tags, events, and broadcasts directly from your terminal.

npm version License: MIT

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-cli

Tip: Using npx is 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 user@example.com
bento tags list

Authentication

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 logout

Multiple 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 staging

Credentials 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 --json

Subscribers

# Look up a subscriber
bento subscribers search --email user@example.com

# Look up + check if they have a tag
bento subscribers search --email user@example.com --tag vip

# Look up + check field value
bento subscribers search --email user@example.com --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 user@example.com --add vip
bento subscribers tag --email user@example.com --remove trial
bento subscribers tag --file users.csv --add customer,active --confirm

# Unsubscribe (stop email delivery)
bento subscribers unsubscribe --email user@example.com
bento subscribers unsubscribe --file unsubscribes.csv --confirm

# Re-subscribe (restore email delivery)
bento subscribers subscribe --email user@example.com

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_size

Events

Track custom events to trigger automations:

# Track a simple event
bento events track --email user@example.com --event signed_up

# Track with details
bento events track \
  --email user@example.com \
  --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.html

Maintainer release order for this feature:

  1. Ship the API endpoint in bento.
  2. Publish a bento-node-sdk version that includes createSequenceEmail.
  3. Release bento-cli against that SDK version.

Current API limitation: sequence email updates support subject and html fields only.

Statistics

# View site-wide stats
bento stats site

Output 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 user@example.com

# JSON for scripting
bento subscribers search --email user@example.com --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 --confirm

Environment 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
alice@example.com,Alice,Smith,pro
bob@example.com,Bob,Jones,starter

Import with inline tag assignment:

email,name,tags,remove_tags,company
jesse@example.com,Jesse Hanley,"customer,mql",lead,Acme Inc
alice@example.com,Alice Smith,"newsletter,active",,Widgets Co

For Email Lists (tag/unsubscribe operations)

A simple CSV with an email column:

email
alice@example.com
bob@example.com

Or a plain text file with one email per line (no header needed):

alice@example.com
bob@example.com

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 --json

Scripting: 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 user@example.com --tag inactive --json \
  | jq -r '.data[].email' \
  | while read email; do
      bento subscribers tag --email "$email" --add "needs-reengagement" --confirm
    done

Automation: Track events from webhooks

# In your webhook handler
curl -X POST https://your-server.com/webhook -d '{"email": "user@example.com", "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 format

Claude 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-cli

Alternatively, 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 --confirm flags
  • Anti-patterns: Common mistakes to avoid with bulk operations
  • Workflows: CI/CD integration, scripting patterns, safe import validation

Requirements

  • Runtime: Bun >= 1.0.0 or Node.js >= 18
  • Bento Account: Sign up if you don't have one

Support

License

MIT License - see LICENSE for details.


Built with love by the Bento team.

About

🍱 Bento CLI

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 100.0%