Skip to content

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_approval or approved state. Attaching is an edit, and a scheduled or published post cannot be edited.
  • Files that are image/* or video/*. 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 maxMedia and supportsVideo on 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.

  1. 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-Type and a nonempty image or video no larger than 512 MB.

  2. Read the asset back until its status is ready:

    content_media_get
      id: <asset id>

    If the fetch fails, the asset has status: "failed" and an error explaining 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.

  1. 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, expiresAt and contentType. Upload before expiry and use that exact content type: it is part of the signature.

  2. PUT the bytes straight to that URL, with that exact Content-Type header.

  3. 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, supportsVideo and supportsLink, per network.
  • Publications: the rest of the validation report.
Was this page helpful?
Esc

Start typing to search the docs.

↑↓navigate↵select