logo
Schedulin Developers

Upload media

Media is attached to posts by url. There are three ways to get a media url, in increasing order of effort — pick the first one that fits your client.

Option A — Upload a file directly (one call)

Send the raw bytes as multipart/form-data to POST /v0/media/upload. The server stores the file and returns the media record; use its url in your post.

curl -X POST https://api.schedulin.app/v0/media/upload \
  -H "x-api-key: sk_live_..." \
  -F "file=@launch.jpg" \
  -F "alt=Launch day"
{ "id": "med_123", "url": "https://r2.schedulin.app/<your-org>/<id>-launch.jpg", "...": "..." }

Accepts image, video, and audio up to 250 MB. SVG and other active content is rejected.

Option B — Import from a public URL

If the file is already hosted somewhere public, let the server fetch it with POST /v0/media/from-url — no bytes leave your machine:

curl -X POST https://api.schedulin.app/v0/media/from-url \
  -H "x-api-key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com/launch.jpg" }'

You can also skip this step entirely and pass a public url straight into the post's media array — POST /v0/posts imports any external URL for you automatically.

Option C — Presigned upload (large files / direct-to-storage)

For direct-to-storage uploads, request a presigned PUT from POST /v0/media/presign (contentType and key required), upload the bytes yourself, then reference the file URL:

# 1. presign
curl -X POST https://api.schedulin.app/v0/media/presign \
  -H "x-api-key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "contentType": "image/jpeg", "key": "launch.jpg", "size": 248173 }'
# → { "url": "https://<bucket>.r2.cloudflarestorage.com/...", "key": "<your-org>/launch.jpg", "method": "PUT" }

# 2. upload the raw bytes to the returned url
curl -X PUT "<url>" -H "Content-Type: image/jpeg" --data-binary @launch.jpg

The public file URL is https://r2.schedulin.app/<key>. The key does not exist until the PUT completes — POST /v0/posts rejects a key whose bytes were never uploaded.

Attach it to a post

Whichever option you used, put the resulting url in the media array:

curl -X POST https://api.schedulin.app/v0/posts \
  -H "x-api-key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "socialAccountId": "acc_123",
    "caption": "Behind the scenes 📸",
    "media": [{ "url": "https://r2.schedulin.app/<your-org>/<id>-launch.jpg" }],
    "action": "now"
  }'