Media Upload
How to attach images, videos, and documents to posts.
Media upload
Media can enter Postato two ways: pre-uploaded via the media API, or referenced by public URL at publish time. Pick based on where the file lives.
Path A: presigned URL (recommended)
Best for: known files on disk, user-provided uploads in your app, anything larger than a few MB.
1. Request an upload URL
curl -X POST https://api.postato.com.br/v1/workspaces/$WORKSPACE_ID/media/upload-url \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filename": "launch.mp4",
"mimeType": "video/mp4",
"sizeBytes": 18234567
}'Response:
{
"mediaId": "med_01H...",
"uploadUrl": "https://storage.postato.com.br/...?signed=...",
"expiresAt": "2026-04-15T12:15:00Z"
}2. PUT the file directly
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: video/mp4" \
--data-binary @launch.mp4The Content-Type header must match the mimeType you declared. Stream the raw bytes; no multipart wrapping.
3. Confirm (optional)
curl -X POST https://api.postato.com.br/v1/workspaces/$WORKSPACE_ID/media/$MEDIA_ID/confirm \
-H "Authorization: Bearer $API_KEY"This transitions the media from pending to uploaded. Some clients can skip this if the presigned URL flow auto-confirms; check the response shape.
4. Attach to a post
{
"content": [
{
"text": "Launch day.",
"media": [{ "id": "med_01H..." }]
}
]
}Path B: public URL
Best for: files already hosted somewhere public (your CDN, GitHub, a vendor).
{
"content": [
{
"text": "From our docs.",
"media": [{ "url": "https://example.com/og.png", "type": "image" }]
}
]
}Postato fetches the URL asynchronously at publish time and uploads into our storage before calling the target network. Returns in milliseconds, but the actual network delivery depends on download speed.
URL requirements
- HTTPS only. HTTP URLs return a validation error.
- No private ranges. RFC-1918 addresses, AWS IMDS (
169.254.x.x), and localhost are blocked for SSRF protection. - Public reachability. If the URL requires auth or signed access, use Path A instead.
Supported formats
| Type | Accepted mimetypes |
|---|---|
| Image | image/jpeg, image/png, image/gif, image/webp, image/heic |
| Video | video/mp4, video/quicktime, video/webm |
| Document | application/pdf (LinkedIn documents only) |
Platform-specific constraints (dimensions, duration, bit rate) are enforced by the target network at publish time, not by Postato at upload. Check the platform's docs for specifics.
Reusing media
Once uploaded, media is referenced by med_ ID. Reuse across multiple posts in the same workspace without re-uploading. Media is NOT shared across workspaces; each workspace has its own library.
Alt text and tagging
Attach per-item:
{
"id": "med_01H...",
"alt": "Screenshot of the dashboard overview page",
"userTags": [
{ "username": "coworker_handle", "x": 0.4, "y": 0.3 }
]
}alt improves accessibility and SEO on platforms that display it. userTags are Instagram-only (photo tagging).
Lifecycle
Media is never auto-deleted. Use DELETE /media/{id} to clean up unused assets. Deleting media referenced by scheduled or draft posts causes those posts to fail at delivery time with media_not_found.