---
title: "Command Line (CLI)"
description: "Post to X, Bluesky, LinkedIn, Mastodon and Threads from your terminal with the octopost command. One binary for macOS and Linux, browser sign-in or an API key."
---

# Command Line (CLI)

`octopost` posts from your terminal: publish now, schedule, add to your queue, check a post before it goes out, and see what happened. It's one self-contained binary for macOS and Linux, so there's nothing else to install.

> **Network status (2026-11):** X is live. Threads opens after Meta approves the Octopost app. Bluesky, LinkedIn and Mastodon are in testing.

## Install

```bash
curl -fsSL https://octopost.ink/cli/install.sh | sh
```

The script picks the build for your computer (macOS or Linux, Apple silicon/ARM or Intel/x64), checks its SHA-256 against [SHA256SUMS](https://octopost.ink/cli/SHA256SUMS), and puts `octopost` in `~/.local/bin`. It doesn't use sudo. Set `OCTOPOST_INSTALL_DIR` to install somewhere else.

The macOS builds are signed with Great Work's Developer ID and notarized by Apple.

Prefer to download by hand? The binaries are at `https://octopost.ink/cli/<platform>/octopost`, where platform is `darwin-arm64`, `darwin-x64`, `linux-x64` or `linux-arm64`.

## Sign in

```bash
octopost login
```

Your browser opens on Octopost. Sign in, check the account and click **Allow**. The CLI saves the sign-in to `~/.config/octopost/credentials.json` (readable only by you) and refreshes it on its own. It shows up as "Octopost CLI" under **Connected apps** on the [API keys page](https://octopost.ink/dashboard/api/keys), where **Disconnect** ends it.

On a server, in CI, or anywhere without a browser, use an API key instead:

```bash
octopost login --key op_...
# or, without saving anything:
OCTOPOST_API_KEY=op_... octopost accounts
```

`octopost whoami` shows how you're signed in. `octopost logout` forgets the saved sign-in.

## Post

```bash
octopost post "Shipped the new export button today"
```

With no `--to`, the post goes to every network you have connected. Pick networks with `--to` (comma-separated or repeated; `x` means X/Twitter):

```bash
octopost post "Hello from the terminal" --to x,bluesky
```

Attach images or a video with `--media`. Local files are uploaded for you; URLs are used as they are. `--alt` sets alt text for the `--media` in the same position:

```bash
octopost post "The new dashboard" --to x \
  --media ./screenshot.png --alt "Dashboard with a weekly chart" \
  --media https://example.com/second.jpg
```

Make a thread with `--thread`, one per reply. Putting a link in a reply instead of the first post keeps X from showing the post to fewer people:

```bash
octopost post "I wrote up how we cut our build time in half" --to x \
  --thread "https://example.com/blog/faster-builds"
```

Read the text from a file or another command with `-`:

```bash
cat announcement.txt | octopost post - --to x
```

Other options: `--account x=@handle` picks the account when a network has several connected, and `--allow-duplicate` posts the same text again (Octopost refuses the same text to the same network within 7 days without it).

## Check before posting

```bash
octopost preview "Is this too long for X? ..." --to x,bluesky
```

Shows each network's character count against its limit, the X units it would use, media checks and anything that would stop it. Nothing is saved or posted. It exits with status 1 when the post wouldn't go out, so scripts can stop early.

## Schedule

```bash
octopost schedule "Weekly update is live" --to x --at "2026-11-10 09:00"
```

`--at` takes:

| You write | Means |
|-----------|-------|
| `+30m`, `+2h`, `+1d` | that long from now |
| `17:30`, `9am`, `9:30pm` | today at that time, or tomorrow if it has passed |
| `2026-11-10 09:00` | that date and time in your computer's time zone |
| `2026-11-10T09:00:00-05:00` | an exact ISO 8601 time |

Add `--approval` to hold it until someone approves it from the email Octopost sends. See [Scheduling Posts](https://octopost.ink/docs/scheduling.md).

## Queue

```bash
octopost queue "An evergreen tip about keyboard shortcuts" --to x
octopost queue "Draft from the release script" --to x --approval
octopost queue          # how many are queued, when the next one goes out
```

Queued posts go out one at a time during your active hours. See [Post Queue](https://octopost.ink/docs/queue.md).

## See your posts

```bash
octopost list                      # newest first
octopost list --status failed      # published, scheduled, draft, queued, pending, partial, failed, retrying
octopost list --limit 50
octopost get <post-id>             # text, networks, links, errors
octopost retry <post-id>           # retry the networks that failed
octopost retry <post-id> --to x    # retry only X
```

When there are more posts, `list` prints the `--cursor` for the next page.

## Accounts and usage

```bash
octopost accounts    # connected accounts, which one is the default per network
octopost usage       # plan, X units left this month, accounts used
```

## Scripts and agents

Every command takes `--json` and prints the raw answer, the same JSON the [MCP tools](https://octopost.ink/docs/mcp.md) return:

```bash
octopost list --status scheduled --json | jq -r '.posts[].id'
```

Exit status is 0 on success, 1 when Octopost refused or the post failed (including a partly published post), and 2 for a mistake in the command itself. Error messages go to stderr.

Coding agents (Claude Code, Cursor, Codex) can run `octopost` like any other command once you've signed in. If your agent supports MCP, connecting `https://octopost.ink/mcp` directly gives it the same tools without a shell; see [Agent Integration](https://octopost.ink/docs/agents.md).

## Reference

```text
octopost login [--key op_...] [--no-browser]
octopost logout | whoami
octopost post "text" [--to x,bluesky] [--media FILE|URL ...] [--alt "text" ...] [--thread "text" ...]
octopost schedule "text" --at TIME [--approval] [post options]
octopost queue ["text"] [--approval] [post options]
octopost preview "text" [post options]
octopost list [--status S] [--limit N] [--cursor C]
octopost get <post-id>
octopost retry <post-id> [--to x]
octopost accounts | usage
```

Global options: `--json`, `--key op_...` (one command only), `--base URL` (another Octopost server; also `OCTOPOST_URL`), `--help`, `--version`.

The CLI talks to `https://octopost.ink/mcp`, which accepts both browser sign-ins and API keys. Your sign-in lives in `$XDG_CONFIG_HOME/octopost/credentials.json` (default `~/.config/octopost`).
