Skip to main content
Use a private S3-compatible bucket, such as Cloudflare R2. Create an object read/write credential limited to that bucket. Keep it in the API/worker runtime environment; the UI must not receive it. Set these values together:
Use your storage service’s correct endpoint and region. R2 uses auto; other providers may require a region name. Replace placeholders privately.

CORS

Allow the exact UI origin to PUT and GET signed objects. Expose ETag and allow headers used by S3 signing. For R2:
Do not enable a public bucket domain. A successful upload in the UI confirms CORS and signing; container health alone does not.

Retention

Temporary uploads use posted/uploads/; expire that prefix after one day. Prepared delivery copies use posted/delivery/; expire them after two days. Retain immutable originals in posted/originals/ and normalized, ready videos in posted/media/ for saved drafts and future schedules. Never use bucket-wide expiry. It can remove files needed by a future scheduled post or saved draft. Back up private retained media alongside PostgreSQL and POSTED_SECRET.