Skip to main content

Supported media types

You can attach media in four ways (same MIME allow-list for uploads): WebM is intentionally excluded — most networks reject it (TikTok and Bluesky would transcode it, the rest refuse it), so accepting it would just produce platform-specific publish failures.

Upload limits

These are the Cloud upload hard caps. Every path (dashboard, REST, MCP signed URL) uses the same per-type ceiling. A network that officially allows more is still clamped here. The editor, REST API, and MCP then apply a tighter per-content_type cap when the network’s API is smaller than that hard cap. GET /content-types is the live catalog — do not hard-code a second table of numbers. Files over 1 MB are sent in chunks (the dashboard streams them via Content-Range to the chunked upload endpoint) so big videos transfer reliably even on flaky connections. On self-hosted instances, raising the video cap also requires bumping PHP’s upload_max_filesize / post_max_size and any reverse-proxy body-size cap to match. Signed upload URLs are single-use and expire after 15 minutes by default (MEDIA_SIGNED_UPLOAD_URL_TTL_MINUTES; legacy fallback MCP_UPLOAD_URL_TTL_MINUTES).

What TryPost does to your files

Images — we convert and, on most networks, resize.
  • On store: PNG and WebP become JPEG. JPEG and GIF stay as they are.
  • On publish, Instagram feed / carousel images are cropped to the feed window; Instagram Stories are fit onto a 9:16 canvas; Facebook feed images are cropped.
  • On publish, stills sent to X, LinkedIn, Pinterest, Mastodon, Bluesky, Discord (not GIF), and TikTok photos are resized into that network’s image budget and written as JPEG.
  • Threads and Telegram receive the original URL — no crop and no optimize pass.
Videos — we do not transcode. Upload accepts MP4 and MOV. What you attach is what the network receives (after the size / duration checks below). There is no FFmpeg step. GIF: only X, Bluesky, Mastodon, Discord, and Telegram accept an animated GIF. The editor blocks GIF on every other content_type. MOV: accepted on every network. Bluesky’s stored embed is MP4, but its video service accepts MOV (video/quicktime) and transcodes it — the same list as the official app.

Enforced on the server, not just in the editor

Every publish or schedule — dashboard, PUT /posts/{post} with status: publishing|scheduled, and MCP publish-post-tool — re-checks each enabled platform’s content_type against the post’s media and fails with a validation error on platforms.<n>.content_type when:
  • the media kind is not supported (a video on pinterest_pin, a PDF outside LinkedIn, images mixed with a video where the network takes one or the other);
  • a GIF lands on a type that does not accept it;
  • a file’s size is over the type’s byte cap (the ~900 MB Instagram Reel is refused here, before Meta ever sees it);
  • a video’s duration is over the type’s cap. Duration is read from the file’s MP4/MOV header on the server when it is stored — dashboard upload, POST /posts/{post}/media, signed upload URL, or a public URL — so it is known for every path. A file whose container carries no duration (a fragmented MP4) is checked by size only.
Drafts are never blocked: the checks run on publish and schedule only. Media attached before this check existed may lack size and is not size-checked until re-attached.

Size catalog (Cloud)

Numbers below are what the editor and GET /content-types enforce after the Cloud hard cap (10 MB image / 1 GB video). A dash means that media kind is not accepted for the type. LinkedIn PDF posts: 100 MB. Bluesky’s 300 MB is the lexicon’s exact decimal value (300 000 000 bytes), not MiB; its images are not capped below the hard cap because TryPost re-encodes every non-GIF image under Bluesky’s 2 MB blob limit at publish (a GIF over 2 MB still fails at publish). TikTok’s 10 minutes is the developer-upload ceiling; TikTok may return a lower per-creator limit (creator_info), which is enforced at publish. There is no linkedin_carousel, linkedin_page_carousel, or instagram_carousel content type on posts. Multi-image Instagram posts use instagram_feed. LinkedIn multi-image / PDF posts use linkedin_post / linkedin_page_post (format is inferred from the attached media; optional meta.document_title for PDFs).

Limits by content type

Each block is the TryPost-enforced cap plus the official spec page we follow. Aspect windows are the editor cropper bounds.

Instagram

Official: IG User Media — Image, Reel, Story specs. Instagram has no plain feed-video container any more: a single video on instagram_feed is published through the Reels container, and a video inside a multi-item feed post goes out as a carousel child (media_type=VIDEO). Meta only documents the Reel spec, so the 100 MB / 60 seconds on instagram_feed is TryPost’s conservative rule (same as Stories), not a Meta number. Pick instagram_reel for anything longer or larger — it unlocks the official 300 MB / 15 minutes.

Facebook

Official: Reels Publishing API, Page Stories API, Video API error codes.

Threads

Official: Overview — Image / Video Specifications and Threads Posts.

X (Twitter)

Official: Media best practices. These are Post (tweet_video) limits — 8 GB / 20 minutes is the default entitlement, X Premium raises it to 16 GB / 125 minutes — not Direct Message (dm_video) limits, and not the amplify_video Ads category. TryPost always uploads Post videos as tweet_video. The 1 GB you see in the editor is the Cloud upload cap, not an X limit; self-hosted installs that raise MEDIA_VIDEO_MAX_SIZE_MB get up to 8 GB on X.

LinkedIn

Official: Videos API, Images API, Documents API. Images, a video, and a PDF cannot be mixed on one post.

TikTok

Official: Media Transfer Guide. 10 minutes is TikTok’s ceiling for API uploads. creator_info can return a shorter max_video_post_duration_sec for a given account; the editor shows it and publishing enforces it.

YouTube

Official: videos.insert. Shorts length is a product rule: 3-minute Shorts.

Pinterest

Official: Creating boards and pins, Pinterest product specs.

Bluesky

Official: app.bsky.embed.video (maxSize 300 000 000; stored blob is video/mp4), app.bsky.embed.images (maxSize 2 000 000). The video service that receives the upload also accepts MOV, MPEG, WebM, and GIF — same MIME list as the official app. The lexicon carries no duration; the 10-minute limit is the video service’s, announced by @bsky.app on 26 August 2026. Images and a video cannot be mixed (the embed is images XOR video). Self-hosted: BLUESKY_VIDEO_MAX_BYTES is the publisher’s skip threshold and defaults to the same 300 000 000 — leave it alone unless the lexicon changes.

Mastodon

Official: Attachments and Instance.media_attachments. Instance defaults vary. TryPost stays on 10 / 40 MB rather than assuming a 99 MB host.

Discord

Official: Uploading Files (20 MiB default for bots).

Telegram

Official: Sending files, sendPhoto, sendVideo. TryPost publishes Telegram media by URL, not multipart upload, so the caps are 5 MB (photo) and 20 MB (video) — not the 10 / 50 MB multipart figures.

Media ordering

Drag attachments in the post editor to reorder them. The order you set is the order they’ll appear on the social platform — important for carousels and multi-image posts.

File storage

Media files are stored on the disk configured by FILESYSTEM_DISK. Out of the box, TryPost ships with these drivers: Any S3-compatible service (MinIO, DigitalOcean Spaces, Backblaze B2) works under the s3 driver with the right endpoint.
On TryPost Cloud, media storage is handled automatically. Self-hosted users should configure cloud storage for production — see the Configuration guide.

FAQ

Cloud upload: 10 MB per image, 1 GB per video, 100 MB per PDF. Many networks are tighter than that — see the size catalog. Files over 1 MB are sent through the chunked upload endpoint via Content-Range headers. Self-hosters can raise the upload caps with MEDIA_IMAGE_MAX_SIZE_MB / MEDIA_VIDEO_MAX_SIZE_MB / MEDIA_DOCUMENT_MAX_SIZE_MB.
An Instagram Reel may be at most 300 MB (and 15 minutes). Meta pulls the file from a public URL (video_url); a ~900 MB file misses that window even though Cloud upload allows 1 GB. Compress or trim the clip, or pick a different network. Resumable / rupload is not available yet.
instagram_feed keeps video at 100 MB / 60 seconds. That is TryPost’s conservative rule (the same as Stories), not a Meta figure — Meta only documents the Reel spec, and a single feed video is published through the Reels container anyway. Switch the content type to Reel (instagram_reel) for anything longer: up to 300 MB / 15 minutes.
Upload checks the Cloud hard cap only; publish and schedule check the per-content_type cap and format rules (see Enforced on the server). The response is a 422 with the message under errors["platforms.<n>.content_type"], e.g. Video exceeds the 300 MB limit for this post type (yours is 900.0 MB). Fix the file, or change the platform’s content_type, then publish again.
TryPost sends Telegram photos and videos as a URL, and Telegram’s URL path is 5 MB (photo) / 20 MB (video). Multipart upload would allow 10 / 50 MB — that is not the path we use.
Yes. The official app and video service accept .mov (video/quicktime) and transcode it to the MP4 blob Bluesky stores. TryPost sends the file as-is.
Yes — store the file in the Asset Library, then attach it with POST /posts/{post}/media/from-asset or MCP attach-existing-asset-tool. The post snapshot shares the library file path. You can also upload again via POST /posts/{post}/media or POST /posts/{post}/media/from-url.
The media records are removed along with the post.
On store, PNG and WebP become JPEG. On publish, most networks get a cropped or optimized JPEG (see What TryPost does to your files). Videos are never transcoded. After that, each network may compress again.