Skip to content
Social SDK megaphone markSocial SDK
Esc
navigateopen⌘Jpreview
On this page

Media

Attach images, video, and documents through URLs, blobs, streams, and uploaded references with bounded memory and explicit processing states.

Media attachments describe real bytes and where they come from. The SDK bounds what it buffers, validates what each platform accepts, and keeps processing states explicit.

Four media sources

Every attachment names a kind (image, video, or document) and a source. Document attachments cover paged files such as PDF, PPTX, or DOCX, and only adapters that declare the document format accept them.

// A public HTTPS URL the platform fetches itself
{ kind: "image", source: { kind: "https-url", url: "https://cdn.example.com/a.jpg" } }

// Bytes you hold in memory
{ kind: "video", source: { kind: "blob", blob, fingerprint: contentHash }, mimeType: "video/mp4", byteSize: blob.size }

// A replayable stream factory for large files
{ kind: "video", source: { kind: "stream", open: () => file.stream(), fingerprint: contentHash } }

// A previously uploaded, account-bound media reference
{ kind: "image", source: { kind: "media-ref", ref: mediaRef } }

Blob and stream sources require a content fingerprint, which feeds idempotency so a retried request reuses the same upload identity. Optional fields like mimeType, byteSize, dimensions, durationSeconds, altText, and captions travel with the attachment where platforms accept them.

Streams are bounded and replayable

Uploads read streams with bounded buffering, so a large video does not sit fully in memory. The source must be replayable: the adapter may need a fresh stream for a retry, which is why the stream source is a factory function rather than a consumed stream.

Platforms differ, loudly

Each adapter validates media against its platform’s real rules during local preparation: which sources it accepts, size ceilings, item counts, required fields. TikTok accepts verified HTTPS origins only. The X adapter uploads images up to 5 MiB each; video and GIF uploads are not supported yet. LinkedIn accepts one MP4 video per post, uploaded from a Blob of 75 KB to 500 MB, and publishes it only after LinkedIn reports it AVAILABLE. LinkedIn also accepts one uploaded PDF, PPT, PPTX, DOC, or DOCX document per post, up to 100 MB, with a required title. Bluesky posts take up to four images or one MP4 video that was uploaded first with media.upload. YouTube requires exactly one video with explicit visibility. Nothing is silently cropped, converted, or dropped; unsupported input fails preparation with a structured issue. The platform pages document each rule set.

Upload once, reference later

Where a platform separates upload from publishing, social.media.upload returns an account-bound media reference you can persist and use in later publish requests through the media-ref source. Adapters check upstream readiness before publishing; a still-processing upload needs an explicit later status check, never background polling.

Processing is a state, not a promise

Video pipelines return processing outcomes: the upload completed but the platform is still working. Keep the delivery reference and reconcile explicitly. A confirmed platform identity produces published; a confirmed rejection produces failed; a lost response stays unknown until reconciled. See references and outcomes.

Last updated on September 24, 2026