Publishing

Media & Uploads

Attach images, videos and PDFs by public URL or from your project's media library.

Posts can carry up to 10 media items in the media array. Every target in the post gets the same media. Each item points to a file in one of two ways:

  • A public URL (https://...) that the platform can download.
  • A media library reference (media://<id>) to a file you've uploaded in the dashboard.
{
  "content": "Behind the scenes at the shoot",
  "targets": [{ "accountId": "8f1c2a4e-5b6d-4e7f-9a0b-1c2d3e4f5a6b" }],
  "media": [
    { "url": "https://cdn.example.com/bts-1.jpg", "type": "image", "altText": "Crew setting up lights" },
    { "url": "media://3f2e1d0c-4b5a-4968-8776-5a4b3c2d1e0f", "type": "image", "altText": "Camera on a dolly" }
  ],
  "publishNow": true
}

Media item fields

FieldTypeRequiredDescription
urlstringYeshttp(s) URL or media://<id>, up to 2,048 characters.
typestringYesimage, video or document.
altTextstringNoUp to 1,000 characters. Passed to platforms that support alt text.
titlestringNoUp to 400 characters. Title shown on a document card (documents only).
  • GIFs use type: "image". Platforms that treat GIFs specially detect them from the .gif file extension.
  • Documents are PDFs and are only supported on LinkedIn. Sending a document to any other platform fails validation with 400.

Public URLs

When you use a URL, the platform (or Relaycast on its behalf) downloads the file at publish time, not when you create the post. So:

  • The URL must be publicly reachable without cookies or authentication. Signed URLs work if they're still valid when the post publishes.
  • For scheduled posts, keep the file available until the scheduled time.
  • Use a URL path that ends in the real file extension (.jpg, .png, .mp4, .gif). Some platform checks use it, for example Instagram only accepts JPEG images and X detects GIFs from it.
  • If the download fails, the target fails with errorCode: "media_error". A 4xx response from your server is treated as permanent, while a 5xx or network error is retried.

URLs pointing at localhost, private networks or pages that need a login will fail at publish time. If you're testing locally, upload files to the media library instead.

Media library

The media library stores files privately in your project. Use it when you don't have your own public hosting, or when you don't want files to be publicly reachable.

Upload

Uploads happen in the dashboard. In the Playground, open the media panel and use the Upload tab, or pick an earlier upload from the Library tab. Accepted files:

KindTypes
ImageJPEG, PNG, WebP
GIFGIF
VideoMP4, MOV (QuickTime)
DocumentPDF

Files can be up to 150 MB. Individual platforms have their own, often smaller, limits. See the platform guides.

The public API has no media upload endpoint. Upload in the dashboard and reference files by ID, or host files yourself and pass public URLs.

Reference library files

Each upload has a reference of the form media://<id>. After adding a library file in the Playground, the Live request panel shows the exact media item to copy into your own requests.

When you create a post, Relaycast checks that every media:// reference belongs to your project. Unknown references are rejected before anything is created:

{
  "error": {
    "code": "unknown_media",
    "message": "Some media library items were not found",
    "details": { "missing": ["media://3f2e1d0c-4b5a-4968-8776-5a4b3c2d1e0f"] }
  }
}

At publish time, each reference is turned into a short-lived signed URL that only the platform uses to download the file. The file itself never becomes public.

media:// references also work inside platform options that take an image, such as a custom video thumbnail.

Deleting library files

If you delete a library file while a scheduled post still uses it, that post's targets fail at publish time with a message saying the item was deleted. Posts that already published aren't affected, because the platform keeps its own copy.

Per-platform rules

Validation runs per target when you create the post, so a mismatch shows up as a 400 before anything is charged. Typical rules:

  • Bluesky: up to 4 images or one video, not both.
  • X (Twitter): up to 4 images, or one video, or one GIF.
  • YouTube: exactly one video.
  • TikTok: one video or a set of photos, not both.
  • Instagram: at least one image or video, JPEG images only.

These are examples, not a complete list. Each platform guide lists its media rules, and the Playground shows them live as you compose.

This page is also available as Markdown.