# PostEverywhere Media Requirements Reference > Image dimensions, video duration limits, file sizes, aspect ratios, and format requirements for every platform supported by the PostEverywhere API. **Source:** https://posteverywhere.ai/docs/media-requirements **Section:** Reference **API reference:** https://posteverywhere.ai/docs/api/reference --- Each social platform enforces its own limits on file sizes, dimensions, video duration, and formats. This page covers every constraint so you can validate media before uploading. ## Upload limits that apply to every platform The PostEverywhere API accepts files up to these sizes: | Type | Maximum Size | |------|-------------| | Images | 20 MB | | Videos | 500 MB | | PDFs | 20 MB | ## Accepted image and video MIME types ``` image/jpeg image/png image/gif image/webp image/heic image/heif video/mp4 application/pdf ``` Only `video/mp4` is accepted for video uploads. If your source video is in another format, transcode it to H.264 MP4 before uploading. ## Maximum file size, platform by platform The API enforces the PostEverywhere upload limits above, but individual platforms may reject media that exceeds their own limits. Ensure your files stay within these bounds: | Platform | Image Max | Video Max | Other | |----------|-----------|-----------|-------| | Instagram | 30 MB | 500 MB | -- | | X / Twitter | 5 MB | 512 MB | -- | | LinkedIn | 100 MB | 5 GB | 100 MB (PDF) | | Facebook | 30 MB | 10 GB | -- | | TikTok | 20 MB | 500 MB | -- | | YouTube | -- | 256 GB | -- | | Threads | 30 MB | 250 MB | -- | | Pinterest | 100 MB | 2 GB | -- | | Telegram | 10 MB | 50 MB | -- | | Bluesky | 50 MB (recompressed to 2 MB per image) | 100 MB | -- | | Discord | 25 MB | 25 MB (linked by URL) | -- | > **Tip:** PostEverywhere's own 500 MB video upload limit is more restrictive than some platforms (YouTube, LinkedIn). We process and re-upload your media to each platform. ## Minimum and maximum image dimensions | Platform | Minimum | Maximum / Recommended | |----------|---------|----------------------| | Instagram | 320 x 320 | 1080 x 1350 (4:5 portrait recommended) | | X / Twitter | 600 x 335 | 4096 x 4096 | | LinkedIn | 200 x 200 | 7680 x 4320 | | Facebook | 600 x 315 | 8192 x 8192 | | TikTok | 360 x 360 | 1080 x 1920 | | Threads | 320 x 320 | 1080 x 1350 | | Pinterest | 200 x 300 | 1000 x 1500 (2:3 recommended) | > **Oversized images are resized for you** > > You do not need to pre-resize images to fit the table above. Media is served to each platform > through Cloudflare Images, and where a platform enforces a hard ceiling we request a > scaled-down variant automatically, since TikTok's Photo API rejects anything over 1080 px, so a > 4032 x 3024 phone photo is delivered to TikTok at 1080 x 810 with the aspect ratio preserved. > Images already within a platform's limits are passed through untouched at full resolution. ## Maximum video length, platform by platform | Platform | Minimum | Maximum | |----------|---------|---------| | Instagram Reels | 3 seconds | 15 minutes | | X / Twitter | 0.5 seconds | 2 min 20 sec | | LinkedIn | 3 seconds | 10 minutes | | Facebook | 1 second | 4 hours | | TikTok | 3 seconds | 10 minutes | | YouTube | 1 second | 12 hours | | Threads | 1 second | 5 minutes | | Pinterest | 4 seconds | 15 minutes | | Bluesky | -- | 3 minutes | ## Accepted aspect ratios per platform Aspect ratio requirements vary significantly by platform. Getting these wrong is one of the most common causes of publishing failures. | Platform | Accepted Ratios | Notes | |----------|----------------|-------| | **TikTok** | **9:16 only** | Vertical video is mandatory. Other ratios are rejected. | | Instagram | 4:5 to 1.91:1 | 4:5 portrait performs best. Square (1:1) is safe. | | X / Twitter | 1:2.39 to 2.39:1 | Wide range accepted. 16:9 is standard. | | LinkedIn | 1:2.4 to 2.4:1 | 1:1 or 16:9 recommended for feed. | | Facebook | 9:16 to 16:9 | 4:5 recommended for feed. | | YouTube | 16:9 | Other ratios are letterboxed or pillarboxed. | | Threads | 1:1, 4:5 or 9:16 | Square and portrait only; no landscape. | | Pinterest | 9:16, 2:3, 4:5 or 1:1 | 2:3 vertical pins perform best. | > **TikTok requires 9:16** > > TikTok strictly rejects any video that is not in 9:16 portrait orientation. Always verify the aspect ratio before publishing to TikTok. ## How many images or videos each post allows Maximum number of media attachments per post: | Platform | Images | Videos | PDF | |----------|--------|--------|-----| | Instagram | 10 (carousel) | 1 (Reels) | -- | | X / Twitter | 4 | 1 | -- | | LinkedIn | 20 | 1 | 1 | | Facebook | 10 | 1 | -- | | TikTok | 35 (photo carousel) | 1 | -- | | YouTube | -- | 1 | -- | | Threads | 10 | 1 | -- | | Pinterest | 5 (carousel) | 1 | -- | | Telegram | 10 | 1 | -- | | Bluesky | 4 | 1 | -- | | Discord | 10 (embeds) | 1 (linked by URL) | -- | > **Note:** You cannot mix images and videos in the same post on most platforms. Instagram carousels are image-only. ## Required video codecs and bitrates PostEverywhere accepts MP4 only, and H.264 is accepted everywhere (some platforms also take H.265 or VP9). Details vary: | Platform | Codec | Frame Rate | Bitrate | |----------|-------|-----------|---------| | Instagram | H.264 / H.265 | 23-60 fps | 6-8 Mbps recommended | | X / Twitter | H.264 | up to 40 fps | 25 Mbps max | | LinkedIn | H.264 | 10-60 fps | 8 Mbps recommended, 10 Mbps max | | Facebook | H.264 | up to 30 fps | 8 Mbps recommended | | TikTok | H.264 / H.265 | 23-60 fps | 6-12 Mbps recommended | | YouTube | H.264 / H.265 / VP9 | up to 60 fps | 12 Mbps recommended at 1080p | | Threads | H.264 | 30 fps | -- | | Pinterest | H.264 / H.265 | up to 60 fps | -- | Audio should be AAC, 128 kbps or higher. PostEverywhere does not transcode uploaded videos (it verifies the file and extracts a thumbnail), so upload a compliant MP4. ## Uploading media, step by step Two options depending on whether the file is already on the public web: ### Option A: Already on a public URL (one call) If your image is already hosted somewhere publicly fetchable, use `POST /v1/media/upload-from-url`: ```bash curl -X POST https://app.posteverywhere.ai/api/v1/media/upload-from-url \ -H "Authorization: Bearer pe_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/hero.webp" }' ``` Response is ready-to-use immediately (`media_status: "ready"`): ```json { "data": { "media_id": "a1b2c3d4-...", "media_ids": ["a1b2c3d4-..."], "media_status": "ready", "type": "image", "url": "https://imagedelivery.net/.../img_.../public", "content_type": "image/webp", "size": 14914 } } ``` Images (25 MB cap) import instantly; MP4 videos (500 MB cap) import asynchronously: poll `GET /v1/media/{id}` until `media_status` is `ready`. For local files, use Option B. ### Option B: Local file (3-step flow) For local files, the upload is a 3-step process: request a presigned URL, upload bytes to it, then finalise. #### Step 1: Request a presigned upload URL `POST /v1/media/upload` takes JSON describing the file you're about to upload, **not** the file itself. Field names are `filename`, `content_type`, `size` (not `file_name`, `mime_type`, `file_size`). ```bash curl -X POST https://app.posteverywhere.ai/api/v1/media/upload \ -H "Authorization: Bearer pe_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "filename": "photo.jpg", "content_type": "image/jpeg", "size": 2048000 }' ``` The response includes a `media_id`, an `upload_url`, and an `upload_method` describing how to upload: ```json { "data": { "media_id": "a1b2c3d4-...", "upload_url": "https://upload.imagedelivery.net/...", "upload_method": { "method": "POST", "content_type": "multipart/form-data", "field_name": "file" }, "media_status": "uploading" } } ``` #### Step 2: Upload the bytes to `upload_url` > **Image upload URLs are not S3-style** > > Sending `PUT` with raw bytes to an **image** `upload_url` returns `400 {"code":100,"message":"method is not supported"}`. Image URLs are Cloudflare direct-upload endpoints: use `POST` with `multipart/form-data` and the file in the field named by `upload_method.field_name` (usually `file`). Only **video and PDF** URLs accept `PUT` with raw bytes. For images, send a multipart POST with the field name from `upload_method.field_name` (usually `file`): ```bash curl -X POST "" \ -F "file=@photo.jpg" ``` For videos, use the PUT method with the correct `Content-Type` header (`upload_method.method` will be `PUT` and `upload_method.headers` tells you the header to send). #### Step 3: Finalise This step is **required**: without it the media stays in `media_status: "uploading"` and `POST /v1/posts` will reject attempts to attach it. ```bash curl -X POST https://app.posteverywhere.ai/api/v1/media/{media_id}/complete \ -H "Authorization: Bearer pe_live_abc123..." ``` After Step 3 the media is `ready` and you can attach it via `media_ids` in a post. ### Polling for video processing (Option B videos only) Videos go through additional processing for thumbnail extraction. After Step 3 returns `ready`, the file is uploadable but the thumbnail may still be generating. Poll `GET /v1/media/{id}` if you need the `thumbnail_url` field populated. ### Step 4: Attach to a post ```bash curl -X POST https://app.posteverywhere.ai/api/v1/posts \ -H "Authorization: Bearer pe_live_abc123..." \ -H "Content-Type: application/json" \ -d '{ "content": "Check out this photo!", "account_ids": [123], "media_ids": ["550e8400-e29b-41d4-a716-446655440000"], "scheduled_for": "2026-04-15T10:00:00Z" }' ``` Always confirm the media status is `ready` before attaching it to a post. See [Upload Media](/docs/api/init-media-upload) for the full endpoint reference. ## Related media and platform pages - [Upload Media](/docs/api/init-media-upload) -- upload endpoint reference - [Schedule a Post](/docs/api/schedule-post) -- attach media to posts - [Error Handling](/docs/errors) -- media-related error codes (`unsupported_media_type`, `file_too_large`, `file_type_mismatch`) **Related:** [Instagram API guide](/docs/platforms/instagram) · [TikTok API guide](/docs/platforms/tiktok) · [YouTube API guide](/docs/platforms/youtube) · [testing uploads safely](/docs/testing) · [storage included in each plan](/pricing)