SOSPosting

SOSPosting Developer API

Publish to Instagram, Facebook, TikTok, YouTube, Pinterest, LinkedIn, Threads, Bluesky, WordPress and Shopify with one REST call — with AI captions per platform, delivery status for every target and engagement metrics read-back for Facebook, Instagram and YouTube. No subscription: API posts spend the same pay-as-you-go tokens as dashboard posts.

Authentication

Every request carries an API key in the Authorization header:

Authorization: Bearer sosp_<your key>

Mint keys in the console under Settings → API access (app.sosposting.com). A key is scoped to the business it was created in: it posts to that business's connected platforms and spends that business's token wallet. Keys are shown once at creation — store them like passwords, and revoke them anytime from the same screen.

Base URL: https://app.sosposting.com. Requests and responses are JSON. API posts cost exactly the same tokens as posts made from the dashboard — see pricing.

POST /api/v1/posts — create a post

One call fans out to every platform you target. Payload fields:

  • type (required) — "reel", "social", "product" or "blog".
  • mediaUrl — public https:// URL of the image or video (use the presign endpoint below if you don't host media yourself).
  • title, caption — your copy; with useAi on, the AI turns it into platform-native captions, titles and hashtags.
  • providers — array like ["INSTAGRAM","FACEBOOK","TIKTOK"]; defaults to all eligible connected platforms for the post type.
  • useAi — default true; set false to publish your text verbatim.
  • scheduledAt — ISO 8601 timestamp to schedule instead of publishing now.
curl -X POST https://app.sosposting.com/api/v1/posts \
  -H "Authorization: Bearer sosp_..." \
  -H "Content-Type: application/json" \
  -d '{
    "type": "reel",
    "mediaUrl": "https://example.com/clip.mp4",
    "title": "Summer drop",
    "caption": "Our new summer collection is live",
    "providers": ["INSTAGRAM", "FACEBOOK", "YOUTUBE"],
    "useAi": true,
    "scheduledAt": "2026-08-01T09:00:00Z"
  }'

Returns 201 with the post id and one target per platform:

{
  "id": "cmcz...",
  "scheduledAt": "2026-08-01T09:00:00.000Z",
  "targets": [
    { "id": "t1...", "status": "QUEUED" },
    { "id": "t2...", "status": "QUEUED" }
  ]
}

GET /api/v1/posts/:id — status & metrics read-back

Poll the post to see how delivery went and how the post performs. Delivery status is returned for every target; engagement metrics are polled from Facebook, Instagram and YouTube only — the platforms whose APIs expose per-post insights to us. Metrics are refreshed at most once per hour, on demand:

curl https://app.sosposting.com/api/v1/posts/cmcz... \
  -H "Authorization: Bearer sosp_..."
{
  "id": "cmcz...",
  "createdAt": "2026-07-13T10:00:00.000Z",
  "scheduledAt": null,
  "status": "POSTED",
  "targets": [
    {
      "provider": "INSTAGRAM",
      "status": "POSTED",
      "externalId": "1789...",
      "externalUrl": "https://www.instagram.com/p/...",
      "error": null,
      "metrics": { "views": 1200, "likes": 88, "comments": 7 }
    }
  ]
}
  • Post-level status rolls up the targets: QUEUED, SCHEDULED (waiting for its scheduled time), PROCESSING, POSTED, PARTIAL, FAILED or SKIPPED.
  • TikTok targets show PENDING_USER while the video sits in the account's TikTok drafts waiting for a manual publish — it isn't publicly live yet, so it has no externalUrl.
  • metrics is populated for FACEBOOK, INSTAGRAM and YOUTUBE targets only; every other provider (TikTok, Pinterest, LinkedIn, Threads, Bluesky, WordPress, Shopify) always returns metrics: null. Even on a supported platform it is null until the first refresh after delivery, and individual keys are omitted when the platform won't report them — shares comes from Facebook only, and views from video posts. metricsAt tells you when a target's metrics were last refreshed.
  • Unknown or foreign post ids return 404.

POST /api/v1/media/presign — upload media without your own bucket

Ask for a presigned upload, PUT the bytes, then use the returned publicUrl as mediaUrl when creating the post:

curl -X POST https://app.sosposting.com/api/v1/media/presign \
  -H "Authorization: Bearer sosp_..." \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "clip.mp4",
    "contentType": "video/mp4",
    "sizeBytes": 10485760
  }'
{
  "uploadUrl": "https://...r2.cloudflarestorage.com/...",  // PUT the raw bytes here
  "publicUrl": "https://media.../uploads/....mp4",         // use as mediaUrl
  "key": "uploads/....mp4"
}
curl -X PUT "<uploadUrl>" \
  -H "Content-Type: video/mp4" \
  --data-binary @clip.mp4

Limits: images up to 25 MB, videos up to 50 MB. sizeBytes is required (missing it returns 400). Unsupported content types are rejected with 415, oversize files with 413; presign requests are rate-limited per business (429).

Tokens & errors

  • Same pricing as the dashboard: an API post is charged the same tokens as the identical post made in the console — see what tokens buy. Failed deliveries on our side are refunded automatically.
  • Errors return a JSON body { "error": "...", "code": "..." } — the code is a stable machine-readable value (e.g. insufficient_tokens, invalid_media_url, rate_limited) — with a conventional status code: 400 bad request, 401 bad key, 402 not enough tokens, 404 not found, 413/415 media limits, 429 rate limited.

Good to know

  • Connect your platforms once in the console — the API publishes through the same integrations.
  • Run several brands? Each business has its own key and connected accounts, and businesses under one account share a single token wallet — no per-seat or per-workspace fees.
  • The API is versioned under /api/v1/; changes are additive.

Post once. Publish everywhere.

Cross-post to Instagram, TikTok, YouTube, Shopify and six more platforms from one place — with AI-written captions and Google Ads on autopilot.

Start free