Guides

Uploading media

Posts reference media by URL. Upload your own files with a signed URL, or point at any file that is already publicly reachable.

Upload in three steps

  1. Ask for an upload URL

    Call POST/media/presign with the file's name, type and exact size in bytes. Needs the media:write scope.

    Request
    curl -X POST "https://dashboard.lifebliss.app/api/v1/media/presign" \
      -H "Authorization: Bearer $PS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "filename": "talk.mp4", "contentType": "video/mp4", "size": 48213004 }'
    Response · 200
    {
      "uploadUrl": "https://…signed…",
      "publicUrl": "https://…/talk.mp4",
      "storageKey": "…",
      "method": "PUT",
      "expiresIn": 3600
    }
  2. Upload the file

    PUT the bytes to uploadUrl within an hour, with the same Content-Type you asked for. No API key — the URL is the permission.

    Request
    curl -X PUT "$UPLOAD_URL" \
      -H "Content-Type: video/mp4" \
      --data-binary @talk.mp4
  3. Attach it to a post

    Use publicUrl in mediaItems (or a target's customMedia). type is image, video, gif or document.

    POST /posts — body
    {
      "content": "The full session is live.",
      "mediaItems": [
        { "type": "video", "url": "PUBLIC_URL", "altText": "Recording of the evening session" }
      ],
      "targets": [{ "accountId": "YOUTUBE_ACCOUNT_ID" }],
      "publishNow": true
    }

In Node.js

upload.mjs
import { readFile, stat } from "node:fs/promises";

const file = "talk.mp4";
const { size } = await stat(file);

const presign = await fetch(`${API}/media/presign`, {
  method: "POST",
  headers,
  body: JSON.stringify({ filename: file, contentType: "video/mp4", size }),
}).then((r) => r.json());

await fetch(presign.uploadUrl, {
  method: "PUT",
  headers: { "Content-Type": "video/mp4" },
  body: await readFile(file),
});

// presign.publicUrl now goes in mediaItems

Using existing URLs

If the file is already online, skip the upload and put its URL straight into mediaItems. It must be publicly reachable over http(s); otherwise the post is refused with 422 media_unreachable, naming the URL. Adding size and durationMs when you know them lets each network's size and length limits be checked before publishing.

Types and limits

Uploads accept:

  • image/jpeg
  • image/png
  • image/webp
  • image/gif
  • video/mp4
  • video/quicktime
  • video/webm

Up to 5 GB per file. Each network then applies its own limits on size, length and count — check them with GET/validate or POST/validate.