Posts & Publishing
Create posts and publish them to connected social platforms.
Create Post
POST /api/v1/posts
Create a post from generation outputs or custom content. Posts start as drafts that you can review before publishing.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
generation_id | string | No | Caption generation ID to populate content from |
items | array | Yes | Post items — one per post type you want to publish |
Post Item Object
| Field | Type | Required | Description |
|---|---|---|---|
post_type | string | Yes | Target post type (e.g., instagram-reel, tiktok-video) |
content | string | Yes* | Caption text for this platform |
title | string | No | Title (required for YouTube post types) |
media_ids | string[] | No | Media to attach (uploaded or generated images) |
* If generation_id is provided, content is optional and will be filled from the generation outputs.
Examples
From a Generation
Create a post using outputs from a completed caption generation:
curl -X POST https://powerpost.ai/api/v1/posts \
-H "x-api-key: pp_live_sk_YOUR_KEY" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"generation_id": "550e8400-e29b-41d4-a716-446655440000",
"items": [
{
"post_type": "instagram-reel",
"media_ids": ["img-001-abcd-efgh"]
},
{
"post_type": "tiktok-video",
"media_ids": ["img-001-abcd-efgh"]
}
]
}'const res = await fetch('https://powerpost.ai/api/v1/posts', {
method: 'POST',
headers: {
'x-api-key': 'pp_live_sk_YOUR_KEY',
'X-Workspace-Id': 'YOUR_WORKSPACE_ID',
'Content-Type': 'application/json',
},
body: JSON.stringify({
generation_id: '550e8400-e29b-41d4-a716-446655440000',
items: [
{ post_type: 'instagram-reel', media_ids: ['img-001-abcd-efgh'] },
{ post_type: 'tiktok-video', media_ids: ['img-001-abcd-efgh'] },
],
}),
})
const data = await res.json()import requests
res = requests.post(
"https://powerpost.ai/api/v1/posts",
headers={
"x-api-key": "pp_live_sk_YOUR_KEY",
"X-Workspace-Id": "YOUR_WORKSPACE_ID",
"Content-Type": "application/json",
},
json={
"generation_id": "550e8400-e29b-41d4-a716-446655440000",
"items": [
{"post_type": "instagram-reel", "media_ids": ["img-001-abcd-efgh"]},
{"post_type": "tiktok-video", "media_ids": ["img-001-abcd-efgh"]},
],
},
)
data = res.json()Custom Content
Create a post with your own content — no generation needed:
curl -X POST https://powerpost.ai/api/v1/posts \
-H "x-api-key: pp_live_sk_YOUR_KEY" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"post_type": "x-post",
"content": "Just shipped the biggest update of the year. Thread below."
},
{
"post_type": "instagram-feed",
"content": "Our biggest update of the year is live! Check link in bio for details.",
"media_ids": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890"]
}
]
}'const res = await fetch('https://powerpost.ai/api/v1/posts', {
method: 'POST',
headers: {
'x-api-key': 'pp_live_sk_YOUR_KEY',
'X-Workspace-Id': 'YOUR_WORKSPACE_ID',
'Content-Type': 'application/json',
},
body: JSON.stringify({
items: [
{
post_type: 'x-post',
content: 'Just shipped the biggest update of the year. Thread below.',
},
{
post_type: 'instagram-feed',
content: 'Our biggest update of the year is live! Check link in bio for details.',
media_ids: ['a1b2c3d4-e5f6-7890-abcd-ef1234567890'],
},
],
}),
})
const data = await res.json()import requests
res = requests.post(
"https://powerpost.ai/api/v1/posts",
headers={
"x-api-key": "pp_live_sk_YOUR_KEY",
"X-Workspace-Id": "YOUR_WORKSPACE_ID",
"Content-Type": "application/json",
},
json={
"items": [
{
"post_type": "x-post",
"content": "Just shipped the biggest update of the year. Thread below.",
},
{
"post_type": "instagram-feed",
"content": "Our biggest update of the year is live! Check link in bio for details.",
"media_ids": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890"],
},
],
},
)
data = res.json()YouTube Post
YouTube requires a title in addition to the description:
curl -X POST https://powerpost.ai/api/v1/posts \
-H "x-api-key: pp_live_sk_YOUR_KEY" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"post_type": "youtube-short",
"title": "We Just Shipped Dark Mode",
"content": "Dark mode is finally here across all our apps. #darkmode #tech",
"media_ids": ["vid-001-abcd-efgh"]
}
]
}'const res = await fetch('https://powerpost.ai/api/v1/posts', {
method: 'POST',
headers: {
'x-api-key': 'pp_live_sk_YOUR_KEY',
'X-Workspace-Id': 'YOUR_WORKSPACE_ID',
'Content-Type': 'application/json',
},
body: JSON.stringify({
items: [
{
post_type: 'youtube-short',
title: 'We Just Shipped Dark Mode',
content: 'Dark mode is finally here across all our apps. #darkmode #tech',
media_ids: ['vid-001-abcd-efgh'],
},
],
}),
})
const data = await res.json()import requests
res = requests.post(
"https://powerpost.ai/api/v1/posts",
headers={
"x-api-key": "pp_live_sk_YOUR_KEY",
"X-Workspace-Id": "YOUR_WORKSPACE_ID",
"Content-Type": "application/json",
},
json={
"items": [
{
"post_type": "youtube-short",
"title": "We Just Shipped Dark Mode",
"content": "Dark mode is finally here across all our apps. #darkmode #tech",
"media_ids": ["vid-001-abcd-efgh"],
},
],
},
)
data = res.json()Response
{
"post_id": "post-550e8400-e29b-41d4-a716-446655440000",
"status": "draft",
"created_at": "2026-01-10T18:30:00Z",
"items": [
{
"item_id": "item-001",
"post_type": "instagram-reel",
"platform": "instagram",
"content": "Dark mode is here! Your late-night scrolling just got easier... #DarkMode",
"media_ids": ["img-001-abcd-efgh"],
"status": "draft"
},
{
"item_id": "item-002",
"post_type": "tiktok-video",
"platform": "tiktok",
"content": "POV: your eyes at 2am finally getting some relief... #darkmode #tech",
"media_ids": ["img-001-abcd-efgh"],
"status": "draft"
}
]
}Get Post
GET /api/v1/posts/{id}
Retrieve the details and status of a post.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The post ID |
Example
curl https://powerpost.ai/api/v1/posts/post-550e8400-e29b-41d4-a716-446655440000 \
-H "x-api-key: pp_live_sk_YOUR_KEY" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID"const res = await fetch(
'https://powerpost.ai/api/v1/posts/post-550e8400-e29b-41d4-a716-446655440000',
{
headers: {
'x-api-key': 'pp_live_sk_YOUR_KEY',
'X-Workspace-Id': 'YOUR_WORKSPACE_ID',
},
}
)
const data = await res.json()import requests
res = requests.get(
"https://powerpost.ai/api/v1/posts/post-550e8400-e29b-41d4-a716-446655440000",
headers={
"x-api-key": "pp_live_sk_YOUR_KEY",
"X-Workspace-Id": "YOUR_WORKSPACE_ID",
},
)
data = res.json()Response
{
"post_id": "post-550e8400-e29b-41d4-a716-446655440000",
"status": "published",
"created_at": "2026-01-10T18:30:00Z",
"published_at": "2026-01-10T18:35:00Z",
"items": [
{
"item_id": "item-001",
"post_type": "instagram-reel",
"platform": "instagram",
"content": "Dark mode is here!...",
"media_ids": ["img-001-abcd-efgh"],
"status": "posted",
"platform_post_id": "17898455678012345"
},
{
"item_id": "item-002",
"post_type": "tiktok-video",
"platform": "tiktok",
"content": "POV: your eyes at 2am...",
"media_ids": ["img-001-abcd-efgh"],
"status": "posted",
"platform_post_id": "7234567890123456789"
}
]
}Publish Post
POST /api/v1/posts/{id}/publish
Publish a draft post to connected social platforms. Each item is published to its target platform independently — if one fails, the others still go through.
Prerequisites
Before publishing, ensure:
- Platforms are connected — Connect your social accounts in Settings → Connections
- Post is in draft status — Published posts cannot be re-published
- Sufficient credits — Publishing costs a flat 1-credit base fee, plus a surcharge for premium platforms (X)
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The post ID |
Example
curl -X POST https://powerpost.ai/api/v1/posts/post-550e8400-e29b-41d4-a716-446655440000/publish \
-H "x-api-key: pp_live_sk_YOUR_KEY" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID"const res = await fetch(
'https://powerpost.ai/api/v1/posts/post-550e8400-e29b-41d4-a716-446655440000/publish',
{
method: 'POST',
headers: {
'x-api-key': 'pp_live_sk_YOUR_KEY',
'X-Workspace-Id': 'YOUR_WORKSPACE_ID',
},
}
)
const data = await res.json()import requests
res = requests.post(
"https://powerpost.ai/api/v1/posts/post-550e8400-e29b-41d4-a716-446655440000/publish",
headers={
"x-api-key": "pp_live_sk_YOUR_KEY",
"X-Workspace-Id": "YOUR_WORKSPACE_ID",
},
)
data = res.json()Response
{
"post_id": "post-550e8400-e29b-41d4-a716-446655440000",
"status": "publishing",
"credits_used": 1,
"status_url": "/api/v1/posts/post-550e8400-e29b-41d4-a716-446655440000"
}| Field | Type | Description |
|---|---|---|
post_id | string | The post ID |
status | string | Will be publishing while in progress |
credits_used | number | Estimated credits for publishing (actual charges per successful item) |
status_url | string | Relative URL to poll for status |
Publishing is asynchronous. Poll the Get Post endpoint or use webhooks to know when publishing completes.
Publishing Costs
Publishing costs a flat 1-credit base fee per publish action. X (Twitter) adds a 3-credit surcharge due to higher API costs. All other platforms are included in the base fee. See the Credits page for more details.
Credits are only charged for items that publish successfully. If an item fails, no credits are charged for it.
Post Status Values
Post Status
| Status | Description |
|---|---|
draft | Created, not yet published |
publishing | Publish in progress |
published | At least one item posted successfully |
failed | All items failed to publish |
Item Status
| Status | Description |
|---|---|
draft | Not yet published |
posting | Publishing in progress |
posted | Successfully published |
failed | Failed (see error field) |
Post Types Reference
| Platform | Post Types |
|---|---|
instagram-feed, instagram-reel, instagram-story | |
| TikTok | tiktok-video, tiktok-photos |
| YouTube | youtube-video, youtube-short |
| X | x-post |
facebook-post, facebook-reel, facebook-story | |
linkedin-post |
Errors
| Code | Description |
|---|---|
| 400 | Invalid request body or post is currently being published |
| 401 | Invalid API key |
| 402 | Insufficient credits for publishing |
| 404 | Post not found or generation not found |
| 409 | Post has already been published |
| 422 | Platform not connected for one or more post types |
| 429 | Rate limit exceeded |