Guides
Media & images
Upload media once to get an id, then attach it to a post. Each network has its own limits. A media set that isn't valid for one target fails just that target.
Upload
Two ways, whichever suits your client. POST the raw bytes with the correct Content-Type:
curl -X POST https://api.postlake.dev/v1/media \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: image/jpeg" \
--data-binary @photo.jpgOr send it as a form file, which is what most HTTP libraries do by default:
curl -X POST https://api.postlake.dev/v1/media \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@photo.jpg"Either way you get back a MediaAsset. For images it includes the pixel dimensions:
{ "id": "med_abc", "url": "https://…", "contentType": "image/jpeg", "size": 208134, "width": 1080, "height": 1920 }From a local MCP agent
Call upload_media without url, passing the file's contentType and sizeBytes. It returns a five-minute signed PUT target and a preallocated med_… id. The agent PUTs the local bytes with the returned headers, then uses that id in create_post. For several slides, call upload_media_batch. The file does not need public hosting and its bytes do not pass through MCP JSON or base64. See the MCP local-file workflow.
POST /v1/media/batch takes either JSON { "items": [{ "contentType": "image/jpeg", "sizeBytes": 123 }] } (signed five-minute PUT targets) or multipart with multiple file parts. Max 12 items. Use this for a carousel instead of one request per slide.
Supported: JPEG, PNG, WebP and GIF images; MP4, MOV and WebM video. Video-only networks (YouTube, TikTok) require a video asset.
Pixel limits
Some networks reject an image for its dimensions, and several only do so after accepting the upload. TikTok is the worst case: it takes the post, processes it in the background, and fails a minute later with picture_size_check_failed, which names neither the limit nor the offending image.
So we check before publishing. An image outside a network's range fails validation immediately, with the limit and the actual size in the message:
{ "error": { "type": "invalid_input",
"message": "TikTok images must be at most 1080x1920. This one is 2160x3840" } }Current limits are on the platforms page, and in get_platform_capabilities as maxPx. TikTok photos must be between 540x960 and 1080x1920. Where we cannot read an image's header we do not guess, and the check is skipped rather than failing the post.
Attach. Globally or per platform
Put ids in media to attach to every account, or use mediaOverrides to give each platform its own set (a square image for Instagram, a video for TikTok). The url from the upload response works anywhere an id does, so you can pass back whichever field you kept.
{
"text": "Launch day",
"media": ["med_abc"],
"mediaOverrides": { "tiktok": ["med_video"] },
"accounts": ["acc_ig", "acc_tt"]
}Per-platform media limits
| Platform | Media |
|---|---|
| Bluesky | Up to 4 images, or 1 video |
| Threads | Image carousel, or video |
| Image or video (Reels) | |
| TikTok | JPEG/WebP photos (max 1080×1920) or video. PNG is converted to JPEG at create/validate, with a warning. |
| YouTube | Video only |
| X, LinkedIn, Facebook | Images and video |
Image or video (needs a boardId) |
These are the practical rules today; call GET /v1/platforms/{platform} for the live, authoritative limits (max count, size, aspect) so you, or an agent, can validate before posting.
Alt text
Provide accessibility alt text per media item through platformOptions / media alt overrides. If a media set is invalid for a target, that target fails with a clear error and the others still publish, see Errors.