Upload Media
twitter.upload_media
ActionChat & messagingconnection required
Calls the X (Twitter) API with the connection's credentials.
Upload an image, GIF or short video and get the media id to attach to a post or a direct message.
Connection
- Required
- Yes — the node will not save without one
- Auth type
- Bearer token
- Providers
- X (Twitter)
- Secret shape
- the X OAuth2 user-context access token, or {"access_token": "…"}
- Resolved by
- config.connection_id, else node.connection_id
Configuration
3 fields, 2 required. A dotted path is a nested object and name[] an array of objects — the editor renders the same tree.
| Field | Type | Required | Default | Constraints | Example |
|---|---|---|---|---|---|
file_content The file, base64-encoded — e.g. {{ $json.file_content }} from a node that emits a file blob. | string | Yes | — | — | R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 |
media_category What the file is for. X validates the file against this. | string | Yes | — | one of "tweet_image", "tweet_video", "tweet_gif", "dm_image", "dm_video", "dm_gif", "subtitles" | — |
additional_owners Comma-separated user ids also allowed to attach this media. | string | No | — | — | — |
Example configuration
Every value below is the contract’s own example or default — nothing invented.
{
"file_content": "R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
}Output
One shape.
result
| Field | Type | Example |
|---|---|---|
id The media id to pass to create_post or send_direct_message. | string | — |
media_key The media key, for the media lookup endpoints. | string | — |
size Bytes X stored. | number | — |
expires_after_secs Seconds until an unattached upload is dropped. | number | — |
processing_info Async transcoding state for video and GIF; empty for a finished image. | object | — |
{
"expires_after_secs": 0,
"id": "",
"media_key": "",
"processing_info": {},
"size": 0
}Notes
- X API access is tiered and metered: most read endpoints need a paid plan, and since 6 February 2026 new developers get pay-per-use credits rather than a free tier. A 403 here usually means the plan, not the code.
- The connection's access token must already carry the scopes this node needs; X does not grant them per call, so a missing scope is a 401 on every run.
- Needs the OAuth2 scopes media.write.
- This is the one-shot upload (POST /2/media/upload), which replaced the upload.twitter.com/1.1 endpoints when they were sunset on 9 June 2025. Large videos need the chunked INIT/APPEND/FINALIZE flow, which this node does not do.
- An uploaded media id expires within a day if nothing attaches it, and video and GIF uploads finish transcoding asynchronously — check processing_info before posting.
See Upload Media run in a workflow.
In a technical demo we add the X (Twitter) connection, drop the node on the canvas and let Workflow Health pre-flight it before the first real run.