Features
Everything below is implemented and covered by the test suite in the repository. The list doesn't include anything that's only planned.
Scheduling
- Compose once, override per platform (X, LinkedIn, Reddit title/body, Bluesky)
- Live character counters: 280 for X, 300 for Bluesky, 3000 for LinkedIn
- X threads: split with a line containing ---, posted as a reply chain
- Drafts, scheduled, published, partial and failed states
- Automatic retries with exponential backoff (1, 2, 4 minutes), configurable attempts
- Per-channel delivery log with remote IDs and post URLs
- Month calendar: click a day to schedule

Autopilot
- Cadence slots such as 09:00, 13:00, 17:30 in server time (set TZ)
- Plans 1 to 14 days ahead and never double-books a slot
- Topic queue with content pillars
- Evergreen topics are recycled when the queue runs dry
- Five personas: Thought Leader, Indie Hacker, Technical Architect, Contrarian Analyst, Viral Storyteller
- Each generated post records which engine wrote it and why it fell back

Channels
- X API v2: OAuth 1.0a user context or OAuth 2.0 user token
- LinkedIn: UGC Posts API for members or organizations
- Reddit: script-app password grant or access token, self posts to any subreddit
- Bluesky: AT Protocol session, with link and hashtag facets
- Webhooks: JSON payload signed with HMAC-SHA256
- Sandbox: an explicit channel type, or SANDBOX_MODE=true for everything
- Multiple accounts per network via env prefixes (X_BRAND2_API_KEY …)

AI providers
| Provider | Env vars | Notes |
|---|---|---|
| Heuristic (default) | none | Offline and deterministic templates. Works without any key. |
| OpenAI | OPENAI_API_KEY, OPENAI_BASE_URL | Chat Completions in JSON mode. Any OpenAI-compatible endpoint works. |
| Anthropic | ANTHROPIC_API_KEY | Messages API |
| Google Gemini | GEMINI_API_KEY | generateContent with a JSON response type |
| Ollama | OLLAMA_URL | Local models, so nothing leaves your network |
If a provider errors, Open Post falls back to the heuristic engine and stores the reason with the post.
Operations
- Storage: built-in
node:sqlite(Node 22+),better-sqlite3, or an atomic JSON file - Optional bearer-token protection with
API_TOKEN - Docker image runs as a non-root user and includes a healthcheck
node cli.js tickruns one scheduler pass, for cron or systemd timers- Measured idle memory on Node 20 is about 70 MB RSS