Publish posts
Use the Social Service HTTP API to publish content to social platform channels
This guide is for developers who want to use the HTTP API to publish content immediately to one or more social platform channels.
v1 only supports direct publishing. Scheduled publishing is not supported. Publish targets must include channelId; sending only accountId to infer a default channel is not supported.
Endpoint
POST /api/social/v1/postProduction URL:
https://sogrowly.com/api/social/v1/postAuthentication
Requests require a Bearer Social API key. The API key must include the social:publish permission:
Authorization: Bearer sma_live_xxx
Content-Type: application/jsonRequest Body
{
"workspaceId": "sws_123",
"draft": {
"text": "Post text",
"assets": [
{
"type": "image",
"source": "https://example.com/image.png"
}
]
},
"targets": [
{
"channelId": "sch_123"
}
]
}Fields:
workspaceId Required. Target workspace id.
draft Required. Content draft to publish.
draft.title Optional. Some platforms can use it as the title or text fallback.
draft.text Optional. Body text.
draft.assets Optional. Media asset array.
targets Required. At least one publish target.
targets.channelId Required. The channels[].id value from /api/social/v1/account.
targets.settings Optional. Platform-specific publish settings. See Platform settings for supported fields.Asset fields:
type Required. "image" | "video" | "document"
source Required. Remote URL or base64 data URL with a MIME prefix.
mimeType Optional override. If omitted, it is inferred from the data URL MIME prefix or remote URL suffix. If inference fails, a default is selected by type.
order Optional. Sort order number. If omitted, the assets array order is used: 0, 1, 2...
metadata Optional. Additional metadata.source supports two formats:
https://example.com/image.png
data:image/png;base64,iVBORw0KGgo...Raw base64 is not supported. Base64 media must include the full MIME prefix, for example data:image/png;base64,....
Request Body Size Limit
When sending uploaded file content in the request body, make sure the full request body is no larger than 4 MB.
For media assets, using a publicly accessible URL as source is recommended:
https://example_public_url.jpegFor local files, first create a presigned upload URL with /api/social/v1/media/upload, upload the file bytes, then use the returned temporaryUrl.url or publishAsset.source as the asset source.
For platform-specific targets[].settings fields, see Platform settings.
Publish Text to X
Request body:
{
"workspaceId": "sws_123",
"draft": {
"text": "Hello from my integration."
},
"targets": [
{
"channelId": "sch_x_123"
}
]
}Example:
curl https://sogrowly.com/api/social/v1/post \
-H "Authorization: Bearer sma_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"workspaceId": "sws_123",
"draft": {
"text": "Hello from my integration."
},
"targets": [
{
"channelId": "sch_x_123"
}
]
}'Successful response:
{
"status": "success",
"statusCode": 200,
"data": {
"postId": "sdraft_123",
"summary": {
"published": 1,
"failed": 0
},
"taskResults": [
{
"taskId": "manual_task_123",
"platform": "x",
"channelId": "sch_x_123",
"status": "published",
"providerPostId": "provider_post_123",
"providerPostUrl": "https://x.com/example/status/123",
"publishedAt": "1760000000000"
}
]
},
"message": "Post published to 1 target.",
"meta": {
"version": "v1"
}
}Publish an Image to Multiple Channels
Request body:
{
"workspaceId": "sws_123",
"draft": {
"text": "New product image.",
"assets": [
{
"type": "image",
"source": "https://example.com/product.png"
}
]
},
"targets": [
{
"channelId": "sch_x_123"
},
{
"channelId": "sch_instagram_123"
}
]
}If publishing fails for some channels, the response is still HTTP 200, but status is warning:
{
"status": "warning",
"statusCode": 200,
"data": {
"postId": "sdraft_123",
"summary": {
"published": 1,
"failed": 1
},
"taskResults": [
{
"taskId": "manual_task_123",
"platform": "x",
"channelId": "sch_x_123",
"status": "published",
"providerPostId": "provider_post_123",
"providerPostUrl": "https://x.com/example/status/123",
"publishedAt": "1760000000000"
},
{
"taskId": "manual_task_456",
"platform": "instagram",
"channelId": "sch_instagram_123",
"status": "failed",
"error": {
"code": "validation_failed",
"message": "Instagram publish requires at least one image or video."
}
}
]
},
"message": "Post published with 1 failed target.",
"meta": {
"version": "v1"
}
}Callers should read data.taskResults to determine the publish result for each target.
If all targets fail, the response uses status: "failed" and returns a non-200 HTTP status code based on the main failure reason. For example, request parameter issues usually return 400, while authentication or authorization issues return 401 or 403.
Publish a Video to YouTube
Request body:
{
"workspaceId": "sws_123",
"draft": {
"title": "Product demo",
"text": "A short product demo video.",
"assets": [
{
"type": "video",
"source": "https://example.com/demo.mp4"
}
]
},
"targets": [
{
"channelId": "sch_youtube_123"
}
]
}The successful response structure is the same as above, and taskResults[].platform is "youtube".
Common Errors
Missing Authorization:
{
"status": "failed",
"statusCode": 401,
"data": {},
"message": "Authorization bearer API key is required.",
"error": {
"code": "invalid_auth",
"message": "Authorization bearer API key is required."
},
"meta": {
"version": "v1"
}
}Missing channelId:
{
"status": "failed",
"statusCode": 400,
"data": {},
"message": "Request body is invalid.",
"error": {
"code": "invalid_payload",
"message": "Request body is invalid.",
"details": {
"issues": [
{
"code": "invalid_type",
"path": "targets.0.channelId",
"message": "Invalid input: expected string, received undefined"
}
]
}
},
"meta": {
"version": "v1"
}
}API key missing the publish permission:
{
"status": "failed",
"statusCode": 403,
"data": {},
"message": "API key requires \"social:publish\" permission.",
"error": {
"code": "workspace_permission_denied",
"message": "API key requires \"social:publish\" permission."
},
"meta": {
"version": "v1"
}
}Channel does not belong to the workspace:
{
"status": "failed",
"statusCode": 400,
"data": {},
"message": "Publish target \"sch_123\" does not belong to workspace \"sws_123\".",
"error": {
"code": "workspace_mismatch",
"message": "Publish target \"sch_123\" does not belong to workspace \"sws_123\"."
},
"meta": {
"version": "v1"
}
}Status Codes and Rate Limits
200 -> success or warning
400 -> Invalid request body, invalid parameters, or channel mismatch
401 -> API key is missing, malformed, invalid, or expired
403 -> API key permission is insufficient, or workspace permission is insufficient
404 -> Workspace/channel does not exist
429 -> Rate limited by userId
500 -> Configuration error or unknown errorCurrent rate limit:
Each resolved userId can make up to 15 requests per minute.
The account and post endpoints share this rate limit.