Public API
REST API to list channels, create and schedule posts, and read analytics.
Authentication
Create a key in Settings → API keys. Send it as a Bearer token on every request. Keys are shown once — store them safely. Revoke a key any time from the same page.
export SURGE_URL="https://your-surge-address" # the address you use to open SocialPostScheduler
export SURGE_API_KEY="your-key"
curl -H "Authorization: Bearer $SURGE_API_KEY" "$SURGE_URL/api/v1/channels"A missing or revoked key returns 401.
Endpoints
| Method | Path | What it does |
|---|---|---|
| GET | /api/v1/channels | List connected channels |
| GET | /api/v1/posts?status=&from=&to= | List posts, filtered by status and date range |
| POST | /api/v1/posts | Create a post (draft or scheduled) |
| GET | /api/v1/posts/{id} | Get one post |
| DELETE | /api/v1/posts/{id} | Delete a post |
| GET | /api/v1/analytics?from=&to= | Analytics for a date range |
| GET | /api/v1/openapi.json | OpenAPI spec |
Status values: draft, pending_approval, approved, scheduled, publishing, published, partially_failed, failed. Dates use ISO 8601.
Create a post
| Field | Type | Required |
|---|---|---|
| text | string | Yes |
| channelIds | string[] | Yes |
| scheduledAt | ISO 8601 date-time | No — omit for a draft |
| firstComment | string | No |
| mediaUrls | string[] | No |
curl -X POST "$SURGE_URL/api/v1/posts" \
-H "Authorization: Bearer $SURGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Diwali hours: 9am–9pm all week 🪔",
"channelIds": ["CHANNEL_ID_1", "CHANNEL_ID_2"],
"scheduledAt": "2026-11-03T09:30:00+05:30",
"firstComment": "Order online: example.com",
"mediaUrls": ["https://example.com/diwali.jpg"]
}'More examples
# Scheduled posts in November
curl -H "Authorization: Bearer $SURGE_API_KEY" \
"$SURGE_URL/api/v1/posts?status=scheduled&from=2026-11-01&to=2026-11-30"
# One post
curl -H "Authorization: Bearer $SURGE_API_KEY" "$SURGE_URL/api/v1/posts/POST_ID"
# Delete a post
curl -X DELETE -H "Authorization: Bearer $SURGE_API_KEY" "$SURGE_URL/api/v1/posts/POST_ID"
# Analytics for October
curl -H "Authorization: Bearer $SURGE_API_KEY" \
"$SURGE_URL/api/v1/analytics?from=2026-10-01&to=2026-10-31"
# OpenAPI spec
curl "$SURGE_URL/api/v1/openapi.json"Threads and evergreen posts
Add thread (parts 2…n) to post a reply chain on X, Threads and Bluesky; other networks get part 1. Add recycleEveryDays to re-queue a copy that many days after it publishes (up to 3 copies).
curl -X POST "$SURGE_URL/api/v1/posts" -H "Authorization: Bearer $SURGE_API_KEY" -H "Content-Type: application/json" \
-d '{"text":"5 sweets every Hyderabadi has an opinion on 🧵","thread":["1. Double Ka Meetha","2. Qubani ka Meetha"],"channelIds":["X_CHANNEL_ID"],"mode":"queue"}'Webhooks
Settings → Webhooks & MCP. SocialPostScheduler sends a JSON POST for post.published, post.failed, post.scheduled, inbox.received and approval.decided.
Each request carries x-surge-event and x-surge-signature: t=TIMESTAMP,v1=HEX, where HEX is HMAC-SHA256 of TIMESTAMP.BODY with your endpoint secret. Reject requests older than 5 minutes.
// Node.js
const [t, v1] = sig.split(",").map((s) => s.split("=")[1]);
const ok = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex") === v1;MCP server (Claude, Cursor, agents)
SocialPostScheduler is also an MCP server at /api/mcp (Streamable HTTP, JSON responses). Tools: list_channels, list_posts, create_post, write_post (Surge AI in your brand voice) and get_analytics. Authenticate with a workspace API key.
claude mcp add --transport http surge-social "$SURGE_URL/api/mcp" --header "Authorization: Bearer $SURGE_API_KEY"