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/publishRequest 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#
| Parameter | Type | Required | Description |
|---|---|---|---|
accounts | Array | Yes | Array of account IDs to publish to (see List Social Accounts) |
content | String | No | Caption/text for the post (max 5000 characters) |
media_url | String | No | URL of the image or video to publish |
media_urls | Array | No | Multiple media URLs for carousel posts (use instead of media_url) |
isDraft | Boolean | No | true to save as draft instead of publishing |
schedule.scheduledFor | String | No | ISO 8601 timestamp to schedule the post (must be at least 60 seconds in the future) |
timezone | String | No | IANA timezone string for scheduling (e.g., "America/New_York", "Europe/London") |
platformOptions | Object | No | Per-account options keyed by account ID (see below) |
Platform Options#
Pass platform-specific options keyed by account ID:
| Platform | Option | Description |
|---|---|---|
firstComment | Auto-post a first comment | |
disableLinkPreview | Disable the link preview card | |
title | Pin title | |
link | Destination 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#
| Field | Type | Description |
|---|---|---|
post_id | Integer | Unique identifier for the post |
status | String | Overall status: published, scheduled, drafted, partial, or failed |
platforms | Array | Per-account results |
platforms[].platform | String | Platform name |
platforms[].username | String | Account username |
platforms[].name | String | Account display name |
platforms[].status | String | published, scheduled, drafted, or failed |
platforms[].url | String | Link to the published post (when available) |
platforms[].error | String | Error 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:
| Format | Unsupported Platforms |
|---|---|
| All platforms (not supported) | |
| MP4, WebM, GIF | Google Business |
| PNG, JPG, WebP | TikTok, 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:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per minute |
X-RateLimit-Remaining | Remaining requests in the current window |
Retry-After | Seconds to wait (only on 429 responses) |
Error Responses#
| Code | Description |
|---|---|
| 400 | Missing or empty accounts array |
| 400 | Content exceeds 5000 characters |
| 400 | Invalid schedule.scheduledFor timestamp |
| 400 | Scheduled time must be in the future |
| 400 | No valid connected accounts found for the given IDs |
| 403 | Missing or invalid API key |
| 403 | Social publishing requires a paid plan |
| 422 | No compatible platforms for the media format |
| 429 | Rate 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