>FFmpegLab Sign In
Storage Guide

FFmpegLab S3 storage: your user namespace, API keys & credentials

Sign in, generate an API key under Settings → API Keys, then call the storage config endpoint to pull your bucket, regional endpoint and temporary S3 credentials. Every user gets a personal namespace based on their userId inside a shared bucket — and the credentials you receive only work inside that namespace.

FFmpegLab doesn't just render video — it gives you a S3-compatible object store attached to your account. Every project you render, every source file you upload, and every output you export can live in a bucket you control, addressed with the same API shape you already know from AWS S3, Cloudflare R2 or MinIO.

That means you never have to build a bespoke upload path. You generate one API key, ask the storage endpoint for your configuration, and hand that configuration to whatever tool you already trust. This guide walks through the whole flow end to end.

Key takeaways

What you're actually getting

The storage layer is a managed, S3-compatible bucket bound to your FFmpegLab account. It's a shared bucket with per-user namespaces — meaning the bucket itself is common infrastructure, but your access is isolated to a folder-like prefix derived from your userId.

You get:

Because it speaks the S3 protocol, you can point any existing pipeline at it without rewriting a single line of upload logic. If you already have scripts that talk to S3, you change one variable: the endpoint. Just remember that all paths must begin with your namespace prefix.

Storage tiers at a glance

TierTypical useEgress feesScaling model
Free / StarterIndividual projects, experiments, small renders€0Fixed starter allocation
TeamShared media libraries, collaborative pipelines€0Expanded allocation, shared access
EnterpriseArchival, AI training sets, petabyte-scale media€0Petabyte-scale nodes, provisioned on request

Prerequisites


Step 1 — Sign in to FFmpegLab

Everything starts with an authenticated session. Open the app and sign in with the account that owns the storage allocation you want to use.

Credentials are scoped per account, so if you belong to more than one workspace, make sure you're in the right one before generating a key. A key created in the wrong workspace will happily authenticate — and then return a namespace you didn't expect.


Step 2 — Generate an API key

Once you're signed in:

  1. Open Settings from the sidebar or the account menu.
  2. Switch to the API Keys tab.
  3. Click Generate new key (or Create API key).
  4. Give it a descriptive name — rclone-laptop, ci-render-runner, training-loader. You will thank yourself later when you need to revoke one.
  5. Copy the secret immediately. Most implementations show the full key exactly once.

The key is a bearer token. Everything you do next — fetching storage config, starting renders, listing jobs — is authenticated with it.

Store it safely

Put the key in an environment variable or a secrets manager. Never commit it to a repository, and never paste it into a client-side bundle.

ShareRenders{ } CodeConfig
Generated CodeLogsCustomize
# .env  (never commit this file)
FFMPEGLAB_API_KEY=ffl_live_xxxxxxxxxxxxxxxxxxxxxxxx

Step 3 — Call the storage config endpoint

With the key in hand, request your storage configuration. This single call returns everything an S3 client needs: the bucket, the endpoint, the region, your namespace prefix, and a set of credentials scoped to that prefix.

ShareRenders{ } CodeConfig
Generated CodeLogsCustomize
curl -sS https://api.ffmpeglab.com/api/files/s3config \
  -H "Authorization: Bearer $FFMPEGLAB_API_KEY" \
  -H "Accept: application/json" | jq

A successful response looks roughly like this:

ShareRenders{ } CodeConfig
Generated CodeLogsCustomize
{
  "bucketId": "ffl-9f2c1a7d-media",
  "endpoint": "https://s3.eu-central-1.ffmpeglab.com",
  "region": "eu-central-1",
  "accessKeyId": "FFLXXXXXXXXXXXXXXXX",
  "secretAccessKey": "********************************",
  "sessionToken": "********************************",
  "prefix": "users/12345/",
  "forcePathStyle": true,
  "expiresAt": "2026-09-12T18:30:00Z"
}

Understanding each field

FieldWhat it isWhere it goes
bucketIdThe shared bucket bound to your accountAWS_BUCKET / rclone remote root
endpointRegional HTTPS hostname for the S3 API--endpoint-url / endpoint =
regionSigning region used for SigV4AWS_REGION
accessKeyIdPublic half of the credential pairAWS_ACCESS_KEY_ID
secretAccessKeySecret half — treat as a passwordAWS_SECRET_ACCESS_KEY
sessionTokenTemporary-session token, if issuedAWS_SESSION_TOKEN
prefixYour personal namespace, derived from your userId (e.g. users/12345/). All uploads must go here.Upload path root
forcePathStyleWhether to use path-style addressingforce_path_style = true
expiresAtWhen the credentials stop workingYour refresh logic

Your namespace is your boundary

The credentials you receive are only valid inside your prefix. You cannot list, read, or write to any other part of the bucket. If you try, the S3 API will return an AccessDenied error. Treat the prefix as your personal root directory — every object you create should live under it.

Don't cache forever

Because credentials can expire, treat this endpoint as something you call at the start of a job, not something you call once and paste into a config file you keep for a year. A short-lived token fetched at runtime is both safer and more reliable.


Step 4 — Wire it into your S3 client

rclone

rclone is the fastest way to move large media libraries. Add a remote to your config:

ShareRenders{ } CodeConfig
Generated CodeLogsCustomize
# ~/.config/rclone/rclone.conf
[ffmpeglab]
type = s3
provider = Other
access_key_id = FFLXXXXXXXXXXXXXXXX
secret_access_key = ********************************
session_token = ********************************
endpoint = https://s3.eu-central-1.ffmpeglab.com
region = eu-central-1
acl = private
force_path_style = true

Then copy, sync or mount. Always include your namespace prefix in the path.

ShareRenders{ } CodeConfig
Generated CodeLogsCustomize
# List your namespace only
rclone lsf ffmpeglab:ffl-9f2c1a7d-media/users/12345/

# Copy files into your namespace
rclone copy ./renders ffmpeglab:ffl-9f2c1a7d-media/users/12345/renders --progress

# Mount your namespace
rclone mount ffmpeglab:ffl-9f2c1a7d-media/users/12345/ /mnt/media --vfs-cache-mode writes

Python + boto3

The cleanest pattern is a helper that fetches the config, builds a client, and automatically prefixes your keys with your namespace.

ShareRenders{ } CodeConfig
Generated CodeLogsCustomize
import os
import requests
import boto3
from botocore.config import Config

API = "https://api.ffmpeglab.com/api/files/s3config"

def storage_config():
    r = requests.get(
        API,
        headers={"Authorization": f"Bearer {os.environ['FFMPEGLAB_API_KEY']}"},
        timeout=15,
    )
    r.raise_for_status()
    return r.json()

def s3_client():
    cfg = storage_config()
    return boto3.client(
        "s3",
        endpoint_url=cfg["endpoint"],
        region_name=cfg["region"],
        aws_access_key_id=cfg["accessKeyId"],
        aws_secret_access_key=cfg["secretAccessKey"],
        aws_session_token=cfg.get("sessionToken"),
        config=Config(
            s3={"addressing_style": "path" if cfg.get("forcePathStyle") else "auto"}
        ),
    ), cfg

client, cfg = s3_client()

# Always prepend your namespace prefix
key = f"{cfg['prefix']}input.mov"

client.upload_file("input.mov", cfg["bucketId"], key)

# List only your namespace
for obj in client.list_objects_v2(
    Bucket=cfg["bucketId"], Prefix=cfg["prefix"]
).get("Contents", []):
    print(obj["Key"], obj["Size"])

AWS CLI

Prefer the command line? Export the values and pass the endpoint on every call. Remember to include your namespace in the S3 URI.

ShareRenders{ } CodeConfig
Generated CodeLogsCustomize
export AWS_ACCESS_KEY_ID=FFLXXXXXXXXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=********************************
export AWS_SESSION_TOKEN=********************************
export AWS_DEFAULT_REGION=eu-central-1
export ENDPOINT=https://s3.eu-central-1.ffmpeglab.com
export BUCKET=ffl-9f2c1a7d-media
export PREFIX=users/12345/

# List only your namespace
aws s3 ls "s3://$BUCKET/$PREFIX" --endpoint-url "$ENDPOINT"

# Upload into your namespace
aws s3 cp ./output.mp4 "s3://$BUCKET/${PREFIX}output.mp4" --endpoint-url "$ENDPOINT"

A shell helper that regenerates config on demand

If you'd rather not keep credentials on disk at all, pull them into your shell session each time:

ShareRenders{ } CodeConfig
Generated CodeLogsCustomize
#!/usr/bin/env bash
set -euo pipefail

JSON=$(curl -sS https://api.ffmpeglab.com/api/files/s3config \
  -H "Authorization: Bearer $FFMPEGLAB_API_KEY")

export AWS_ACCESS_KEY_ID=$(echo "$JSON" | jq -r .accessKeyId)
export AWS_SECRET_ACCESS_KEY=$(echo "$JSON" | jq -r .secretAccessKey)
export AWS_SESSION_TOKEN=$(echo "$JSON" | jq -r '.sessionToken // empty')
export AWS_DEFAULT_REGION=$(echo "$JSON" | jq -r .region)
export ENDPOINT=$(echo "$JSON" | jq -r .endpoint)
export BUCKET=$(echo "$JSON" | jq -r .bucketId)
export PREFIX=$(echo "$JSON" | jq -r .prefix)

echo "Ready: s3://$BUCKET/$PREFIX via $ENDPOINT"

Path-style vs virtual-hosted addressing

S3 has two ways to put a bucket in a URL:

If the config response sets forcePathStyle: true, use path-style addressing. Most clients need to be told explicitly:

ClientSetting
rcloneforce_path_style = true
boto3Config(s3={"addressing_style": "path"})
AWS CLIaws configure set default.s3.addressing_style path
s5cmd--use-path-style (or config flag)

If you get a 301, 307, or a TLS certificate mismatch, this setting is almost always the culprit.


Security & namespace best practices


Troubleshooting

SymptomLikely causeFix
401 Unauthorized on the config callMissing, malformed or revoked API keyRe-check the Authorization: Bearer header and regenerate the key in Settings → API Keys
403 Forbidden on uploadCredentials expired, or writing outside your namespaceRe-fetch the storage config and ensure your key starts with prefix (e.g. users/12345/)
AccessDenied when listingListing the bucket root instead of your prefixAdd your prefix to the list call — you cannot list the whole bucket
Certificate / hostname mismatchVirtual-hosted addressing against a custom endpointEnable path-style addressing
301 Moved PermanentlyWrong region in the signing configUse the region value from the config response verbatim
Uploads stall on large filesMultipart threshold too high for your linkLower the multipart chunk size (e.g. rclone's --s3-chunk-size)

Frequently asked questions

Where exactly do I generate the API key?

Sign in, open Settings, then the API Keys tab. Create a key, name it, and copy the secret — it's normally displayed only once.

Do I need a separate key for storage?

No. The same API key authenticates the storage config endpoint and the rest of the platform API. One key, one revocation point.

What is my user namespace?

Your namespace is a folder-like prefix inside the shared bucket, derived from your userId. For example, if your userId is 12345, your prefix will be users/12345/. The S3 credentials you receive are scoped to that prefix only.

Can I access other users' data in the same bucket?

No. The temporary credentials only grant access to your own namespace. Attempting to read or write outside your prefix will result in an AccessDenied error. This isolation is enforced at the credential level.

Are the S3 credentials permanent?

Treat them as temporary. Fetch them at the start of a job and refresh when they expire, rather than persisting them indefinitely.

Can I use rclone, Cyberduck or s5cmd?

Yes. Anything that supports a custom endpoint URL and path-style addressing will work. rclone and boto3 are the two most commonly used.

Is there an egress charge when I download my renders?

The platform is built around zero egress fees, so moving data out — including large renders and shared outputs — doesn't add per-gigabyte transfer costs on supported tiers.

Can I store petabytes here?

Yes, at the upper tiers. Rather than splitting data across thousands of small accounts, you provision capacity at the enterprise level and manage it through the same single endpoint and API key. Check the dashboard or pricing page for the current scaling options.


Next steps

Once the connection works, the interesting part starts: pointing your rendering pipeline at your namespace so sources and outputs never leave the platform.

Working with containers and codecs alongside this? See the complete FFmpeg formats guide and the complete codecs guide. If you'd rather keep processing local, read about the offline, private editor or self-hosting with Docker.

Want to try it end to end? Open FFmpegLab, generate a key in Settings → API Keys, and access your user namespace in under a minute.

✦  Fresh from the render queue

Better FFmpeg workflows, delivered.

Get practical commands, new templates, and deep-dive guides for the edits that are usually hardest to get right.

✓  Copy-pasteable commands    ✓  Editor templates    ✓  No noise
One useful email at a time.

Generate a key, grab your namespace, start uploading.

Free in your browser — S3-compatible storage, zero egress, your own user prefix.