Create a post
A post is one piece of content sent to one or more accounts. Each account and placement gets its own result. This page covers POST /v1/posts and the endpoints to read and cancel posts.
Updated
POST /v1/posts
| Field | Type | Description |
|---|---|---|
accounts | string[], required | Account IDs from GET /v1/accounts. Can mix platforms. |
format | string, required | video, slideshow or image. |
media | string[], required | Public URLs. One for video and image, 2 or more in order for slideshow. |
caption | string | Caption with hashtags. Used as the description on YouTube. |
scheduled_at | ISO 8601 string | When to publish, like 2026-11-01T17:00:00Z. Omit to publish now. |
external_id | string | Your ID for this post. Returned in results and webhooks. |
options | object | Per-platform options: instagram, tiktok, youtube, facebook. See formats and options. |
curl https://ugcapi.dev/v1/posts \
-H "Authorization: Bearer ugc_live_..." \
-H "Content-Type: application/json" \
-d '{
"accounts": ["acc_tt_01", "acc_ig_01"],
"format": "video",
"media": ["https://cdn.example.com/clip.mp4"],
"caption": "Day 1 of the test #ugc",
"scheduled_at": "2026-11-01T17:00:00Z",
"external_id": "deliverable-981",
"options": {
"instagram": { "grid": true, "story": true },
"tiktok": { "draft": false, "ai_generated": false }
}
}'Response
{
"id": "post_abc",
"status": "scheduled",
"format": "video",
"scheduled_at": "2026-11-01T17:00:00Z",
"external_id": "deliverable-981",
"results": [
{ "account_id": "acc_tt_01", "platform": "tiktok", "placement": "video", "status": "scheduled", "url": null, "error": null },
{ "account_id": "acc_ig_01", "platform": "instagram", "placement": "reel", "status": "scheduled", "url": null, "error": null },
{ "account_id": "acc_ig_01", "platform": "instagram", "placement": "story", "status": "scheduled", "url": null, "error": null }
]
}Each result is one post credit. Result status is scheduled, publishing, published or failed. A published result has a public url. A failed one has an error object with code and message. See pricing and credits.
Read a post
const res = await fetch("https://ugcapi.dev/v1/posts/post_abc", {
headers: { "Authorization": "Bearer " + process.env.UGCAPI_KEY },
});
const post = await res.json();
for (const r of post.results) console.log(r.platform, r.placement, r.status, r.url);List posts
GET /v1/posts returns posts newest first. Query parameters: status, account_id, external_id, limit and cursor. The response has data and next_cursor. Pass next_cursor as cursor to get the next page; it is null on the last page.
curl "https://ugcapi.dev/v1/posts?status=failed&limit=50" -H "Authorization: Bearer ugc_live_..."Cancel a scheduled post
curl -X DELETE https://ugcapi.dev/v1/posts/post_abc -H "Authorization: Bearer ugc_live_..."You can cancel a post while its results are still scheduled. Results that already published can't be removed through the API. Delete them on the platform.
Validation
We validate the request before accepting it. A missing field or unknown option returns 400 invalid_request. An account ID that isn't yours returns 404 account_not_found. Not enough credits for all results returns 402 insufficient_credits. See errors. To schedule many posts over many accounts, use campaigns instead of a loop.
FAQ
How many accounts can one post target?
As many as you have connected. Each account and placement is a separate result and credit.
What time zone does scheduled_at use?
It is an ISO 8601 timestamp. Include Z for UTC or an explicit offset.
Can I edit a scheduled post?
Cancel it with DELETE /v1/posts/:id and create a new one.