---
title: CLI
description: The brainy command wraps the REST API for shell scripts, cron jobs, and coding agents.
sidebar:
  icon: terminal
---

`brainy` is a thin client for the [REST API](/api). Every command accepts `--json` for machine-readable output.

The package is [`brainy-shorts`](https://www.npmjs.com/package/brainy-shorts) on npm and needs Node 18 or newer. Every command maps to one REST endpoint, so anything the CLI can't do is still available through the [REST API](/api) or the [MCP server](/mcp).

## Configure

```bash
npm install -g brainy-shorts
brainy config --api-key ba_sk_...
```

For unattended runners, prefer environment variables:

```bash
export BRAINY_API_KEY="ba_sk_..."
export BRAINY_API_URL="https://www.brainyshorts.com"   # optional, this is the default
```

The key comes from the flag, then `BRAINY_API_KEY`, then `~/.brainy/config.json`. The host comes from `BRAINY_API_URL`, then the config file, then `https://www.brainyshorts.com`. Requests go to `<host>/api/cli/...` with `Authorization: Bearer <key>`.

## Accounts

```bash
brainy accounts --json
```

## Posts

`post create` makes a draft unless you pass `--publish` or a schedule.

```bash
# Draft
brainy post create -c "caption" -p tiktok -a <account-id>

# Scheduled, with media
brainy post create -c "caption" -p tiktok -a <account-id> \
  -m "https://storage.brainyshorts.com/video.mp4" \
  -s "2026-10-01T10:00:00Z"

# Publish now
brainy post create -c "caption" -p tiktok -a <account-id> --publish

# Several accounts at once
brainy post create -c "caption" -i <account-id-1>,<account-id-2>

# From a JSON file
brainy post create --from-json post.json

brainy post list -s scheduled -p tiktok --json
brainy post update <id> -c "new caption"
brainy post update <id> -s "2026-10-02T10:00:00Z"
brainy post update <id> --unschedule
brainy post reschedule <id> "2026-10-01T14:00:00Z"
brainy post delete <id>
```

`post update` accepts a parent post id or a platform delivery id. Every still-scheduled delivery under the parent is updated together.

A `post.json` file looks like this:

```json post.json
{
  "caption": "Post caption text",
  "media_urls": ["https://storage.brainyshorts.com/video.mp4"],
  "scheduled_time": "2026-10-01T10:00:00Z",
  "integrations": [
    { "social_account_id": "uuid-1", "platform": "tiktok" },
    { "social_account_id": "uuid-2", "platform": "youtube" }
  ]
}
```

`media_urls` must be a JSON array, not a comma-separated string.

## Bulk scheduling

```bash
brainy post bulk --from-json batch.json --json
brainy post bulk-status <batch-id> --offset 0 --limit 100 --json
brainy post bulk-update --from-json updates.json --json
```

See [Bulk scheduling](/bulk-scheduling) for the batch format and idempotency rules.

## Schedules

```bash
brainy schedule list -p youtube
brainy schedule cancel <id>      # reverts the post to a draft
```

## Analytics

```bash
brainy analytics overview --json
brainy analytics overview -a <account-id>
brainy analytics overview -p x
brainy analytics post <post-id>
```

## Runner commands

For [scheduled runs](/automations):

```bash
brainy automations list --json
brainy agent claim --json
brainy agent renew <run-id> --claim-token <token> --lease-seconds 900 --json
brainy agent complete <run-id> --claim-token <token> --caption "..." --media "https://..." --json
brainy agent complete <run-id> --claim-token <token> --caption "..." --slides ./slides.json --json
brainy agent complete <run-id> --from-json ./result.json --json
brainy agent skip <run-id> --claim-token <token> --code NO_QUALIFYING_STORY --reason "..." --json
brainy agent fail <run-id> --claim-token <token> --error "Source image download failed" --json
```
