Posts API
The Posts API lets you create and submit posts to one or more social media platforms through a single API call. You can publish immediately or schedule posts for a future time.
Create a Post
Submit a new post for publishing.
| Header | Required | Description |
|---|
Content-Type | Yes | Must be application/json |
soku-api-key | Yes | Your Soku API key |
Idempotency-Key | No | A unique string to prevent duplicate post submissions. See Idempotency. |
Request Body
The request body is a JSON object with the following top-level fields:
| Field | Type | Required | Description |
|---|
post | object | Yes | The post content and targeting configuration |
scheduledTime | string | No | ISO 8601 timestamp for scheduling. If omitted, the post is published immediately. Must be at least 1 minute in the future. An invalid format returns a 400 error with code validation_error. |
Post Object
| Field | Type | Required | Description |
|---|
post.content | object | Yes | The content payload for the post |
Content Object
| Field | Type | Required | Description |
|---|
content.text | string | No | The text body of the post (caption, tweet, etc.) |
content.mediaType | string | No | The media type: "video", "image", or "text" |
content.mediaUrls | string[] | No | Array of media URLs (general-purpose, for any media type) |
content.videoUrl | string | No | URL of the video file. Use when mediaType is "video". |
content.imageUrls | string[] | No | Array of image URLs. Use when mediaType is "image". |
content.platform | array | Yes | Array of platform targets. Each element can be a string or a platform object. |
Each element in the platform array specifies a destination for the post. There are two formats:
String format (legacy, single account):
Use a plain string when you have only one connected account for a platform, or to target the default account.
"platform": ["threads", "x"]
Object format (multi-account):
Use an object when you need to target a specific account for a platform. The accountId field is required when you have multiple accounts connected for the same platform.
"platform": [
{ "platform": "instagram", "accountId": "ig_main" },
{ "platform": "instagram", "accountId": "ig_brand" },
"threads"
]
| Field | Type | Required | Description |
|---|
platform | string | Yes | The platform name: "instagram", "tiktok", "youtube", "facebook", "x", "threads", "linkedin", "snapchat" |
accountId | string | Conditional | The ID of the specific account to target. Required when multiple accounts are connected for the same platform. |
You can mix string and object formats in the same platform array. Use objects only where you need to specify an accountId.
Response
| Field | Type | Description |
|---|
postSubmissionId | string | A unique identifier for the post submission. Use this to track the status of the post. |
{
"postSubmissionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Examples
Publish a text post immediately
curl -X POST https://api.mysoku.io/v1/posts \
-H "Content-Type: application/json" \
-H "soku-api-key: sk_live_your_api_key_here" \
-d '{
"post": {
"content": {
"text": "Just shipped a new feature. Check it out!",
"mediaType": "text",
"platform": ["threads", "x", "linkedin"]
}
}
}'
Publish a video post to specific accounts
curl -X POST https://api.mysoku.io/v1/posts \
-H "Content-Type: application/json" \
-H "soku-api-key: sk_live_your_api_key_here" \
-d '{
"post": {
"content": {
"text": "New product walkthrough",
"mediaType": "video",
"videoUrl": "https://storage.mysoku.io/media/abc123/video.mp4",
"platform": [
{ "platform": "instagram", "accountId": "ig_main" },
{ "platform": "tiktok", "accountId": "tt_brand" },
"youtube"
]
}
}
}'
Publish an image post with multiple images
curl -X POST https://api.mysoku.io/v1/posts \
-H "Content-Type: application/json" \
-H "soku-api-key: sk_live_your_api_key_here" \
-d '{
"post": {
"content": {
"text": "Behind the scenes from today'\''s shoot",
"mediaType": "image",
"imageUrls": [
"https://storage.mysoku.io/media/img1.jpg",
"https://storage.mysoku.io/media/img2.jpg",
"https://storage.mysoku.io/media/img3.jpg"
],
"platform": ["instagram", "facebook"]
}
}
}'
Schedule a post for later
curl -X POST https://api.mysoku.io/v1/posts \
-H "Content-Type: application/json" \
-H "soku-api-key: sk_live_your_api_key_here" \
-d '{
"post": {
"content": {
"text": "Monday motivation incoming.",
"mediaType": "text",
"platform": ["threads", "x"]
}
},
"scheduledTime": "2026-03-02T09:00:00.000Z"
}'
Error Responses
| HTTP Status | Error Code | Description |
|---|
| 400 | validation_error | Missing or invalid fields in the request body |
| 400 | missing_integrations | One or more target platforms are not connected to your account |
| 400 | missing_account | The specified accountId does not exist for the given platform |
| 401 | unauthorized | Missing or invalid API key |
| 403 | forbidden | Subscription is not active |
| 429 | rate_limit_exceeded | Too many requests. See Rate Limits. |
| 400 | upload_failed | Media URL could not be fetched or stored |
| 409 | idempotency_conflict | Same idempotency key used with a different request body |
| 500 | dispatch_failed | The post was created but delivery to one or more platforms failed |
| 500 | post_creation_failed | An internal error occurred while creating the post |
Example error response:
{
"error": {
"type": "invalid_request_error",
"code": "missing_integrations",
"message": "The following platforms are not connected: tiktok. Connect them in Settings > Integrations.",
"timestamp": "2026-02-28T12:00:00.000Z",
"requestId": "req_abc123def456",
"details": {
"missingPlatforms": ["tiktok"]
}
}
}
Ensure all target platforms are connected in your Soku dashboard before making API calls. You can connect platforms in Settings > Integrations.
Idempotency
The Idempotency-Key header prevents duplicate post submissions when retrying requests.
- Include an
Idempotency-Key header with a unique string value (for example, a UUID) on POST /v1/posts requests.
- If the header is omitted, Soku auto-derives a key from your user ID and a hash of the request payload.
- If you send the same idempotency key with the same request body, the API returns the original result without creating a duplicate post.
- If you send the same idempotency key with a different request body, the API returns a
409 error with code idempotency_conflict.
Next Steps
| Topic | Description |
|---|
| Media API | Upload media files before attaching them to posts |
| Templates API | Generate OG images to include in posts |
| Error Handling | Full reference of error codes and troubleshooting |