Glossary

Every Twitter API media_category Value and What It Permits

Taras Shynkarenko
Taras Shynkarenko
Updated: 7 min read
The twitter api media_category values for Posts, DMs and adsThe twitter api media_category values for Posts, DMs and ads

TL;DR, Quick Answer

7 min read

media_category tells X what the file is for. The initialize endpoint accepts eight values, tweet_image, tweet_video, tweet_gif, amplify_video, dm_image, dm_video, dm_gif and subtitles, and X uses the value to pick which size and duration ceiling to enforce. tweet_video and amplify_video share the same caps on a Post, 20 minutes and 8 GB by default and 125 minutes and 16 GB for Premium, while the Ads API page still says promoted video tops out at 10 minutes and 500 MB. Omitting the value makes X guess from the content type.

What is the twitter api media_category parameter?

Eight values exist for the twitter api media_category parameter, and X defines the job it does in one line: "The Media Category parameter defines the use case of the media file to be uploaded, and can affect file size limits or other constraints enforced for media uploads."

Use case, not file type. media_type already tells X that the bytes are an MP4. media_category tells X whether that MP4 is going on a Post, into a Direct Message or into an ad, and X picks a different ceiling for each answer.

The parameter is optional on POST /2/media/upload/initialize and X documents the fallback: "If media category is not specified, the uploaded media is assumed to be media for a Post (tweet_image, tweet_video, or tweet_gif), depending on the content type."

That default covers Posts and nothing else. Anything bound for a DM, an ad or a subtitle track has to say so, because X has no way to infer it from an MP4.

What does each twitter api media_category value permit?

Each value maps to one surface, and X publishes the complete enum on the initialize endpoint schema.

ValueSurface it permitsDefault capX Premium cap
tweet_imageImage on a Post5 MB5 MB
tweet_gifAnimated GIF on a Post15 MB15 MB
tweet_videoVideo on a Post20 min, 8 GB125 min, 16 GB
amplify_videoAds and promoted video20 min, 8 GB125 min, 16 GB
dm_imageImage in a Direct Message5 MB5 MB
dm_gifAnimated GIF in a Direct Message15 MB15 MB
dm_videoVideo in a Direct Message140 s, 512 MB10 min, 1 GB
subtitlesSubtitle file1 MB1 MB

Minimum video duration is the same across every video category. X states it as "0.5 seconds" and repeats it as a floor rather than a recommendation.

Two values carry an instruction beyond their limits. amplify_video is required rather than optional for anything promoted, and the Ads API has said so since 2015: "When uploading videos to be used in promoted content, the media_category parameter must be set with a value of amplify_video for all INIT command requests." tweet_gif is the switch that turns on asynchronous processing for large animated GIFs, which X spells out on the best practices page: "In order to process larger GIFs, use the chunked upload endpoint with the media_category parameter. This allows the server to process the GIF file asynchronously, which is a requirement for processing larger files."

A phone displaying a video file mid-upload, representing the size and duration checks a media_category triggers.

How does media_category change the size and duration caps?

The category selects which row of X's limit table applies, and the account's subscription selects which column. X names both inputs: limits depend on "the authenticated user's X Premium / verified status, not your developer API plan" and on "the media_category you pass when initializing the upload."

The spread between the categories is wide. A video that fits tweet_video at 20 minutes has to be under 140 seconds to go out as dm_video on the same account, and under 10 minutes even with Premium. Same file, same account, same endpoint, and a factor of eight between the two ceilings.

total_bytes is checked against the category too. X writes that "POST /2/media/upload/initialize accepts total_bytes up to 16 GB. Passing a larger total_bytes than the account is allowed to upload fails at initialize or finalize." Two failure points are named and X does not say which one catches it, so treat both INIT and FINALIZE as places a size rejection can surface.

The category does not change the image rules. Images stay at 5 MB and animated GIFs at 15 MB whether they are bound for a Post or a DM, and Premium moves neither number. Only video duration and video file size respond to the subscription, which is a narrower effect than the full set of X Premium entitlements suggests.

A team reviewing a video ad campaign on a laptop, tied to the separate size limits promoted video uploads face.

Why does X publish two different limits for amplify_video?

Because the Ads API creatives page and the media documentation disagree, and both are live.

The media pages treat amplify_video as an equal of tweet_video. The best practices page says it outright: "For Posts, Premium and default duration/size caps are the same for tweet_video and amplify_video." Its table gives both 20 minutes and 8 GB by default, 125 minutes and 16 GB with Premium.

AdaptlyPost
AdaptlyPost

Start 7-Day FREE Trial

All-platform analytics

Social Inbox

AI-powered assistant

The Ads API creatives page, in the Promoted Video section, gives a different pair of numbers in a single bullet: "The maximum promoted video length currently allowed is 10 mins with a file size of 500MB or less." It adds a format constraint the media pages do not mention either: "Uploaded video should be either mp4 or mov."

Ten minutes against 125. Five hundred megabytes against 16 gigabytes. Nothing on either page acknowledges the other, and neither carries a date beyond the 2015 note attached to the bullet above it. Build for the smaller pair if the video is going into a campaign, because the ads pipeline is the one that would reject it.

A second mismatch shows up one layer along. The upload endpoints take lowercase values. The Ads API media library takes uppercase ones: "There are four possible category values: AMPLIFY_VIDEO, TWEET_GIF, TWEET_IMAGE, and TWEET_VIDEO." Same four concepts, two spellings, and the media library list omits the DM and subtitle categories entirely.

What happens when you pick the wrong media_category?

The upload succeeds and the next call fails. X names this as the common case: "Using the wrong category (for example a DM category on a Post) is a common reason an upload succeeds and Post create then fails."

That is the shape of almost every media_category mistake. INIT accepts the value, APPEND moves the bytes, FINALIZE returns a clean processing_info, and the rejection arrives at POST /2/tweets with a 403 because upload and posting are enforced separately. A 403 reading "This user is not allowed to post a video longer than N minutes" on a video well under the Post limit is usually a dm_video category doing exactly what it was told.

Three smaller traps sit in the same parameter.

The two upload endpoints do not agree on whether the parameter is optional. On POST /2/media/upload/initialize it is optional and the enum has eight values. On the simple POST /2/media/upload endpoint the schema lists media and media_category as required, and its enum has seven values with amplify_video missing. Promoted video therefore cannot go through the simple upload path at all, which matches X's separate advice to use chunked upload for all video regardless.

Omitting the value on a large GIF gives up the asynchronous processing that large GIFs need, because X ties that behaviour to passing tweet_gif rather than to the file itself.

And subtitles is the odd one out. It is the only value in the enum that is not an image, a GIF or a video, it caps at 1 MB, and its media_type values are text/srt and text/vtt. A subtitle file uploaded without it inherits the Post default and is graded against image rules it was never going to meet.

Every network solves this differently, and the category concept does not travel. Instagram splits the same decision across media_type and the reels specification instead, and TikTok resolves duration by account standing rather than by an upload parameter. On X, the whole decision lives in one optional string you send once, at INIT, and never get to change. If you set it wrong, the upload walkthrough has to start over from the beginning.

Where a wrong media_category actually fails
1
INIT. Accepts the value, no matter which surface it names.
2
APPEND. Moves the bytes without checking the destination.
3
FINALIZE. Returns a clean processing_info.
4
POST /2/tweets. Rejects with a 403 because upload and posting are enforced separately.
A wrong media_category passes every upload step and only surfaces at the Post call.

Frequently asked questions

What values does the twitter api media_category parameter accept?

Eight: tweet_image, tweet_video, tweet_gif, amplify_video, dm_image, dm_video, dm_gif and subtitles. That is the enum published on POST /2/media/upload/initialize.

Is media_category required on the X API?

It depends on the endpoint. POST /2/media/upload/initialize treats it as optional and guesses a Post category from the content type. The simple POST /2/media/upload endpoint lists it as required.

What is the difference between tweet_video and amplify_video?

Purpose, not size. X requires amplify_video for anything used in promoted content and says the duration and size caps for the two are the same on a Post. The Ads API creatives page still states a lower promoted video ceiling of 10 minutes and 500 MB.

How long can a dm_video be on the X API?

140 seconds by default and 10 minutes for an X Premium or verified account, with file size caps of 512 MB and 1 GB. Minimum duration is 0.5 seconds, same as every other video category.

What error do you get from the wrong media_category?

Usually a 403 Forbidden on POST /2/tweets rather than an error at upload time. X notes that a DM category used on a Post is a common reason an upload succeeds and Post creation then fails.

AdaptlyPost
AdaptlyPost

Start 7-Day FREE Trial

All-platform analytics

Social Inbox

AI-powered assistant

Does media_category affect image size limits?

No. Images stay at 5 MB and animated GIFs at 15 MB across Posts and DMs, and X Premium does not raise either. Only video duration and video file size change with the category and the subscription.

What's the difference between media_type and media_category on the X API?

media_type tells X the format of the file, for example video/mp4. media_category tells X what that file is for, a Post, a Direct Message, a subtitle track or an ad. X uses media_category, not media_type, to decide which size and duration ceiling applies.

What's the minimum video length the X API accepts?

The minimum is 0.5 seconds, and X states it as a floor rather than a recommendation. That minimum is the same across every video category, tweet_video, amplify_video, dm_video and the rest, so switching categories does not lower it.

What video format does the X Ads API require for promoted video?

The Ads API creatives page requires mp4 or mov for uploaded video in promoted content. It states this plainly: uploaded video should be either mp4 or mov. The media documentation pages do not repeat this constraint anywhere else.

Does the simple media upload endpoint support promoted video?

Promoted video cannot go through the simple upload endpoint. Its enum lists seven media_category values and leaves amplify_video out, while POST /2/media/upload/initialize keeps all eight. That gap lines up with X's separate advice to use chunked upload for all video regardless of category.

Was This Article Helpful?

Let us know what you think!

See us more often in Google

One click marks AdaptlyPost as a preferred source, so our articles sit higher in your Top Stories, AI Mode, and AI Overviews.

Before you go...

AdaptlyPost

AdaptlyPost

Schedule your content across all platforms

Manage all your social media accounts in one place with AdaptlyPost.

All-platform analytics

Social Inbox

AI-powered assistant

Related Glossary Terms

Related Articles