Instagram carousel
Multi-photo post with user tags and per-photo alt text.
Instagram carousel
A carousel is 2–10 images (or videos) shown as a swipeable unit. On Postato, you build it as a single content item with multiple media attachments.
Shape
{
"platform": "instagram",
"accountId": "acc_01H...",
"status": "publish",
"postType": "carousel",
"content": [
{
"text": "Launch day, in photos.",
"media": [
{ "id": "med_01H...photo1", "alt": "Team cheering at release moment" },
{ "id": "med_01H...photo2", "alt": "Dashboard metrics hitting target" },
{ "id": "med_01H...photo3", "alt": "Office whiteboard with launch plan" }
]
}
]
}Auto-promotion
If you send postType: "feed" with 2+ media items in a single content item, Postato automatically upgrades to carousel. You don't have to classify upfront; just attach the media and we match it to the right Instagram format.
User tagging
Tag people by handle + position on the photo. Coordinates are normalized 0–1 (top-left is 0, 0):
{
"id": "med_01H...photo1",
"alt": "Team cheering",
"userTags": [
{ "username": "teammate_one", "x": 0.3, "y": 0.4 },
{ "username": "teammate_two", "x": 0.7, "y": 0.35 }
]
}User tags are Instagram-only and work only on images (not videos). Tagging a username that doesn't exist silently fails at publish; Instagram just omits the tag.
Full call
// 1. Upload each photo via presigned URLs (see Media upload guide)
const photos = await Promise.all([
uploadMedia('./photo1.jpg', 'image/jpeg'),
uploadMedia('./photo2.jpg', 'image/jpeg'),
uploadMedia('./photo3.jpg', 'image/jpeg'),
]);
// 2. Compose and publish
const response = await fetch(
`https://api.postato.com.br/v1/workspaces/${WORKSPACE_ID}/posts`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
platform: 'instagram',
accountId: INSTAGRAM_ACCOUNT_ID,
status: 'publish',
postType: 'carousel',
content: [
{
text: 'Launch day, in photos.',
media: photos.map((id, i) => ({
id,
alt: `Launch photo ${i + 1}`,
})),
},
],
}),
}
);import uuid
import httpx
# 1. Upload each photo via presigned URLs (see Media upload guide)
photos = [
upload_media("photo1.jpg", "image/jpeg"),
upload_media("photo2.jpg", "image/jpeg"),
upload_media("photo3.jpg", "image/jpeg"),
]
# 2. Compose and publish
response = httpx.post(
f"https://api.postato.com.br/v1/workspaces/{WORKSPACE_ID}/posts",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"platform": "instagram",
"accountId": INSTAGRAM_ACCOUNT_ID,
"status": "publish",
"postType": "carousel",
"content": [
{
"text": "Launch day, in photos.",
"media": [
{"id": mid, "alt": f"Launch photo {i + 1}"}
for i, mid in enumerate(photos)
],
},
],
},
timeout=60,
)Constraints
- 2–10 media items per carousel. Fewer → Postato sends a regular feed post. More → Instagram rejects.
- Mixed images + videos is allowed. Each slide is independent.
- Caption (the
text) applies to the whole carousel, not per-slide. Captions above 2,200 characters fail. - Location tagging and collaborator mentions go in
options; see the API reference for exact shape.
Reels vs carousel
A reel is always a single video, not a carousel. If you need a reel, use postType: "reel" with one video attachment. Postato does not transcode between formats; use the right postType upfront.