Public APIAPI Endpoints Reference

API Endpoints Reference

Complete reference for all SocialRails Public API endpoints including request and response examples.

Base URL: https://socialrails.com/api/v1

All responses follow this format:

// Success
{ "data": { ... }, "pagination": { "total": 100, "limit": 50, "offset": 0 } }
 
// Error
{ "error": { "code": "ERROR_CODE", "message": "Human-readable message" } }

Health

GET /health

Public endpoint, no authentication required. Use it to verify connectivity.

Response:

{
  "data": {
    "status": "ok",
    "version": "1.0",
    "timestamp": "2026-03-02T12:00:00Z"
  }
}

Posts

GET /posts

List posts in your workspace. Requires read scope.

Query Parameters:

  • status (optional): Filter by status, scheduled, posted, draft, failed (also accepts published as alias for posted)
  • platform (optional): Filter by platform, twitter, linkedin, etc.
  • sort (optional): Sort field, created_at (default) or scheduled_for
  • from (optional): Filter posts created after this ISO 8601 date
  • to (optional): Filter posts created before this ISO 8601 date
  • limit (optional): Results per page, max 100 (default: 50)
  • offset (optional): Pagination offset (default: 0)

Response:

{
  "data": [
    {
      "id": "uuid",
      "content": "Check out our latest update!",
      "platform": "twitter",
      "status": "scheduled",
      "scheduled_for": "2026-03-05T14:00:00Z",
      "posted_at": null,
      "created_at": "2026-03-02T10:30:00Z"
    }
  ],
  "pagination": { "total": 42, "limit": 50, "offset": 0 }
}

GET /posts/:id

Get a single post by ID. Requires read scope.

Response:

{
  "data": {
    "id": "uuid",
    "content": "Check out our latest update!",
    "platform": "twitter",
    "status": "scheduled",
    "scheduled_for": "2026-03-05T14:00:00Z",
    "posted_at": null,
    "created_at": "2026-03-02T10:30:00Z"
  }
}

POST /posts

Create a new post. Requires write scope. Platform settings (e.g. Facebook page, TikTok privacy) are automatically loaded from your workspace defaults.

Request Body:

{
  "content": "Excited to announce our new feature!",
  "platform": "linkedin",
  "scheduled_for": "2026-03-05T14:00:00Z",
  "media": ["workspace-id/api-uploads/images/media-uuid.jpg"]
}
FieldTypeRequiredDescription
contentstringYesPost content (max 5,000 chars)
platformstringYesOne of: twitter, linkedin, facebook, instagram, tiktok, bluesky, pinterest, threads, youtube
scheduled_forstringNoISO 8601 date in the future. If omitted, post is saved as draft.
mediaarrayNoArray of R2 keys returned by the media upload endpoint (key field)
platform_settingsobjectNoOverride default platform settings (e.g. { "facebook": { "videoType": "reel" } })

Response (201):

{
  "data": {
    "id": "uuid",
    "content": { "all": "Excited to announce our new feature!" },
    "platform": "linkedin",
    "status": "scheduled",
    "scheduled_for": "2026-03-05T14:00:00Z",
    "created_at": "2026-03-02T10:30:00Z"
  }
}

PATCH /posts/:id

Update a draft or scheduled post. Requires write scope. Only draft and scheduled posts can be updated.

Request Body (all fields optional):

{
  "content": "Updated content here",
  "platform": "twitter",
  "scheduled_for": "2026-03-06T10:00:00Z",
  "media": ["workspace-id/api-uploads/images/new-media-uuid.jpg"]
}

Set scheduled_for to null to convert a scheduled post back to draft. Changing the platform will automatically reload default settings for the new platform.

DELETE /posts/:id

Delete a draft or scheduled post. Requires write scope. Published or failed posts cannot be deleted.

Response:

{
  "data": { "id": "uuid", "deleted": true }
}

POST /posts/batch

Create the same post for multiple platforms at once. Requires write scope. Each platform counts as one post against your monthly limit.

Request Body:

{
  "content": "Big announcement coming soon!",
  "platforms": ["twitter", "linkedin", "facebook"],
  "scheduled_for": "2026-03-05T14:00:00Z",
  "platform_content": {
    "twitter": "Short tweet version of the announcement!"
  },
  "media": ["workspace-id/api-uploads/images/media-uuid.jpg"]
}
FieldTypeRequiredDescription
contentstringYesDefault post content (max 5,000 chars)
platformsarrayYesArray of platform names (max 9)
scheduled_forstringNoISO 8601 date in the future
platform_contentobjectNoPer-platform content overrides (e.g. shorter text for Twitter)
mediaarrayNoArray of R2 keys from the media upload endpoint
platform_settingsobjectNoPer-platform settings overrides

Response (201):

{
  "data": {
    "batch_id": "uuid",
    "posts": [
      { "id": "uuid-1", "platform": "twitter", "status": "scheduled" },
      { "id": "uuid-2", "platform": "linkedin", "status": "scheduled" },
      { "id": "uuid-3", "platform": "facebook", "status": "scheduled" }
    ]
  }
}

Analytics

GET /analytics

Get post analytics for your workspace. Requires read scope.

Query Parameters:

  • platform (optional): Filter by platform name
  • period (optional): Time period, 7d, 30d, 90d, 365d (default: 7d)
  • post_id (optional): Get analytics for a specific post

Response (aggregate):

{
  "data": {
    "period": "30d",
    "since": "2026-02-01T00:00:00Z",
    "total_posts_published": 47,
    "by_platform": [
      { "platform": "twitter", "posts_published": 20 },
      { "platform": "linkedin", "posts_published": 15 },
      { "platform": "instagram", "posts_published": 12 }
    ]
  }
}

Accounts

GET /accounts

List connected social media accounts. Requires read scope. Never exposes access tokens.

Response:

{
  "data": [
    {
      "id": "uuid",
      "provider": "twitter",
      "name": "MyBrand",
      "status": "connected",
      "connected_at": "2026-01-15T08:00:00Z"
    },
    {
      "id": "uuid",
      "provider": "linkedin",
      "name": "My Company Page",
      "status": "expired",
      "connected_at": "2026-01-20T12:00:00Z"
    }
  ]
}

The status field indicates whether the account connection is active (connected) or needs reauthorization (expired).


AI Generation

POST /ai/generate

Generate AI-powered social media content. Requires ai scope. Each request deducts 2 AI credits from your plan.

Request Body:

{
  "prompt": "Write a tweet announcing our summer sale with 30% off all products",
  "platform": "twitter",
  "tone": "humorous"
}
FieldTypeRequiredDescription
promptstringYesWhat to generate (max 2,000 chars)
platformstringNoOptimize for a specific platform
tonestringNoOne of: professional (default), casual, friendly, formal, humorous, inspirational, educational, persuasive

Response:

{
  "data": {
    "content": "Summer just got even better! Get 30% off EVERYTHING in our store. Shop now before it's gone!",
    "platform": "twitter",
    "tone": "humorous"
  }
}

When your monthly AI credits are exhausted, you'll receive a 429 response:

{
  "error": {
    "code": "LIMIT_EXCEEDED",
    "message": "Monthly AI credit limit reached (1000/1000 credits used). Upgrade your plan for more."
  }
}

Workspace

GET /workspace

Get workspace info, plan limits, and current usage. Requires read scope.

Response:

{
  "data": {
    "id": "uuid",
    "name": "My Workspace",
    "created_at": "2025-06-01T00:00:00Z",
    "plan": "professional",
    "limits": {
      "api_requests_per_hour": 300,
      "api_keys_max": 5,
      "max_posts_per_month": 900,
      "max_ai_credits_per_month": 1000
    },
    "usage": {
      "posts_this_month": 142
    }
  }
}

Media

See the dedicated Media Uploads page for full documentation.

POST /media/upload

Upload a file (multipart form data, max 10MB). Requires write scope. Returns media_id, key, and url. Use the key value in the media array when creating posts.

POST /media/upload-url

Upload media from a URL. Requires write scope. Request body: { "url": "https://..." }. Returns the same fields as /media/upload.


Webhooks (Coming Soon)

Webhook event delivery is coming soon. You can already register webhook endpoints via the API, and they will start receiving events in a future update.

See the dedicated Webhooks page for more details.

GET /webhooks

List registered webhooks. Requires read scope.

POST /webhooks

Register a new webhook. Requires webhooks scope. Request body: { "url": "https://...", "events": ["post.published"] }.

DELETE /webhooks/:id

Remove a webhook registration. Requires webhooks scope.

Updated 2 days ago