Publish to Social

Publish images or videos directly to connected social accounts


Publish content to your connected social media accounts. Use this when you already have a media URL (e.g., from a previous render) and want to post it without rendering again.

To publish as part of a render in a single call, use the publish parameter on Render from Studio Template instead.

Endpoint#

POST /social/publish#

https://api.orshot.com/v1/social/publish

Request Example#

await fetch("https://api.orshot.com/v1/social/publish", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer <ORSHOT_API_KEY>",
  },
  body: JSON.stringify({
    accounts: [1, 2],
    content: "Check out our latest design!",
    media_url: "https://storage.orshot.com/.../image.png",
  }),
});

Find your account IDs using the List Social Accounts endpoint, or from the Social Accounts page in your workspace sidebar.

Schedule a Post#

await fetch("https://api.orshot.com/v1/social/publish", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer <ORSHOT_API_KEY>",
  },
  body: JSON.stringify({
    accounts: [1],
    content: "This will be posted later!",
    media_url: "https://storage.orshot.com/.../image.png",
    schedule: { scheduledFor: "2030-01-15T10:00:00Z" },
    timezone: "America/New_York",
  }),
});

Save as Draft#

await fetch("https://api.orshot.com/v1/social/publish", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer <ORSHOT_API_KEY>",
  },
  body: JSON.stringify({
    accounts: [1, 2],
    content: "Draft post — will publish later from the dashboard",
    media_url: "https://storage.orshot.com/.../image.png",
    isDraft: true,
  }),
});

Platform-Specific Options#

await fetch("https://api.orshot.com/v1/social/publish", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer <ORSHOT_API_KEY>",
  },
  body: JSON.stringify({
    accounts: [1, 2],
    content: "New product launch!",
    media_url: "https://storage.orshot.com/.../image.png",
    platformOptions: {
      "1": { firstComment: "Follow us for more updates!" },
      "2": { title: "Product Launch", link: "https://acme.com/launch" },
    },
  }),
});

Request Parameters#

ParameterTypeRequiredDescription
accountsArrayYesArray of account IDs to publish to (see List Social Accounts)
contentStringNoCaption/text for the post (max 5000 characters)
media_urlStringNoURL of the image or video to publish
media_urlsArrayNoMultiple media URLs for carousel posts (use instead of media_url)
isDraftBooleanNotrue to save as draft instead of publishing
schedule.scheduledForStringNoISO 8601 timestamp to schedule the post (must be at least 60 seconds in the future)
timezoneStringNoIANA timezone string for scheduling (e.g., "America/New_York", "Europe/London")
platformOptionsObjectNoPer-account options keyed by account ID (see below)

Platform Options#

Pass platform-specific options keyed by account ID:

PlatformOptionDescription
LinkedInfirstCommentAuto-post a first comment
LinkedIndisableLinkPreviewDisable the link preview card
PinteresttitlePin title
PinterestlinkDestination URL for the pin

Response Example#

{
  "data": {
    "post_id": 42,
    "status": "published",
    "platforms": [
      {
        "platform": "twitter",
        "username": "acmehq",
        "name": "Acme HQ",
        "status": "published",
        "url": "https://twitter.com/acmehq/status/1234567890"
      },
      {
        "platform": "linkedin",
        "username": "acme-inc",
        "name": "Acme Inc",
        "status": "published",
        "url": "https://linkedin.com/feed/update/urn:li:share:1234567890"
      }
    ]
  }
}

Response Fields#

FieldTypeDescription
post_idIntegerUnique identifier for the post
statusStringOverall status: published, scheduled, drafted, partial, or failed
platformsArrayPer-account results
platforms[].platformStringPlatform name
platforms[].usernameStringAccount username
platforms[].nameStringAccount display name
platforms[].statusStringpublished, scheduled, drafted, or failed
platforms[].urlStringLink to the published post (when available)
platforms[].errorStringError message (only on failure)

A partial status means some accounts succeeded and others failed — check individual platforms[].status for details.

Format Compatibility#

Not all formats work on every platform:

FormatUnsupported Platforms
PDFAll platforms (not supported)
MP4, WebM, GIFGoogle Business
PNG, JPG, WebPTikTok, YouTube (video-only platforms)

If some accounts are incompatible with the media format, they are skipped and returned with status: "failed" and a reason in the error field.

Rate Limits#

This endpoint is rate limited to 20 requests per minute per workspace. Rate limit headers are included in every response:

HeaderDescription
X-RateLimit-LimitMaximum requests per minute
X-RateLimit-RemainingRemaining requests in the current window
Retry-AfterSeconds to wait (only on 429 responses)

Error Responses#

CodeDescription
400Missing or empty accounts array
400Content exceeds 5000 characters
400Invalid schedule.scheduledFor timestamp
400Scheduled time must be in the future
400No valid connected accounts found for the given IDs
403Missing or invalid API key
403Social publishing requires a paid plan
422No compatible platforms for the media format
429Rate limit exceeded

Ready to automate?

Start rendering images, PDFs and videos from your templates in under 2 minutes. Free plan, no credit card.

Get your API key
  • Image, PDF and video generation via API
  • Visual editor with AI and smart layouts
  • Zapier, Make, MCP and 50+ integrations
  • White-label embed for your own app
  • 60 free renders — no credit card required