Overview
You have three ways to upload files.Method 1: Multipart Upload (The Pro Way)
The file is split into fixed 64 MiB chunks that you PUT independently, then we assemble them. Each chunk can be retried or re-signed on its own, so a long upload survives a flaky connection.Step 1: Initialize
Endpoint:POST /api/v1/upload/multipart/init
uploadId, the path, the partSize, and one presigned url per part.
Step 2: PUT each part - and keep every ETag
Slice the file atpartSize boundaries and PUT each slice to its own URL. Every part
except the last must be exactly partSize bytes - storage rejects the assembly at the end
if they are not uniform.
Read the ETag response header from each PUT. You need the full list to finish, and
there is no way to recover it afterwards.
Part URLs are valid for 6 hours. If one expires mid-upload, call
POST /api/v1/upload/multipart/sign with { path, uploadId, partNumbers: [12] } to get a
fresh URL for just those parts. Parts you already uploaded keep their ETags - do not
re-send them.Step 3: Complete
Endpoint:POST /api/v1/upload/multipart/complete
id you pass when creating a post.
Handling errors on complete
This is worth wiring properly - it decides whether a failure costs you seconds or a full re-upload.Giving up
Endpoint:POST /api/v1/upload/multipart/abort with { path, uploadId }.
Call it whenever you abandon an upload - unfinished parts occupy storage and count against
your usage. If your process dies before it can, transfers left untouched for 7 days are
aborted automatically, but that is a backstop, not your cleanup path.
A single upload is capped at 10 000 parts, and the file still has to fit your plan’s
video limit (see Limits).
Method 2: Direct Upload
One presignedPUT for the whole file. Simpler than multipart, but a failure means
starting over, and the hard ceiling is 5 GiB (a single storage request cannot carry
more). Above that we reject at init and point you to multipart.
Step 1: Initialize
Endpoint:POST /api/v1/upload/init
url and a path.
The pre-signed URL expires after 30 minutes. If you don’t start uploading within that window, you’ll need to initialize again.
Step 2: Push the Bytes
Send the raw binary file to theurl we gave you. Use PUT.
Important: Do not wrap this in JSON or Multipart form. Just send the raw bytes.
Step 3: Finalize
Tell us you’re done so we can register the file in our system. Endpoint:POST /api/v1/upload/finalize
id (e.g., upload_abc123). This is the ID you use when creating a post.
Method 3: Simple Upload (The Lazy Way)
Good for images or small clips. Uses standardmultipart/form-data.
Endpoint: POST /api/v1/upload
id immediately.
Upload from a URL
Register media by passing a public HTTP(S) URL instead of uploading the bytes yourself:POST /api/v1/upload/from-url (also exposed in the SDKs and the MCP server). We fetch the asset server-side and register it like any other upload.
The 1 GB / 60 s limit applies only to URL imports, because we download the file for you. Uploads where you send the bytes stream straight to storage and allow up to your full video limit.
Supported Formats & Limits
The default video ceiling is 5 GB per file - talk to us if you need more, which is granted per organization and only applies to Multipart Upload. The max video size also depends on the platform you’re posting to: TikTok allows up to 1 GB, YouTube up to 5 GB, while Discord caps at 10 MB. Check Platform Limits for the exact numbers per platform.
Tip: If you are uploading a picture of your cat (or your mom, we don’t judge), Simple Upload is fine. For a 4K podcast clip, use Multipart.
Video Compression
You can enable automatic video compression on your organization. When enabled, we’ll compress videos larger than 10 MB before they’re stored and posted.How to enable
Video compression is an organization-level setting. You can toggle it from your dashboard or contact us to enable it. Once on, it applies to all uploads across all teams in your org.What happens
We’re smart about it - if the compressed file ends up larger than the original (rare, but it happens with already-compressed videos), we keep the original and toss the compressed version. You always get the smaller file.