Upload media: upload
curl --request POST \
--url https://apistable.ai/api/v1/files/upload \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form file=@example-file \
--form uploadPath=files \
--form 'fileName=<string>'const form = new FormData();
form.append('file', '<string>');
form.append('uploadPath', 'files');
form.append('fileName', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://apistable.ai/api/v1/files/upload', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://apistable.ai/api/v1/files/upload"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"uploadPath": "files",
"fileName": "<string>"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text){
"success": true,
"code": 200,
"msg": "<string>",
"data": {
"fileName": "<string>",
"filePath": "<string>",
"downloadUrl": "<string>",
"fileSize": 123,
"mimeType": "<string>",
"uploadedAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z"
}
}File uploads
file upload
Get a public media URL, available for 24 hours.
POST
/
api
/
v1
/
files
/
upload
Upload media: upload
curl --request POST \
--url https://apistable.ai/api/v1/files/upload \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form file=@example-file \
--form uploadPath=files \
--form 'fileName=<string>'const form = new FormData();
form.append('file', '<string>');
form.append('uploadPath', 'files');
form.append('fileName', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://apistable.ai/api/v1/files/upload', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://apistable.ai/api/v1/files/upload"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"uploadPath": "files",
"fileName": "<string>"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text){
"success": true,
"code": 200,
"msg": "<string>",
"data": {
"fileName": "<string>",
"filePath": "<string>",
"downloadUrl": "<string>",
"fileSize": 123,
"mimeType": "<string>",
"uploadedAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z"
}
}Input
Bearer API key required. upload uses multipart/form-data; the other methods use JSON. uploadPath is a relative logical path; fileName is optional. Storage uses account-scoped immutable object versions, so a later upload does not replace a file used by an existing task. Stream/URL uploads: up to 500 MiB. URL requests time out after 30 seconds; up to 100 MiB is recommended. Base64 decoded uploads have a platform limit of 10 MiB; use URL or stream uploads for larger files. Model input limits are validated separately.{
"file": "multipart binary",
"uploadPath": "audio",
"fileName": "sample.wav"
}
Output
{
"success": true,
"code": 200,
"msg": "File uploaded successfully",
"data": {
"fileName": "sample.wav",
"filePath": "audio/sample.wav",
"downloadUrl": "https://files.apistable.ai/uploads/account/version/sample.wav",
"fileSize": 245760,
"mimeType": "audio/wav",
"uploadedAt": "2026-11-01T00:00:00Z",
"expiresAt": "2026-11-02T00:00:00Z"
}
}
Authorizations
Every valid key can submit and query its own account. Revoked keys are rejected.