Compatible / legacy endpoints
Drop-in endpoints for tools that expect another API shape.
On this page
Many FiveM scripts already know how to upload to a media host. Point them at these endpoints instead of changing their code. They live on upload.basix.media only.
| Method | Path | Use |
|---|---|---|
| POST | /api/v3/file | Upload. Multipart, the file part can have any name. |
| POST | /api/v2/image, /api/v2/video, /api/v2/audio | Upload, restricted to one media type. |
| POST | /v1/media/images, /v1/media/videos, /v1/media/audios | Same, older path style (also under /api/v1/media/...). |
| GET, POST | /api/v3/file/presigned-url | Presigned URL (see above). /api/v2/presigned-url?fileType=image also works. |
| POST | /api/v3/file/base64 | Base64 upload (see above). |
| GET | /api/v3/file?page=1&limit=50&type=image&path=reports/ | List files, page-based, limit 1-100. |
| GET, DELETE | /api/v3/file/<id or path> | Read or delete one file. Delete needs a full key. |
| POST | /api/v3/logs | Send logs: a JSON array of events. Dataset from the X-Basix-Dataset header or ?dataset=. |
How they differ from /api/v1/upload:
- The key is accepted as
Authorization: Bearer <key>,Authorization: Key <key>,Authorization: <key>,X-Api-Key: <key>, or?apiKey=<key>(upload endpoints only, for scripts that cannot send headers). pathis always a folder. Invalid characters are repaired (Player Photosbecomesplayer-photos). The file name is always<id>.<ext>, so two uploads never overwrite each other.- Optional fields:
filenameorname(kept as the original name),retentionExempt.
Success response (the URL is both at the top level and under data):
{
"status": "ok",
"success": true,
"url": "https://cdn.basix.media/a7k2m9x4/reports/k7x2m9q4pz1a.png",
"id": "k7x2m9q4pz1a",
"data": { "id": "k7x2m9q4pz1a", "url": "...", "originalUrl": "..." },
"filename": "k7x2m9q4pz1a.png",
"original_filename": "screenshot.png",
"mime_type": "image/png",
"size": 182344,
"hash": "<sha256>",
"path": "reports/k7x2m9q4pz1a.png",
"replaced": false,
"created_at": "2026-10-25T14:00:00.000Z",
"updated_at": "2026-10-25T14:00:00.000Z"
}Error response on these endpoints:
{ "status": "error", "success": false, "code": "UNAUTHORIZED", "error": "Missing or invalid token.", "message": "Missing or invalid token.", "data": null }From a generic backend. Any tool that already speaks this shape can POST straight to /api/v3/file:
curl -X POST https://upload.basix.media/api/v3/file \
-H "Authorization: Bearer $BASIX_KEY" \
-F "path=reports" \
-F "[email protected]"ShareX. Save this as BasiX.sxcu and open it. Or use Download for ShareX on the API keys page, which creates the key for you.
{
"Version": "15.0.0",
"Name": "BasiX Media",
"DestinationType": "ImageUploader, FileUploader",
"RequestMethod": "POST",
"RequestURL": "https://upload.basix.media/api/v3/file",
"Headers": { "Authorization": "Bearer YOUR_BASIX_KEY" },
"Body": "MultipartFormData",
"FileFormName": "file",
"URL": "{json:url}",
"ErrorMessage": "{json:message}"
}LB Phone. Use its built-in Custom upload method:
Config.UploadMethod = {
Image = "Custom",
Video = "Custom",
Audio = "Custom",
}
Custom = {
url = "https://upload.basix.media/api/v3/file",
field = "file",
headers = {
["Authorization"] = "Key API_KEY",
},
success = { path = "url" },
error = { path = "success", value = false },
}Replace API_KEY in LB Phone's server-side API key file, not in a client file.
screenshot-basic. From a server script:
exports['screenshot-basic']:requestClientScreenshotUpload(
source,
'https://upload.basix.media/api/v3/file',
{ headers = { Authorization = 'Bearer ' .. GetConvar('basix_key', '') }, fileName = 'file' },
function(err, data)
print(json.decode(data).url)
end
)Step-by-step guides for more scripts: https://basix.media/docs/integrations.
Zip import
Unpack a zip archive into your account in one call. Media files keep the folder structure of the archive. Anything else is skipped and reported. The archive itself is never stored.
curl -X POST https://upload.basix.media/api/v1/import \
-H "Authorization: Bearer $BASIX_KEY" \
-F "path=shop" \
-F "[email protected]"It answers 202 Accepted at once and works in the background:
{ "id": "k7x2m9q4pz1a", "fileName": "assets.zip", "status": "pending" }Poll GET /api/v1/import/<id> until status is done or failed:
{
"id": "k7x2m9q4pz1a",
"fileName": "assets.zip",
"status": "done",
"total": 312, "extracted": 248, "skipped": 61, "refused": 3,
"bytes": "184320512",
"report": [ { "path": "resource.lua", "reason": "not an image, video or audio file" } ],
"error": null,
"createdAt": "2026-10-25T14:00:00.000Z",
"finishedAt": "2026-10-25T14:01:10.000Z"
}One import runs at a time per account. A second one answers 409 PATH_CONFLICT.
Try it on your own server
Create a free account and your API key is ready in about two minutes. 3 GB included, bandwidth never billed, no card needed.