Attach media to a post
Upload images or video by URL or signed upload, attach ready assets, and validate channel limits.
Upload an image or video, wait until the asset is ready, then attach its id to your post. Use a public URL when the file is already hosted, or a signed upload when your app holds the bytes. Both paths create an asset in the product’s bucket.
Replace the example URL and <asset id>, <post id> and <channel id> with your file URL and the ids returned by Content.
Before you start
- For MCP calls, use a token with product-scoped write access for the Content operations below.
- A post in
draft,pending_approvalorapprovedstate. Attaching is an edit, and ascheduledorpublishedpost cannot be edited. - Files that are
image/*orvideo/*. Nothing else is accepted — this publishes to social networks. - Each asset no larger than 512 MB.
- A post carries at most 20 attachments, and a channel may accept fewer. Check
maxMediaandsupportsVideoon the channel in Channels before you attach.
Option A: from a URL
Choose this path for a file available at a public http(s) URL.
-
Create the asset from its URL:
content_media_upload sourceUrl: "https://example.com/screenshot.png"Content downloads the file server-side. The source must provide
Content-Typeand a nonempty image or video no larger than 512 MB. -
Read the asset back until its
statusisready:content_media_get id: <asset id>If the fetch fails, the asset has
status: "failed"and anerrorexplaining the failure. Check those fields before continuing; a failed fetch returns an asset instead of raising an error.
Option B: by signed upload
Choose this path to upload bytes directly from your app.
-
Request an upload URL with the file’s media type:
content_media_create_upload_url contentType: "image/png"The response includes a pending asset, signed
uploadUrl,expiresAtandcontentType. Upload before expiry and use that exact content type: it is part of the signature. -
PUTthe bytes straight to that URL, with that exactContent-Typeheader. -
Finalize the upload:
content_media_finalize id: <asset id>Finalization checks the stored object and marks the asset
ready. Calling it before the upload exists fails.
Attach it
content_posts_attach_media
id: <post id>
mediaIds: [<asset id>]Pass 1 to 20 asset ids in display order. To remove assets, call content_posts_detach_media; the remaining assets keep their order.
Every asset must be ready and belong to the post’s product. If either condition fails, the post stays unchanged. An asset already attached to the post is not added again.
Attaching and detaching both create a version. Complete these changes before submission: changing an approved post returns it to pending_approval and requires another approval. See Posts.
Check it worked
content_publications_validate
postId: <post id>
channels: [{ channelId: <channel id> }]Check for media issues in the validation result; ok: true means no issue blocks scheduling. The media issue codes are media_missing for an asset that does not exist, media_not_ready for one that is not stored yet, media_not_supported for one the network will not take, too_many_media for more attachments than the channel accepts, and video_required when the selected post type requires video, including YouTube uploads, but none is attached.
The shape of an asset
Field | What it is |
|---|---|
id | Media asset id — this is what you attach to a post |
key | Object key in the product bucket. Private; it is not a URL |
mime | Stored media type, or null while pending |
sizeBytes | Stored size, or null while pending |
status | pending, ready or failed |
source | url (fetched by Content) or upload (sent by your app) |
sourceUrl | The URL the bytes were fetched from, if any |
filename | The original filename, kept for display |
error | Why the asset failed, or null |
createdAt, updatedAt | ISO-8601 timestamps |
Listing and storage
content_media_list returns assets newest first, with total counting every match regardless of paging. Filter by status; page with limit (1 to 100, default 50) and offset.
Storage metering uses the latest total bytes stored for the product. Each reading is a complete total, so do not add successive readings together.
Tools
Tool | What it does |
|---|---|
content_media_upload | Ingest media from a public http(s) URL |
content_media_create_upload_url | Get a signed PUT URL and a pending asset |
content_media_finalize | Confirm a signed upload and make the asset ready |
content_media_get | Read one asset |
content_media_list | List assets, newest first |
content_posts_attach_media | Attach ready assets to a post |
content_posts_detach_media | Remove assets from a post |
Next steps
- Channels:
maxMedia,supportsVideoandsupportsLink, per network. - Publications: the rest of the validation report.