Posts
Content model, post types, and lifecycle.
Posts
A post in Postato is one piece of content destined for one social network. Multi-network campaigns become multiple posts, one per platform.
Content model
The content field is polymorphic:
String (single post)
Simple text goes as a string:
{ "content": "Shipping something small today." }Internally this normalizes to [{ text: "Shipping something small today." }]. The two forms are equivalent.
Array (threads and multi-item posts)
For threads (Twitter) and multi-slide posts, use an array of content items:
{
"content": [
{ "text": "Part one of the thread." },
{ "text": "Part two, continuing the thought." },
{ "text": "Part three, wrap-up." }
]
}Each array element is a separate tweet (or equivalent unit on the target platform).
Validation
You can either send content alone OR pair a string content with a top-level media array. Mixing an array content with a top-level media array is a validation error; attach media to individual content items instead:
{
"content": [
{
"text": "Launch photos",
"media": [{ "id": "med_01ABC..." }]
}
]
}Post types
postType maps to platform-native content formats:
| Platform | Types |
|---|---|
feed, reel, story, carousel | |
| Twitter / X | tweet, thread |
post, document | |
| TikTok | video, photo |
| YouTube | video, short |
Carousel auto-promotion
If you send a single content item with 2+ media attachments on a platform that supports carousels, Postato upgrades postType to carousel automatically. No need to pre-classify.
Status lifecycle
status at submission is one of:
publish: deliver immediatelyscheduled: requiresscheduledAt(ISO 8601). Platform will fire the delivery at that timedraft: persist without publishing; useful for review workflows
Post states after submission:
queued → (worker picks up) → publishing → published
↘ failed
↘ retrying → ...
scheduled → (wait for scheduledAt) → queued → ...
draft → (no action until status change) → ...
pending_approval → (reviewer decides) → queued or rejectedQuery the final state via GET /posts/{id} or subscribe to the post.published / post.failed webhooks.
Media
Media can be referenced in two ways:
id: media uploaded via the Postato media API, returned asmed_<ULID>. This is the preferred path.url: a public URL. Postato fetches the file into our object storage before publishing, which adds latency but removes the need to upload ahead of time.
Both can carry alt (accessibility) and Instagram userTags (photo tagging with coordinates 0–1).
Options
Platform-specific toggles live under options. For Twitter: options.reply_settings. For Instagram: options.location, options.collaborators. Browse the REST reference for the full list.
Retries and delivery
- One
post-{postId}-{platform}job runs per post. - Transient network errors retry with exponential backoff.
- Permanent rejections (content violation, invalid account) fail fast and fire the
post.failedwebhook.
See Idempotency for safely re-submitting after a timeout.