Uploading Media
Guide to Uploading Media
There are a few important concepts to understand when using the POST media/upload endpoint. Uploading media with OAuth can be a bit tricky, so we’ve outlined some things to keep in mind as well as a working sample of how to use this endpoint here.
Keep in mind
- Because the method uses multipart POST, OAuth is handled a little differently. POST or query string parameters are not used when calculating an OAuth signature basestring or signature. Only the
oauth_*
parameters are used. - The maximum image size for this endpoint is 5MB. Depending on how the image is used, further limits apply. For example, if the image is attached to a Tweet, the maximum limit in this case is 3MB.
- The maximum video size for organic Tweets is 15MB.
- You may include up to 4 photos or 1 animated GIF or 1 video in a Tweet.
- Users have a separate, published daily media upload limit that is independent of their unpublished daily status update limits.
- The image passed should be the raw binary of the image or binary base64 encoded, no need to otherwise encode or escape the contents as long as the Content-Type is set appropriately (when in doubt:
application/octet-stream
). - Supported image formats: PNG, JPEG, WEBP and GIF. Animated GIFs are supported.
- Supported video formats: MP4
- When posting base64 encoded images, be sure to set the “Content-Transfer-Encoding: base64” on the image part of the message.
- Multi-part message boundaries must be on their own line and terminated by a CRLF.
- For working examples of how to POST using this endpoint, we recommend testing with twurl. Also take a look at the Twitter Libraries available.
Video specifications and recommendations
In addition to the 15MB file size limit, videos must meet the following criteria inclusively:
- Duration should be between 0.5 seconds and 30 seconds
- Dimensions should be between 32x32 and 1280x1024
- Aspect ratio should be between 1:3 and 3:1
- Frame rate should be 40fps or less
- Audio should be mono or stereo
The media platform is optimized to handle the specifications of video captured on mobile devices. For developers creating their own video (i.e. not uploading video captured directly from a mobile device), please refer to the table below. Each row represents an upload recommendation, but is not a requirement. All uploads are processed for optimization across multiple platforms.
Orientation | Width | Height | Video Bitrate | Audio Bitrate |
---|---|---|---|---|
Landscape | 1280 | 720 | 2048K | 128K |
Landscape | 640 | 360 | 768K | 64K |
Landscape | 320 | 180 | 256K | 64K |
Portrait | 640 | 640 | 1024K | 96K |
Portrait | 480 | 480 | 768K | 64K |
Portrait | 240 | 240 | 256K | 64K |
Example of image media/upload
As of Twurl v0.9.0 (see our command-line twurl tool) support for calling Twitter’s v1.1 REST API with a multipart message for the POST media/upload endpoint now exists. Use this example as a great way to debug your own code. Note that many of the Twitter Libraries include methods that will handle this POST correctly for you.
Using the -t
option will show you the full trace of the request and response that was POSTed to the Twitter API.
twurl -H upload.twitter.com -X POST "/1.1/media/upload.json" --file "/path/to/media.jpg" --file-field "media"
{ "media_id": 553656900508606464, "media_id_string": "553656900508606464", "size": 998865, "image": { "w": 2234, "h": 1873, "image_type": "image/jpeg" } }
Example of chunked video media/upload
Using the chunked POST media/upload endpoint requires an adjusted workflow from single image uploads. For video or chunked uploads, you must:
- Initialize the upload using the
INIT
command - Upload each chunk of bytes using the
APPEND
command - Complete the upload using the
FINALIZE
command
Below is a working example of this. To see full headers of the requests and responses when using twurl
, use the -t
option to enable trace mode.
INIT
twurl -H upload.twitter.com "/1.1/media/upload.json" -d "command=INIT&media_type=video/mp4&total_bytes=4430752"
{ "media_id": 601413451156586496, "media_id_string": "601413451156586496", "expires_after_secs": 3599 }
APPEND
twurl -H upload.twitter.com "/1.1/media/upload.json" -d "command=APPEND&media_id=601413451156586496&segment_index=0" --file /path/to/video.mp4 --file-field "media"
HTTP 2XX
will be returned with an empty response body on successful upload.
FINALIZE
twurl -H upload.twitter.com "/1.1/media/upload.json" -d "command=FINALIZE&media_id=601413451156586496"
{ "media_id": 601413451156586496, "media_id_string": "601413451156586496", "size": 4430752, "expires_after_secs": 3600, "video": { "video_type": "video/mp4" } }