UFOLOAD API documentation
Automate uploads, import files by URL, organize your library and issue signed links over a plain JSON REST API. WebDAV and FTP are available with the same API key.
https://ufoload.com/api/v1Send Authorization: Bearer ufo_... on every request.
Overview
Everything you can do in the dashboard with files and folders is available over HTTPS.
- Base URL:
https://ufoload.com/api/v1. Requests and responses are JSON, except file uploads and downloads. - Files are processed after upload (
uploading,queued,processing,readyorfailed); pollGET /files/{id}or filter the list bystatus. - Uploading the same content again does not use extra storage: the existing file is returned with
"duplicate": true. - Errors use standard HTTP statuses:
401(missing or invalid key),404(not found),409(not enough storage),413(file too large),429(rate limited, retry later).
Authentication
Create an API key in your account (Developers section) and send it as a bearer token.
Authorization: Bearer ufo_...The key is shown only once when it is created; store it in an environment variable or a secrets manager and revoke it from the dashboard if it leaks. The same key works as the password for WebDAV and FTP, with your account email as the login. Create a free account or log in to get a key.
Common operations
Examples assume UFOLOAD_API_KEY is set in your shell.
Upload a file
Send the file as the raw request body and give its name in X-File-Name. Optional folder: ?folder_id= or X-Folder-Id (root is the top level).
curl -X POST "https://ufoload.com/api/v1/files" \
-H "Authorization: Bearer $UFOLOAD_API_KEY" \
-H "X-File-Name: report.pdf" \
-H "Content-Type: application/pdf" \
--data-binary @report.pdfMultipart form uploads work too (field file):
curl -X POST "https://ufoload.com/api/v1/files?folder_id=root" \
-H "Authorization: Bearer $UFOLOAD_API_KEY" \
-F "file=@video.mp4"Import by URL
The server downloads the file itself from a public http(s) link (up to 10 active imports). Track progress with GET /files/import.
curl -X POST "https://ufoload.com/api/v1/files/import" \
-H "Authorization: Bearer $UFOLOAD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/video.mp4", "name": "video.mp4"}'List files
Query parameters: status, q (name search), folder_id, limit (default 50, max 200), offset. The response contains items, total, limit and offset.
curl "https://ufoload.com/api/v1/files?status=ready&limit=20" \
-H "Authorization: Bearer $UFOLOAD_API_KEY"Issue signed links
Playback and download links with a lifetime of 60 seconds to 30 days (ttl), optionally bound to an IP (bind_ip) or cookie (bind_cookie).
curl -X POST "https://ufoload.com/api/v1/files/FILE_ID/links" \
-H "Authorization: Bearer $UFOLOAD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ttl": 86400}'WebDAV and FTP
Mount your library as a network drive or script transfers with standard tools. Login is your account email, the password is an API key.
HTTPS, port 443
curl -u "you@example.com:$UFOLOAD_API_KEY" https://ufoload.com/dav/
curl -u "you@example.com:$UFOLOAD_API_KEY" -T report.pdf https://ufoload.com/dav/report.pdfFTP and FTPS, port 21
curl -u "you@example.com:$UFOLOAD_API_KEY" ftp://ufoload.com/
curl -u "you@example.com:$UFOLOAD_API_KEY" --ftp-ssl -T report.pdf ftp://ufoload.com/report.pdfPython
Using the requests library.
import os
import requests
BASE = "https://ufoload.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['UFOLOAD_API_KEY']}"}
# Upload a file (raw body; the name goes into X-File-Name)
with open("report.pdf", "rb") as f:
r = requests.post(f"{BASE}/files", data=f, headers={**HEADERS, "X-File-Name": "report.pdf"})
r.raise_for_status()
print(r.json()["file"]["id"])
# Import by URL
r = requests.post(f"{BASE}/files/import", headers=HEADERS, json={"url": "https://example.com/video.mp4"})
r.raise_for_status()
# List ready files
page = requests.get(f"{BASE}/files", headers=HEADERS, params={"status": "ready", "limit": 20}).json()
for item in page["items"]:
print(item["id"], item["name"])Node.js
Node.js 18 or newer: built-in fetch, no dependencies.
import { readFile } from 'node:fs/promises'
const BASE = 'https://ufoload.com/api/v1'
const headers = { Authorization: `Bearer ${process.env.UFOLOAD_API_KEY}` }
// Upload a file (raw body; the name goes into X-File-Name)
const res = await fetch(`${BASE}/files`, {
method: 'POST',
headers: { ...headers, 'X-File-Name': 'report.pdf', 'Content-Type': 'application/pdf' },
body: await readFile('report.pdf'),
})
if (!res.ok) throw new Error(`upload failed: ${res.status}`)
const { file } = await res.json()
console.log(file.id)
// Import by URL
await fetch(`${BASE}/files/import`, {
method: 'POST',
headers: { ...headers, 'Content-Type': 'application/json' },
body: JSON.stringify({ url: 'https://example.com/video.mp4' }),
})
// List ready files
const page = await (await fetch(`${BASE}/files?status=ready&limit=20`, { headers })).json()
for (const item of page.items) console.log(item.id, item.name)Endpoint reference
All 25 public operations. Paths are relative to https://ufoload.com; request and response schemas are in the OpenAPI specification.
Files
Upload, list, rename, delete and share files; manage covers and chapters of videos.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/files | Upload a file (multipart form or raw request body) |
| GET | /api/v1/files | List your files (filter by status, name, folder; paginated) |
| GET | /api/v1/files/{fileID} | Get a file with playback and download links |
| PATCH | /api/v1/files/{fileID} | Rename a file or move it to a folder |
| DELETE | /api/v1/files/{fileID} | Delete a file |
| POST | /api/v1/files/{fileID}/links | Issue signed links with a custom lifetime and IP/cookie binding |
| GET | /api/v1/files/{fileID}/cover | Cover state: current, automatic, candidate frames, custom |
| PUT | /api/v1/files/{fileID}/cover | Choose the cover |
| POST | /api/v1/files/{fileID}/cover/upload | Upload your own cover image |
| GET | /api/v1/files/{fileID}/chapters | Chapters (timecodes) of a video |
| PUT | /api/v1/files/{fileID}/chapters | Set chapters manually |
| DELETE | /api/v1/files/{fileID}/chapters | Revert to chapters from the video file |
| GET | /api/v1/files/stats | Summary of your files |
Import by URL
The server downloads a file from a direct http(s) link and queues it for processing.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/files/import | Start an import from a direct link (up to 10 active imports) |
| GET | /api/v1/files/import | Active and recent imports |
| DELETE | /api/v1/files/import/{id} | Cancel an import or remove a finished one from the list |
Folders
Folder hierarchy and bulk operations on files and folders.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/folders | Subfolders of a folder and the path to it |
| POST | /api/v1/folders | Create a folder |
| GET | /api/v1/folders/tree | All folders as a flat list |
| PATCH | /api/v1/folders/{id} | Rename and/or move a folder |
| DELETE | /api/v1/folders/{id} | Delete a folder with its contents |
| POST | /api/v1/fs/move | Move files and folders into a folder |
| POST | /api/v1/fs/delete | Delete files and folders |
Public playback
Endpoints behind the public watch and embed pages; no API key required.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/public/files/{fileID} | Data for the public watch and embed page |
| POST | /api/v1/public/files/{fileID}/view | Count a view |
OpenAPI specification
Machine-readable description for code generators and API clients.
/api/openapi.json(JSON) and/api/openapi.yaml(YAML): REST API v1 described on this page./api/openapi-papi.json: public API for developers (/papi).- Interactive documentation with a request sandbox.