media array. Each item names where the media comes from with source_type, so one list can mix an uploaded file, a public URL, and media you uploaded to a platform yourself. Order is preserved and decides carousel sequence.
The older
media_ids array still works and is not going away without notice. ["abc"] is exactly equivalent to [{ "source_type": "media_id", "source": "abc" }]. If you send both, media wins and media_ids is ignored. Responses continue to include media_ids alongside media, listing the media_id items only.Choosing an upload path
There are two ways to get a file into SocialAPI. Both return amedia_id that you use the same way.
If a file is larger than 50 MB, use the presigned-URL path.
Server-side upload
Send the file as multipart form data in a single request. Thefile field is required.
ready. Pass it as a media_id source on your next POST /v1/posts call (see Using media in posts).
Presigned URL upload
Use this path for large files. It has three steps: request a signed URL, upload the bytes to it, then verify. Step 1: Request a signed upload URL. Bothmedia_type (the file’s MIME type) and filename are required.
upload_url is valid for 15 minutes.
Step 2: Upload the file with an HTTP PUT to upload_url. The Content-Type must match the media_type you declared in step 1.
pending to ready.
Using media in posts
Pass themedia array on POST /v1/posts. Order is preserved. A single entry produces an image or video; multiple entries produce a carousel, subject to each platform’s limits.
media is also accepted per target, where it overrides the post-level list for that platform only. A target that sets no media inherits the post-level one.
Per-platform media limits (image versus video, carousel counts, maximum items per post) are listed in the Posts overview capability matrix.
Publishing from a public URL
Setsource_type to url and we fetch the file at publish time. Nothing is stored in your media library and no storage quota is consumed.
http or https. URLs resolving to private, loopback, link-local, or otherwise internal addresses are rejected. The check runs again at publish time, so a URL that stops resolving publicly between scheduling and publishing fails the post rather than silently dropping the media.
Because the fetch happens when the post publishes, the URL must still be live at that moment. For a post scheduled weeks out, an uploaded media_id is the safer choice: a link that expires or rotates in the meantime will fail the post.
Publishing a platform attachment ID
If you have already uploaded media to a platform through its own API, pass that ID directly and we publish it without re-uploading.type is required here (image, video, audio, or file). For url and media_id we infer it from the file, but a platform attachment ID is opaque to us, so you have to declare it.
Supported on Instagram, Threads, LinkedIn, LinkedIn Page, and X/Twitter. Any other platform returns 422 publishing.media.unsupported_source.
Mixing rules differ by platform:
On Instagram and Threads a
platform_attachment_id is one finished, publishable container (a single photo or video, or a carousel you assembled yourself), so it cannot be combined with anything else. Sending more than one item returns 422 publishing.media.mixing_unsupported. To build a mixed carousel there, pass url or media_id items and we assemble it for you.
These gates are per target: a post can still publish to its other targets when one target is rejected.
Managing your library
List media. Returns yourready files, newest first, with cursor pagination (default 50 per page, max 100). Each item includes a short-lived url for previewing the file.
X-Storage-Used and X-Storage-Limit response headers on media requests (-1 means unlimited).
Storage limits
An upload that would exceed your quota returns
413. On the presigned path the object is removed and the media is marked failed.
Constraints and gotchas
- A public URL now publishes directly as a
urlsource. In the deprecatedmedia_idsarray a raw URL is still ignored:media_idsonly accepts media library IDs. urlsources are fetched at publish time and must still be reachable then. Prefer an uploadedmedia_idfor posts scheduled far ahead.platform_attachment_idrequires an explicittype, works only on Instagram, Threads, LinkedIn, LinkedIn Page, and X/Twitter, and cannot be mixed with other media on Instagram or Threads.- The verify step is mandatory on the presigned path. Without it, media stays
pendingand publishing fails withMedia not found. - The server-side upload endpoint caps files at 50 MB. Use the presigned path for anything larger.
- Media has three states:
pending(created, bytes not yet confirmed),ready(usable in posts), andfailed(quota exceeded, or the object was missing at verify). - Video duration is detected automatically at verify or upload time. You do not need to send it.
- Per-platform format, size, and count rules are enforced when you publish. See each platform’s posts page.