This document describes the FBC Uploader REST API endpoints. All endpoints return JSON responses unless otherwise specified. The API implements token-based authentication and TUS protocol for resumable file uploads.
Note: All API routes are prefixed with
/api. For deployment and environment configuration, see README.md.
- HTTP API Documentation
- Table of Contents
- Authentication
- Global Notes
- Endpoints
- GET /health
- POST /api/tokens/
- GET /api/tokens/
- GET /api/tokens/{token_value}
- PATCH /api/tokens/{token_value}
- DELETE /api/tokens/{token_value}
- GET /api/tokens/{token_value}/info
- GET /api/tokens/{token_value}/uploads
- GET /api/tokens/{download_token}/uploads/{upload_id}
- GET /api/tokens/{download_token}/uploads/{upload_id}/stream
- GET /api/tokens/{download_token}/uploads/{upload_id}/preview.mp4
- GET /api/tokens/{download_token}/uploads/{upload_id}/thumbnail
- GET /api/tokens/{download_token}/uploads/{upload_id}/download
- POST /api/uploads/initiate
- OPTIONS /api/uploads/tus
- HEAD /api/uploads/{upload_id}/tus
- PATCH /api/uploads/{upload_id}/tus
- DELETE /api/uploads/{upload_id}/tus
- DELETE /api/uploads/{upload_id}/cancel
- POST /api/uploads/{upload_id}/complete
- GET /api/metadata/
- POST /api/metadata/extract
- POST /api/metadata/validate
- GET /api/notice/
- GET /api/admin/validate
- DELETE /api/admin/uploads/{upload_id}
- TUS Protocol
- Upload Flow
- Error Codes Reference
- Notes
Admin-only endpoints require a Bearer token in the Authorization header:
Authorization: Bearer <admin_api_key>The admin API key is configured via FBC_ADMIN_API_KEY environment variable or auto-generated and stored in {config_path}/secret.key.
The following endpoints are always public:
GET /healthGET /api/tokens/{token}/infoPOST /api/uploads/initiate?token=...- All TUS protocol endpoints (
/api/uploads/{id}/tus) GET /api/metadata/POST /api/metadata/validateGET /api/notice/
When FBC_ALLOW_PUBLIC_DOWNLOADS=1, download endpoints also become public without requiring admin authentication.
-
Content-Type
- Requests with JSON body should include
Content-Type: application/json - TUS protocol PATCH requests require
Content-Type: application/offset+octet-stream - Responses typically include
Content-Type: application/json, unless returning a file
- Requests with JSON body should include
-
Status Codes
200 OK- Request successful201 Created- Resource created successfully204 No Content- Request successful, no content to return4xx- Client errors (bad request, unauthorized, forbidden, not found)5xx- Server errors
-
Error Responses When an error occurs, responses follow this structure:
{ "detail": "Error description" }or for validation errors:
{ "detail": { "field": "field_name", "message": "Error message" } } -
Datetime Format All datetime values are in UTC with ISO 8601 format including timezone info.
Health check endpoint to verify the service is running.
Authentication: None
Response (200):
{
"status": "ok"
}Create a new upload token.
Authentication: Required (Admin)
Request Body:
{
"max_uploads": 5,
"max_size_bytes": 104857600,
"expiry_datetime": "2025-12-24T00:00:00Z",
"allowed_mime": ["application/pdf", "video/*"]
}Fields:
max_uploads(integer, required): Maximum number of uploads allowed (min: 1)max_size_bytes(integer, required): Maximum file size in bytes (> 0)expiry_datetime(datetime, optional): Token expiration date (defaults to current time +FBC_DEFAULT_TOKEN_TTL_HOURS)allowed_mime(array of strings, optional): Allowed MIME types with wildcard support (e.g.,video/*). Empty = all types allowed
Response (201):
{
"token": "upload-token-string",
"download_token": "fbc_download-token-string",
"upload_url": "http://localhost:8000/api/uploads/initiate?token=upload-token-string",
"expires_at": "2025-12-24T00:00:00Z",
"max_uploads": 5,
"max_size_bytes": 104857600,
"allowed_mime": ["application/pdf", "video/*"]
}List all upload tokens.
Authentication: Required (Admin)
Query Parameters:
skip(integer, optional): Number of records to skip (default: 0)limit(integer, optional): Maximum records to return (default: 100)
Response (200):
[
{
"token": "upload-token-string",
"download_token": "fbc_download-token-string",
"expires_at": "2025-12-24T00:00:00Z",
"uploads_used": 2,
"max_uploads": 5,
"max_size_bytes": 104857600,
"allowed_mime": ["application/pdf"],
"disabled": false,
"created_at": "2025-12-23T00:00:00Z",
"remaining_uploads": 3
}
]Get detailed information about a specific token.
Authentication: Required (Admin, or public if FBC_ALLOW_PUBLIC_DOWNLOADS=1)
Path Parameters:
token_value(string): Upload token or download token
Response (200):
{
"token": "upload-token-string",
"download_token": "fbc_download-token-string",
"expires_at": "2025-12-24T00:00:00Z",
"uploads_used": 0,
"max_uploads": 1,
"max_size_bytes": 104857600,
"allowed_mime": ["application/pdf"],
"disabled": false,
"created_at": "2025-12-23T00:00:00Z",
"remaining_uploads": 1
}Error Responses:
404 Not Found- Token does not exist
Update an existing token.
Authentication: Required (Admin)
Path Parameters:
token_value(string): Upload token or download token
Request Body:
{
"max_uploads": 10,
"max_size_bytes": 209715200,
"expiry_datetime": "2025-12-31T23:59:59Z",
"allowed_mime": ["image/*", "video/*"],
"disabled": false
}Fields (all optional):
max_uploads(integer): Update maximum uploadsmax_size_bytes(integer): Update maximum file sizeexpiry_datetime(datetime): Update expiration dateallowed_mime(array): Update allowed MIME typesdisabled(boolean): Enable or disable the token
Response (200):
{
"token": "upload-token-string",
"download_token": "fbc_download-token-string",
"expires_at": "2025-12-31T23:59:59Z",
"uploads_used": 0,
"max_uploads": 10,
"max_size_bytes": 209715200,
"allowed_mime": ["image/*", "video/*"],
"disabled": false,
"created_at": "2025-12-23T00:00:00Z",
"remaining_uploads": 10
}Error Responses:
404 Not Found- Token does not exist
Delete a token and its associated uploads.
Authentication: Required (Admin)
Path Parameters:
token_value(string): Upload token or download token
Query Parameters:
delete_files(boolean, optional): Whether to delete physical files (default: false)
Response (204): No content
Error Responses:
404 Not Found- Token does not exist
Notes:
- Deletes the token and all associated upload records
- Physical files are deleted from storage if
delete_files=true - This operation cannot be undone
Get public token information including uploads.
Authentication: None
Path Parameters:
token_value(string): The upload token
Response (200):
{
"token": "upload-token-string",
"download_token": "fbc_download-token-string",
"remaining_uploads": 1,
"max_uploads": 1,
"max_size_bytes": 104857600,
"max_chunk_bytes": 94371840,
"allowed_mime": ["application/pdf"],
"expires_at": "2025-12-24T00:00:00Z",
"allow_public_downloads": false,
"uploads": [
{
"public_id": "rT72ZKGMPdldiEmA9eDI7kik",
"filename": "document.pdf",
"ext": "pdf",
"mimetype": "application/pdf",
"size_bytes": 1024000,
"meta_data": {"title": "My Document"},
"upload_length": 1024000,
"upload_offset": 1024000,
"recommended_chunk_bytes": 94371840,
"status": "completed",
"created_at": "2025-12-23T12:00:00Z",
"completed_at": "2025-12-23T12:01:00Z",
"stream_url": "http://localhost:8000/api/tokens/fbc_token/uploads/rT72ZKGMPdldiEmA9eDI7kik/stream",
"thumbnail_url": "http://localhost:8000/api/tokens/fbc_token/uploads/rT72ZKGMPdldiEmA9eDI7kik/thumbnail",
"download_url": "http://localhost:8000/api/tokens/fbc_token/uploads/rT72ZKGMPdldiEmA9eDI7kik",
"upload_url": "http://localhost:8000/api/uploads/rT72ZKGMPdldiEmA9eDI7kik/tus"
}
]
}Fields:
remaining_uploads: Number of uploads still availablemax_chunk_bytes: Maximum chunk size for TUS uploads (fromFBC_MAX_CHUNK_BYTES)allow_public_downloads: Whether public downloads are enableduploads: Array of upload recordsrecommended_chunk_bytes: Server-selected TUS chunk size to reuse for checksum-verified resume operationsstream_url: Inline media URL for browser playback when the upload is completedthumbnail_url: Preview image URL for embeds and thumbnail-first media UIs
Upload Status Values:
initiated- Upload created but no data uploaded yetin_progress- Upload in progresscompleted- Upload complete
Error Responses:
404 Not Found- Token does not exist
List all uploads for a specific token.
Authentication: Required (Admin, or public if FBC_ALLOW_PUBLIC_DOWNLOADS=1)
Path Parameters:
token_value(string): Upload token or download token
Response (200):
[
{
"public_id": "rT72ZKGMPdldiEmA9eDI7kik",
"filename": "document.pdf",
"ext": "pdf",
"mimetype": "application/pdf",
"size_bytes": 1024000,
"meta_data": {"title": "My Document"},
"upload_length": 1024000,
"upload_offset": 1024000,
"recommended_chunk_bytes": 94371840,
"status": "completed",
"created_at": "2025-12-23T12:00:00Z",
"completed_at": "2025-12-23T12:01:00Z",
"stream_url": "http://localhost:8000/api/tokens/fbc_token/uploads/rT72ZKGMPdldiEmA9eDI7kik/stream",
"thumbnail_url": "http://localhost:8000/api/tokens/fbc_token/uploads/rT72ZKGMPdldiEmA9eDI7kik/thumbnail",
"download_url": "http://localhost:8000/api/tokens/fbc_token/uploads/rT72ZKGMPdldiEmA9eDI7kik",
"upload_url": "http://localhost:8000/api/uploads/rT72ZKGMPdldiEmA9eDI7kik/tus"
}
]Error Responses:
404 Not Found- Token does not exist
Get metadata information about a completed upload.
Authentication: Required (Admin, or public if FBC_ALLOW_PUBLIC_DOWNLOADS=1)
Path Parameters:
download_token(string): The download tokenupload_id(integer): The upload record ID
Response (200):
{
"public_id": "rT72ZKGMPdldiEmA9eDI7kik",
"filename": "document.pdf",
"ext": "pdf",
"mimetype": "application/pdf",
"size_bytes": 1024000,
"meta_data": {
"title": "My Document"
},
"upload_length": 1024000,
"upload_offset": 1024000,
"recommended_chunk_bytes": 94371840,
"status": "completed",
"created_at": "2025-01-01T12:00:00Z",
"completed_at": "2025-01-01T12:05:00Z",
"stream_url": "http://localhost:8000/api/tokens/fbc_token/uploads/rT72ZKGMPdldiEmA9eDI7kik/stream",
"thumbnail_url": "http://localhost:8000/api/tokens/fbc_token/uploads/rT72ZKGMPdldiEmA9eDI7kik/thumbnail",
"upload_url": "http://localhost:8000/api/uploads/rT72ZKGMPdldiEmA9eDI7kik/tus",
"download_url": "http://localhost:8000/api/tokens/fbc_token/uploads/rT72ZKGMPdldiEmA9eDI7kik/download"
}Error Responses:
404 Not Found- Download token or upload not found409 Conflict- Upload not yet completed
HEAD is also supported.
Stream a completed file inline for browser playback.
Authentication: Required (Admin, or public if FBC_ALLOW_PUBLIC_DOWNLOADS=1)
Path Parameters:
download_token(string): The download tokenupload_id(integer): The upload record ID
Response (200): Returns the file with headers:
Content-Type: Original file MIME type orapplication/octet-streamContent-Disposition:inline; filename="original-filename.ext"Content-Length: File size in bytes
Error Responses:
404 Not Found- Download token or upload not found409 Conflict- Upload not yet completed
Notes:
- Use this endpoint for HTML
<video>and<audio>playback - Use
/downloadwhen you want attachment-style download behavior
List external subtitle tracks that match a completed upload filename.
Authentication: Required (Admin, or public if FBC_ALLOW_PUBLIC_DOWNLOADS=1)
Path Parameters:
download_token(string): The download tokenupload_id(integer): The upload record ID
Response (200):
{
"subtitles": [
{
"source_format": "vtt",
"delivery_format": "vtt",
"renderer": "native",
"url": "http://localhost:8000/api/tokens/fbc_token/uploads/rT72ZKGMPdldiEmA9eDI7kik/subtitles/vtt"
},
{
"source_format": "ass",
"delivery_format": "ass",
"renderer": "assjs",
"url": "http://localhost:8000/api/tokens/fbc_token/uploads/rT72ZKGMPdldiEmA9eDI7kik/subtitles/ass"
}
]
}Notes:
- This endpoint only returns tracks discovered under
FBC_SUBTITLE_PATH. - Discovery results are cached per upload for
FBC_SUBTITLE_CACHE_TTL_SECONDS, including cases where no subtitles are found. - Results are ordered by renderer preference:
.vtt, then.srt, then.ass. .srtfiles are exposed here withsource_format: "srt",delivery_format: "vtt", andrenderer: "native".- Duplicate matches for the same stem and extension are treated as ambiguous and omitted.
Error Responses:
404 Not Found- Download token or upload not found409 Conflict- Upload not yet completed
HEAD is also supported.
Return the selected subtitle content for a completed upload.
Authentication: Required (Admin, or public if FBC_ALLOW_PUBLIC_DOWNLOADS=1)
Path Parameters:
download_token(string): The download tokenupload_id(integer): The upload record IDsource_format(string): One ofvtt,srt, orass
Response (200):
vtt:Content-Type: text/vttsrt: Converted on the fly and returned asContent-Type: text/vttass: Returned asContent-Type: text/x-ssa
Error Responses:
404 Not Found- Download token, upload, or subtitle not found409 Conflict- Upload not yet completed
Notes:
- The share page uses
vttand convertedsrtas native browser subtitle tracks. .asssubtitles are intended for ASS.js-based browser rendering.- Subtitle discovery is cached per upload, so newly added or removed subtitle files may take up to
FBC_SUBTITLE_CACHE_TTL_SECONDSto appear.
HEAD is also supported.
Return a short MP4 preview clip for bot embeds when one has been generated.
Authentication: Required (Admin, or public if FBC_ALLOW_PUBLIC_DOWNLOADS=1)
Path Parameters:
download_token(string): The download tokenupload_id(integer): The upload record ID
Response (200): Returns the file with headers:
Content-Type:video/mp4Content-Disposition:inline; filename="..."
Error Responses:
404 Not Found- Download token, upload, or preview not found409 Conflict- Upload not yet completed
Notes:
- Bot embed metadata may use this endpoint instead of the full stream for large videos that meet the preview size threshold.
- Setting
FBC_EMBED_PREVIEW_MIN_SIZE_BYTES=0disables preview sidecars and keeps embed metadata on the original/streamURL. - If no preview sidecar exists, embed metadata falls back to the original
/streamURL.
HEAD is also supported.
Return a preview image for a completed upload.
Authentication: Required (Admin, or public if FBC_ALLOW_PUBLIC_DOWNLOADS=1)
Path Parameters:
download_token(string): The download tokenupload_id(integer): The upload record ID
Response (200): Returns an image with headers:
Content-Type:image/jpegContent-Disposition:inline; filename="..."
Error Responses:
404 Not Found- Download token or upload not found409 Conflict- Upload not yet completed
Notes:
- Video uploads return a generated sidecar thumbnail when available
- The same endpoint is used by social embeds and the thumbnail-first share page UI
HEAD is also supported.
Download a completed file.
Authentication: Required (Admin, or public if FBC_ALLOW_PUBLIC_DOWNLOADS=1)
Path Parameters:
download_token(string): The download tokenupload_id(integer): The upload record ID
Response (200): Returns the file with headers:
Content-Type: Original file MIME type orapplication/octet-streamContent-Disposition:attachment; filename="original-filename.ext"Content-Length: File size in bytes
Error Responses:
404 Not Found- Download token or upload not found409 Conflict- Upload not yet completed
Initiate a new file upload.
Authentication: Required via query parameter
Query Parameters:
token(string, required): The upload token
Request Body:
{
"meta_data": {
"title": "My Document",
"category": "reports"
},
"filename": "document.pdf",
"filetype": "application/pdf",
"size_bytes": 1024000
}Fields:
meta_data(object, required): Metadata fields validated against{config_path}/metadata.jsonschemafilename(string, optional): Original filenamefiletype(string, optional): MIME typesize_bytes(integer, optional): Total file size in bytes (> 0)
Response (201):
{
"upload_id": "rT72ZKGMPdldiEmA9eDI7kik",
"upload_url": "http://localhost:8000/api/uploads/rT72ZKGMPdldiEmA9eDI7kik/tus",
"download_url": "http://localhost:8000/api/tokens/fbc_token/uploads/rT72ZKGMPdldiEmA9eDI7kik",
"meta_data": {
"title": "My Document",
"category": "reports"
},
"allowed_mime": ["application/pdf"],
"remaining_uploads": 0,
"recommended_chunk_bytes": 1024000
}recommended_chunk_bytes: Server-selected TUS chunk size for this upload. Clients should use this value when sending checksum-verified PATCH requests and when resuming the upload.
Error Responses:
404 Not Found- Token does not exist403 Forbidden- Token expired, disabled, or upload limit reached413 Content Too Large- File size exceeds token limit415 Unsupported Media Type- File type not allowed for this token422 Unprocessable Entity- Metadata validation error
Get TUS protocol capabilities.
Authentication: None
Response (204):
Headers:
Tus-Resumable: 1.0.0
Tus-Version: 1.0.0
Tus-Extension: creation,termination,checksum
Tus-Checksum-Algorithm: sha1,sha256Check upload status (TUS protocol).
Authentication: None
Path Parameters:
upload_id(integer): The upload record ID
Response (200):
Headers:
Upload-Offset: 512000
Upload-Length: 1024000
Tus-Resumable: 1.0.0Error Responses:
404 Not Found- Upload not found409 Conflict- Upload length unknown
Upload file chunk (TUS protocol).
Authentication: None
Path Parameters:
upload_id(string): The upload record public ID (random string)
Required Headers:
Upload-Offset(integer): Current upload offset (must match server state)Tus-Resumable(string): TUS protocol version (1.0.0)Content-Type: Must beapplication/offset+octet-streamContent-Length(integer, optional): Chunk size
Optional Headers:
Upload-Checksum(string): Per-chunk checksum in the form<algorithm> <base64-digest>
Request Body: Binary data (file chunk)
Max Chunk Size: Controlled by FBC_MAX_CHUNK_BYTES (default: 90MB)
Response (204):
Headers:
Upload-Offset: 1024000
Tus-Resumable: 1.0.0
Upload-Length: 1024000Error Responses:
404 Not Found- Upload not found409 Conflict- Upload length unknown or mismatched Upload-Offset460 Checksum Mismatch- Uploaded chunk checksum did not matchUpload-Checksum413 Content Too Large- Chunk too large or upload exceeds declared length415 Unsupported Media Type- Invalid Content-Type or actual file mimetype doesn't match allowed types
Notes:
- The upload is only finalized after
POST /api/uploads/{upload_id}/complete - When
Upload-Checksumis supplied, the chunk is verified before it is appended to the upload file - Server-side MIME type validation: Upon completion, the server detects the actual file type using libmagic and validates it against the token's
allowed_mimerestrictions. If validation fails, the upload is rejected and deleted (HTTP 415) - The detected MIME type replaces the client-provided value in the database
- The
uploads_usedcounter on the token is incremented upon initiation, not completion
Delete an upload and its associated file (TUS protocol).
Authentication: None
Path Parameters:
upload_id(string): The upload record public ID (random string)
Response (204): No content
Error Responses:
404 Not Found- Upload not found
Notes:
- Deletes both the database record and the physical file
- This operation cannot be undone
Cancel an in-progress upload and restore the token slot.
Authentication: Required via query parameter
Path Parameters:
upload_id(string): The upload record public ID (random string)
Query Parameters:
token(string, required): The upload token
Response (200):
{
"message": "Upload cancelled successfully",
"remaining_uploads": 5
}Error Responses:
404 Not Found- Upload or token not found409 Conflict- Upload already completed
Notes:
- Restores the upload slot to the token (increments
remaining_uploads) - Deletes the physical file if it exists
- Can only cancel uploads that are not completed
Manually mark an upload as complete.
Authentication: None
Path Parameters:
upload_id(string): The upload record public ID (random string)
Response (200):
{
"public_id": "rT72ZKGMPdldiEmA9eDI7kik",
"filename": "document.pdf",
"ext": "pdf",
"mimetype": "application/pdf",
"size_bytes": 1024000,
"meta_data": {"title": "My Document"},
"upload_length": 1024000,
"upload_offset": 1024000,
"status": "completed",
"created_at": "2025-12-23T12:00:00Z",
"completed_at": "2025-12-23T12:01:00Z",
"download_url": null,
"upload_url": null
}Error Responses:
404 Not Found- Upload not found
Get the metadata schema configuration.
Authentication: None
Response (200):
{
"fields": [
{
"key": "title",
"label": "Title",
"type": "string",
"required": true,
"minLength": 3,
"maxLength": 100
},
{
"key": "category",
"label": "Category",
"type": "select",
"required": false,
"options": ["reports", "images", "videos"],
"allowCustom": false
}
]
}Field Schema:
Each field object can have:
key(string, required): Field identifierlabel(string, optional): Human-readable labeltype(string, required): Field type (string,text,number,integer,boolean,date,datetime,select,multiselect)required(boolean, optional): Whether field is mandatoryoptions(array, optional): Available options for select/multiselectallowCustom(boolean, optional): Allow custom values not in optionsminLength,maxLength(integer, optional): String length constraintsmin,max(number, optional): Numeric value constraintsregex(string, optional): Regular expression pattern for string validationdefault(any, optional): Default value if not providedextract_regex(string, optional): Python regular expression used by/api/metadata/extractto prefill metadata from a filename
Notes:
- Schema is loaded from
{config_path}/metadata.json extract_regexis interpreted with Pythonresyntax
Extract metadata values from a filename using the configured schema.
Authentication: None
Request Body:
{
"filename": "240101 Example Show [youtube-dQw4w9WgXcQ].mp4"
}Response (200):
{
"metadata": {
"broadcast_date": "2024-01-01",
"title": "Example Show",
"source": "youtube",
"source_id": "dQw4w9WgXcQ"
}
}Extraction Rules:
- Fields without
extract_regexare ignored - The regex is matched against the provided filename with case-insensitive search
- Capture group 1 is used when present; otherwise the full match is used
- For
datefields, named groupsyear,month, anddayare combined intoYYYY-MM-DD - Two-digit years are normalized to
20xx
Validate metadata payload against the schema.
Authentication: None
Request Body:
{
"metadata": {
"title": "My Document",
"category": "reports"
}
}or direct metadata object:
{
"title": "My Document",
"category": "reports"
}Response (200):
{
"metadata": {
"title": "My Document",
"category": "reports"
}
}Error Responses:
422 Unprocessable Entity- Validation error{ "detail": { "field": "title", "message": "Must be at least 3 characters" } }
Validation Rules:
- Type Coercion: Values are automatically converted to the expected type
- Required Fields: Missing required fields result in validation error
- String/Text: Length validated against
minLength/maxLength, pattern validated againstregex - Number/Integer: Value validated against
min/max - Boolean: Accepts various formats (
true,1,"yes","on"→true) - Date/DateTime: Parsed from ISO format string
- Select: Value must be in
options(unlessallowCustomis true) - Multiselect: Each value must be in
options(unlessallowCustomis true)
Get the system notice (if configured).
Authentication: None
Response (200):
{
"notice": "# Important Notice\n\nThe system will undergo maintenance..."
}Fields:
notice(string or null): Markdown content from{config_path}/notice.md, ornullif file doesn't exist
Notes:
- Notice is displayed to users in the frontend
- Supports full Markdown formatting
Validate the admin API key.
Authentication: Required (Admin)
Response (200):
{
"valid": true
}Error Responses:
401 Unauthorized- Invalid or missing API key
Delete an upload record and its file (Admin only).
Authentication: Required (Admin)
Path Parameters:
upload_id(string): The upload record public ID (random string)
Response (204): No content
Error Responses:
404 Not Found- Upload not found
Notes:
- Deletes both the database record and the physical file
- Does not restore the upload slot to the token
- This operation cannot be undone
The API implements the TUS resumable upload protocol v1.0.0.
Supported Extensions:
creation: Create new uploadstermination: Delete uploads
Key Features:
- Resumable: Upload can be paused and resumed from the same offset
- Chunked: Large files can be split into smaller chunks
- Verified: Each chunk is verified by checking the offset
Required Headers:
Tus-Resumable: 1.0.0- Protocol versionUpload-Offset: <bytes>- Current upload positionContent-Type: application/offset+octet-stream- Required for PATCH
Response Headers:
Upload-Offset: Updated upload position after chunkUpload-Length: Total file size (if known)Tus-Resumable: Protocol version echo
Typical upload flow:
-
Create Token (Admin)
POST /api/tokens Authorization: Bearer YOUR_API_KEY Content-Type: application/json { "max_uploads": 5, "max_size_bytes": 104857600, "allowed_mime": ["application/pdf"] }
-
Get Token Info (Client)
GET /api/tokens/{token}/info
-
Initiate Upload (Client)
POST /api/uploads/initiate?token={token} Content-Type: application/json { "meta_data": {"title": "My Document"}, "filename": "document.pdf", "filetype": "application/pdf", "size_bytes": 1024000 }
-
Upload File Chunks (TUS Protocol)
# Check current offset HEAD /api/uploads/rT72ZKGMPdldiEmA9eDI7kik/tus # Upload chunk PATCH /api/uploads/rT72ZKGMPdldiEmA9eDI7kik/tus Upload-Offset: 0 Tus-Resumable: 1.0.0 Content-Type: application/offset+octet-stream [binary data]
-
Download File
GET /api/tokens/{download_token}/uploads/rT72ZKGMPdldiEmA9eDI7kik Authorization: Bearer YOUR_API_KEY
| Code | Meaning | Common Causes |
|---|---|---|
200 |
OK | Request successful |
201 |
Created | Resource created successfully |
204 |
No Content | Request successful, no content to return |
400 |
Bad Request | Invalid request format or parameters |
401 |
Unauthorized | Missing or invalid admin credentials |
403 |
Forbidden | Token expired, disabled, or limit reached |
404 |
Not Found | Resource not found |
409 |
Conflict | Upload not ready, offset mismatch, or state conflict |
413 |
Content Too Large | File or chunk exceeds limit |
415 |
Unsupported Media Type | Invalid Content-Type or file type not allowed |
422 |
Unprocessable Entity | Validation error in request body |
500 |
Internal Server Error | Server-side error |
- All datetime values are in UTC with ISO 8601 format including timezone info
- File paths are resolved and stored as absolute paths
- Upload tokens are 18-character URL-safe strings
- Download tokens are prefixed with
fbc_followed by 16-character URL-safe strings - Upload IDs (
public_id) are 18-character URL-safe random strings (not sequential integers for security) - Metadata is stored as JSON in the database (
meta_datacolumn) - TUS protocol is recommended for files larger than a few MB for reliability
- Maximum chunk size is controlled by
FBC_MAX_CHUNK_BYTES(default: 90MB) - Media remux eligibility is capped by
FBC_MAX_REMUX_BYTES(default: 5GB) - Multimedia post-processing runs with up to
FBC_POSTPROCESSING_WORKERSconcurrent workers (default: 2)