How direct uploads work
1
Presign
Tell the API which files you want to upload (name, MIME type, size). It pre-creates a temporary media item for each and returns a short-lived, pre-signed upload URL.
2
Upload
PUT each file’s bytes straight to the returned upload_url, replaying the signed headers. This goes to storage, not to the PublishBuddy API.3
Confirm
Tell the API which uploads finished. It verifies each object landed in storage, moves it into the workspace’s library, and marks it active.
Direct uploads replace the old
POST /media_contents multipart endpoint, which has been removed from the public API. Uploading through the API is no longer supported — always use the presign → upload → confirm flow.A single upload
1. Presign
name and size (bytes); mime is optional but recommended. You can presign up to 10 files per request.
Response — one PresignedMediaUploadResource per file:
id is the temporary media item’s UUID — you’ll pass it back in the confirm step. The upload_url is valid for expires_in seconds (30 minutes).
2. Upload the bytes
PUT the file straight to upload_url, replaying every header from upload_headers exactly as returned:
api.publishbuddy.com. A 200/204 means the bytes are in place.
3. Confirm
size, width, height, and time are detected asynchronously and may come back null immediately after confirm. Fetch the media item again a moment later (GET /media_contents/{mediaContent}) to read the resolved values.data — a UUID you confirm without uploading is silently skipped rather than erroring.
Multiple files in one request
Presign and confirm both accept up to 10 items per request. Presign every file,PUT each one, then confirm them all together:
folder_id after confirming (see Organising with folders).
Bulk imports
For larger imports (hundreds or thousands of files), batch them in groups of 10 (the presign/confirm limit) and cap concurrency:media_contents endpoint group uses the throttle:api_1000_per_min rate limit, so a modest concurrency (8 or so) per token stays comfortably under it. Note the presign/confirm calls count against the API rate limit, but the PUT uploads go to storage and don’t.
Supported formats and limits
The maximum per-file size is 2 GB (declare the real byte count in the presign
size field). Per-network and per-plan limits may be lower and are enforced at publish time. For very large files (long-form video), upload them once and reuse the same media_content_id across multiple posts.
Organising with folders
Folders are workspace-internal — they help your team find assets and don’t change anything that gets sent to the social network.folder_id:
Filtering existing media
folder_id with page and per_page (see Pagination) to walk large libraries.
Replacing a file
The binary attached to a media object is immutable. To “replace” an asset:- Upload the new file (presign → upload → confirm gives you a new
media_content_id). - Update any scheduled (
status: waiting) posts that reference the old ID — set theirmedia_content_idsto include the new ID instead. - Delete the old media object (optional — already-published posts hold their own reference).
PUT is intentionally not supported; this keeps the audit trail clean (“the post that went out on Dec 25 used exactly this asset”).