open-dispatch
v0.4.0 ยท MIT ยท 129 tests

One API to dispatch
your content
anywhere.

Open-source infrastructure for content distribution. Like Stripe for payments โ€” except for posting. One HTTP call, seven platforms, zero vendor lock-in.

๐• Twitter / X๐Ÿฆ‹ Bluesky๐Ÿ“ท Instagram๐Ÿงต Threads๐Ÿ’ผ LinkedInโœˆ๏ธ Telegramโ–ถ๏ธ YouTube Shorts
dispatch.sh
curl -X POST http://localhost:8000/dispatch \
  -H "Content-Type: application/json" \
  -d '{
  "targets": ["twitter", "bluesky", "telegram"],
  "formats": {
    "twitter_thread": {"tweets":["shipped v0.4"]},
    "bluesky_post":   {"text":"shipped v0.4"},
    "telegram_message":{"text":"shipped v0.4"}
  }
}'

Get started in 60 seconds.

Five ways to install โ€” pick what fits your stack.

๐Ÿบ Homebrew
# Add the tap (formula lives in the main repo)
brew tap matthew-selvam/open-dispatch \
  https://github.com/Matthew-Selvam/Open-Dispatch
brew install open-dispatch

# Set up credentials
$EDITOR ~/.open-dispatch/.env

# Start (foreground)
open-dispatch

# Or run as a background service โ€” auto-starts on login
brew services start open-dispatch
โ„น๏ธ Installs dispatch + open-dispatch + open-dispatch-worker. brew services wires launchd so it starts at login.

Everything you need. Nothing you don't.

โšก

API-first

Every action reachable via one HTTP call. Automate from cron, n8n, AI agents, or your own app โ€” no dashboard required.

๐Ÿ–ฅ๏ธ

Web UI included

HTMX-powered dark dashboard: compose, retry, watch the queue live. Same port as the API โ€” zero JS build step.

๐Ÿ—๏ธ

3 queue backends

JSONL on disk (zero infra), Redis (multi-worker), or Postgres (ACID + SKIP LOCKED). Swap with a single env var.

๐Ÿค–

AI caption adapt

One source text โ†’ per-platform rewrites. Ollama-first, OpenRouter fallback, heuristic safety net. Never 500s.

๐Ÿ–ผ๏ธ

Media transcoding

10 platform image specs built in โ€” square, reels, 16:9, portrait. REST endpoint + Python API.

๐Ÿ”Œ

n8n node

Native integration: Dispatch, Adapt, Get Row, Retry, List Queue โ€” all 5 ops, zero JSON wiring.

Simple, stable API.

Every endpoint is reachable over plain HTTP. /queue/{id} content-negotiates โ€” browsers get the HTML detail page, API clients get JSON.

MethodPathPurpose
GET/healthzLiveness probe
POST/dispatchEnqueue a ContentUnit for one or many platforms
GET/queue?status=โ€ฆList rows (queued / publishing / published / failed / dead)
GET/queue/{id}One row โ€” JSON or HTML (content-negotiated)
POST/queue/{id}/retryRe-queue a failed or dead row
POST/ai/adaptRewrite a caption for each target platform
POST/media/transcodeResize image to a platform spec
GET/media/specsList all 10 platform image specs

Architecture at a glance.

flow.txt
POST /dispatch
   โ”‚
   โ–ผ
Queue (JSONL โ”‚ Redis โ”‚ Postgres)
   โ”‚
   โ–ผ
scheduler/worker.py
   โ”‚
   โ”œโ”€โ–ถ adapters/twitter.py
   โ”œโ”€โ–ถ adapters/bluesky.py
   โ”œโ”€โ–ถ adapters/instagram.py
   โ”œโ”€โ–ถ adapters/telegram.py
   โ”œโ”€โ–ถ adapters/linkedin.py
   โ”œโ”€โ–ถ adapters/threads.py
   โ””โ”€โ–ถ adapters/youtube.py
          โ”‚
          โ–ผ  on publish / fail
      webhook_url

Add a platform in 80 LOC.

One function, one file. The worker handles retry, backoff, and webhooks for you.

adapters/myplatform.py
def publish(
  unit: ContentUnit,
  account: str | None)
  -> tuple[bool, str, str]:
  """Returns (ok, post_id, error)."""
  ...
  • 1.Write adapters/myplatform.py
  • 2.Add it to ADAPTERS in adapters/__init__.py
  • 3.Document the format key in README
๐Ÿ”Œ

Native n8n integration.

Community node ships in the repo. Build it once, use all five operations from the visual editor โ€” no JSON wiring.

DispatchAdapt CaptionGet RowRetry RowList Queue
cd n8n-node && npm install && npm run build

Frequently asked questions.

Which install method should I use?

On macOS the quickest path is the macOS App โ€” one download, drag to /Applications, done. If you prefer the terminal, Homebrew gives you brew services for automatic startup at login.

How do I self-host on a Linux server or VPS?

Docker is the cleanest option for Linux โ€” zero Python setup, runs as a non-root user, and includes an optional Redis sidecar. Watch the Docker setup walkthrough โ†’

Is it really free?

Yes โ€” MIT licensed. Your platform credentials never leave your own machine. There's no cloud component, no telemetry, and no account to create.

Can I add a new social platform?

Yes. The adapter contract is a single Python function โ€” about 80 lines of code. See CONTRIBUTING.md for a step-by-step guide. The worker handles retry, backoff, and webhooks automatically.

Ready to dispatch?

MIT licensed. Self-host forever free. Your platform credentials never leave your .env.

129 tests ยท 7 platforms ยท 3 queue backends ยท 5 install methods