API
SimplePost has two HTTP APIs with overlapping request shapes:
- The Scheduler API is part of the Scheduler app. It uses connected accounts, user sessions, upload storage, scheduling, CLI auth, and the MCP OAuth flow.
- The self-hosted REST server is a small stateless Express server around the SDK. It uses an API key and an
accounts.jsonfile. It publishes immediately and does not include users, scheduling, OAuth account connection, or MCP.
Use the same client-side posting model for both when possible, then choose the deployment based on account management and scheduling needs.
Which API should I use?
| Need | Use | Why |
|---|---|---|
| Multi-user account connection | Scheduler API | Users connect accounts in the web app. |
| Scheduling | Scheduler API | Scheduled posts are stored and dispatched later. |
| MCP for AI assistants | Scheduler API | MCP is hosted by the Scheduler app. |
| Simple backend-to-backend publishing | Self-hosted REST server | One API key, one account file, no app database. |
| Your own token store | Self-hosted REST server or SDK | You provide credentials directly. |
| Direct upload to S3/R2 | Scheduler API | Supports presigned upload URLs. |
| Local disk media uploads | Self-hosted REST server | Serves uploaded files from /media/:filename. |
Common posting request
curl -X POST "$SIMPLEPOST_BASE_URL/api/v1/posts" \
-H "Content-Type: application/json" \
-H "x-api-key: $SIMPLE_POST_API_KEY" \
-d '{
"message": "Launching today!",
"accountIds": ["x-main", "telegram-news"],
"postingMode": "now"
}'
The Scheduler API authenticates differently, depending on the caller. Browser users rely on their session. CLI calls use a Scheduler-issued bearer token. MCP calls use MCP OAuth bearer tokens. The self-hosted REST server uses x-api-key.
Scheduler API
Use the Scheduler API when you run the Scheduler app or use the hosted Scheduler at schedule.simplepost.dev.
Main capabilities:
- List connected accounts.
- Upload media through the server or presigned storage URLs.
- Validate posts against selected accounts.
- Publish now.
- Schedule for later.
- Inspect drafts, scheduled, posted, and failed posts.
- Update or delete drafts and scheduled posts.
- Set per-account platform options, such as YouTube
thumbnailUrlafter uploading a custom thumbnail. - Support CLI authorization.
- Support OAuth and MCP endpoints.
Useful routes:
| Route | Purpose |
|---|---|
/api/v1/accounts | List connected accounts. |
/api/v1/posts | Create, list, save drafts, publish, or schedule posts. |
/api/v1/posts/{id} | Inspect, update, publish, schedule, draft, or delete one post when supported by its status. |
/api/v1/upload | Server-side media upload. |
/api/v1/upload/presign | Direct S3/R2 upload URL generation. |
/api/v1/validation | Validate a post draft. |
/api/cli/authorize | CLI connection flow. |
/api/oauth/* | MCP OAuth flow. |
/mcp | MCP Streamable HTTP endpoint. |
The Scheduler app also exposes internal dispatch for scheduled posts. Call it only from trusted infrastructure:
curl -X POST "$NEXT_PUBLIC_APP_URL/api/internal/scheduled-posts/dispatch" \
-H "Authorization: Bearer $SCHEDULED_POST_DISPATCH_SECRET"
Self-hosted REST server
Use the REST server when you want a small HTTP wrapper around the SDK without running the full Scheduler app.
What it includes:
GET /healthGET /api/v1/accountsPOST /api/v1/uploadPOST /api/v1/validationPOST /api/v1/postsGET /media/:filenameGET /openapi.json
What it does not include:
- Scheduling.
- Account connection UI.
- OAuth callback flows.
- Multi-user sessions.
- Database persistence.
- MCP.
- Presigned S3/R2 upload routes.
Configure the server
cd core
yarn install
cp server/.env.example server/.env
Set:
| Variable | Required | Description |
|---|---|---|
SIMPLE_POST_API_KEY | Yes | Shared secret clients send as x-api-key. |
SIMPLE_POST_ACCOUNTS_FILE | Recommended | Path to accounts.json. Without it, posting rejects all accounts. |
SIMPLE_POST_PUBLIC_URL | Recommended | Public URL used for media URLs. |
SIMPLE_POST_STORAGE_DIR | No | Local uploaded media directory. |
PORT | No | Defaults to 3000. |
Minimal accounts.json:
{
"accounts": [
{
"id": "telegram-news",
"platform": "telegram",
"platformAccountId": "@your_channel",
"credentials": { "botToken": "123456:ABC..." }
}
]
}
Each account can also include label, username, profilePicture, provider options, and provider-specific credentials. See the platform pages and credential strategies.
Run locally
yarn workspace @simple-post/server dev
Run in production
yarn workspace @simple-post/server build
yarn workspace @simple-post/server start
Run with Docker
cd core
docker build -t simple-post-server -f server/Dockerfile .
docker run -p 3000:3000 \
-e SIMPLE_POST_API_KEY=your-secret-api-key \
-e SIMPLE_POST_PUBLIC_URL=https://posts.example.com \
-e SIMPLE_POST_ACCOUNTS_FILE=/config/accounts.json \
-e SIMPLE_POST_STORAGE_DIR=/data \
-v /path/on/host/accounts.json:/config/accounts.json:ro \
-v simple-post-data:/data \
simple-post-server
API reference
Open API reference for the generated OpenAPI reference. It includes the Scheduler API and the self-hosted REST server API.