Effect-powered CLI wrapper around the Kit API v4, with agent-friendly JSON output and launch-ops helpers for broadcast drafts.
curl -fsSL https://raw.githubusercontent.com/badass-courses/kit-cli/main/install.sh | bashThis downloads the latest standalone binary from GitHub Releases and installs:
~/.local/bin/kit
~/.local/bin/kit-cliOptions:
curl -fsSL https://raw.githubusercontent.com/badass-courses/kit-cli/main/install.sh | \
INSTALL_DIR=/usr/local/bin KIT_CLI_VERSION=v0.2.2 bashGitHub releases include standalone binaries compiled with bun build --compile, so Bun is not required to run kit.
Release assets:
kit-darwin-arm64/kit-cli-darwin-arm64kit-darwin-x64/kit-cli-darwin-x64kit-linux-arm64/kit-cli-linux-arm64kit-linux-x64/kit-cli-linux-x64
git clone https://github.com/badass-courses/kit-cli.git
cd kit-cli
bun install
bun run build
bun linkStore named accounts with short aliases:
kit account add code-with-antonio --api-key "..." --alias cwa,antonio --name "Code with Antonio"
kit account add totaltypescript-ai-hero --api-key "..." --alias aih,aihero --name "AI Hero / Total TypeScript"
kit account list
kit account use cwa
kit account pin cwa
kit whoami --auth api-keykit account use <id-or-alias> sets the user default Kit account in ~/.config/kit-cli/config.json. kit account pin <id-or-alias> writes a project-local .kit/config.json for the current directory so repo-specific account selection wins without env vars. API keys live in ~/.config/kit-cli/credentials.json under provider keys like kit:code-with-antonio.
For one-off scripts, you can still use an env var:
KIT_API_KEY="..." kit whoami --auth api-keykit whoami --auth api-key
kit bcasts list --auth api-key
kit bcasts text <broadcast-id> --auth api-key
kit bcasts lint <broadcast-id> --auth api-key
kit bcasts replace <broadcast-id> --auth api-key --find "old" --replace "new"
kit bcasts filter --exclude-tag 19562218 --exclude-tag 8244351
kit bcasts filter --segment 548647 --exclude-tag 19562218 --exclude-tag 8244351
kit sequences list --auth api-key
kit sequences create --auth api-key --body '{"name":"Welcome sequence"}'
kit seqemails list <sequence-id> --auth api-key
kit seqemails create <sequence-id> --auth api-key --body-file sequence-email.json
kit seqemails update <sequence-id> <email-id> --auth api-key --body '{"published":false}'All commands return JSON envelopes with ok, command, result, next_actions, and structured error details when something fails.
Build subscriber filters without hand-writing JSON:
kit bcasts filter --exclude-tag 19562218 --exclude-tag 8244351
# result.subscriber_filter: [{"none":[{"type":"tag","ids":[19562218,8244351]}]}]
kit bcasts filter --segment 548647 --exclude-tag 19562218 --exclude-tag 8244351
# result.subscriber_filter: [{"all":[{"type":"segment","ids":[548647]}]},{"none":[{"type":"tag","ids":[19562218,8244351]}]}]Broadcast create/update commands also accept structured filter flags:
kit bcasts create --body-file broadcast.json --exclude-tag 19562218 --exclude-tag 8244351
kit bcasts update <broadcast-id> --body '{"subject":"Updated"}' --segment 548647 --exclude-tag 19562218
kit bcasts update <broadcast-id> --body-file broadcast.json --subscriber-filter-file filter.jsonkit bcasts update uses read-then-merge safety: it fetches the current broadcast, merges your supplied fields on top, and preserves supported subscriber_filter values unless you explicitly replace them with --exclude-tag, --segment, --subscriber-filter-file, --body, or --body-file containing subscriber_filter.
kit bcasts replace fetches a broadcast, performs exact HTML content replacements, and PUTs back a safe update payload. It intentionally avoids round-tripping Kit's default all_subscribers subscriber filter because Kit's update endpoint only accepts segment or tag filters.
Sequence email endpoints are available through both generated commands and short aliases:
kit sequences emails list <sequence-id> --auth api-key
kit sequences emails create <sequence-id> --auth api-key --body-file sequence-email.json
kit sequences emails get <sequence-id> <email-id> --auth api-key
kit sequences emails update <sequence-id> <email-id> --auth api-key --body '{"published":false}'
kit sequences emails delete <sequence-id> <email-id> --auth api-key
kit seqemails create <sequence-id> --auth api-key --body-file sequence-email.jsonA draft payload looks like this:
{
"subject": "Welcome to the sequence",
"preview_text": "Start here.",
"content": "<p>Hello.</p>",
"delay_value": 0,
"delay_unit": "days",
"email_template_id": 4389070,
"published": false,
"position": 0
}Keep published false until you intentionally want Kit to process subscribers for that sequence email.
Broadcast and sequence email payloads require Kit API email_template_id values. Use kit emailtemplates list --auth api-key or kit templates list --auth api-key and copy the returned id. Kit editor URL IDs can differ from API email template IDs; this CLI does not claim to map those IDs unless Kit exposes that relationship.
Releases are tag-driven:
npm version patch
git push origin main --tagsThe GitHub Action:
- installs dependencies with Bun
- runs typecheck, tests, and build
- compiles standalone Linux/macOS binaries with the Bun runtime embedded
- uploads binaries and checksums to the GitHub release
bun install
bun run typecheck
bun test
bun run buildThe generated Kit operation list is built from openapi/kit-v4.json:
bun run gen