Developers

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.

bash
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

MethodPathWhat it does
GET/api/v1/channelsList connected channels
GET/api/v1/posts?status=&from=&to=List posts, filtered by status and date range
POST/api/v1/postsCreate 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.jsonOpenAPI spec

Status values: draft, pending_approval, approved, scheduled, publishing, published, partially_failed, failed. Dates use ISO 8601.

Create a post

FieldTypeRequired
textstringYes
channelIdsstring[]Yes
scheduledAtISO 8601 date-timeNo — omit for a draft
firstCommentstringNo
mediaUrlsstring[]No
bash
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

bash
# 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"
Use the OpenAPI spec for exact response fields and to generate a client.

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).

bash
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.

js
// 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.

bash
claude mcp add --transport http surge-social "$SURGE_URL/api/mcp" --header "Authorization: Bearer $SURGE_API_KEY"