Create Upload URL
Overview
Create a pre-signed upload URL for direct browser or server uploads. Call this first when you want to upload a local file to API Mall storage and then pass the returned public URL into image, video, or audio generation requests.
Authentication
All API requests require a Bearer token in the request header.
Authorization: Bearer YOUR_API_KEYCreate and manage API keys from API Keys or use https://www.apimall.ai/api-keys.
Request
API Information
- URL:
POST https://gateway.apimall.ai/api/v1/files/upload-url - Content-Type:
application/json
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
filename | string | Required | Original filename used to derive the stored object key. |
content_type | string | Required | MIME type of the file being uploaded. API Mall accepts public `image/*`, `video/*`, and `audio/*` uploads. |
file_size | integer | Required | File size in bytes. Maximum `104857600` bytes (100 MB). |
expires_in | integer | Optional | Requested upload URL lifetime in seconds. Default: Range: 60 - 3600 |
Request Example
{
"filename": "cover.png",
"content_type": "image/png",
"file_size": 524288,
"expires_in": 900
}Response Example
{
"success": true,
"data": {
"upload_url": "https://pub-example.r2.cloudflarestorage.com/uploads/cover.png?signature=...",
"key": "uploads/2026/03/12/cover.png",
"public_url": "https://cdn.apimall.ai/uploads/2026/03/12/cover.png",
"expires_in": 900,
"max_file_size": 104857600,
"content_type": "image/png"
},
"request_id": "req_01HQ9M7J7X9P7Y8T6W5V4U3S2R"
}cURL Example
curl --request POST 'https://gateway.apimall.ai/api/v1/files/upload-url' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"filename": "cover.png",
"content_type": "image/png",
"file_size": 524288,
"expires_in": 900
}'JavaScript Example
const API_KEY = process.env.APIMALL_API_KEY;
const fs = await import('node:fs/promises');
const filePath = './cover.png';
const fileBytes = await fs.readFile(filePath);
const metadata = {
filename: 'cover.png',
content_type: 'image/png',
file_size: fileBytes.byteLength,
expires_in: 900,
};
const createRes = await fetch('https://gateway.apimall.ai/api/v1/files/upload-url', {
method: 'POST',
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(metadata),
});
if (!createRes.ok) {
throw new Error(`Create upload URL failed: ${createRes.status} ${createRes.statusText}`);
}
const createJson = await createRes.json();
const uploadUrl = createJson.data?.upload_url;
const publicUrl = createJson.data?.public_url;
if (!uploadUrl || !publicUrl) {
throw new Error('Missing upload_url or public_url in response');
}
const uploadRes = await fetch(uploadUrl, {
method: 'PUT',
headers: {
'Content-Type': metadata.content_type,
},
body: fileBytes,
});
if (!uploadRes.ok) {
throw new Error(`Direct upload failed: ${uploadRes.status} ${uploadRes.statusText}`);
}
console.log({ publicUrl });Response Parameters
| Parameter | Type | Description |
|---|---|---|
success | boolean | Whether the request completed successfully. |
data.upload_url | string | Pre-signed upload URL used to upload the file directly to storage. |
data.key | string | Storage object key assigned to the uploaded file. |
data.public_url | string | Public CDN URL for the uploaded file after it is stored. |
data.expires_in | integer | Number of seconds before the upload URL expires. |
data.max_file_size | integer | Maximum allowed file size in bytes for this upload. |
data.content_type | string | Detected or required MIME type for the uploaded file. |
request_id | string | Request identifier for debugging and support. |
Error Response Example
{
"success": false,
"error": {
"code": "invalid_request",
"message": "Unsupported content_type",
"details": {
"max_file_size": 104857600
}
},
"request_id": "req_01HQ9M7J7X9P7Y8T6W5V4U3S2R"
}Integration Notes
- Store your API key on the server side only.
Error Codes
Common Error Codes
| Status Code | Description |
|---|---|
| 200 | Request successful |
| 400 | Invalid request parameters |
| 401 | API key required or invalid API key |
| 403 | API access not approved or request made on a non-gateway host |
| 429 | Rate limit exceeded or too many concurrent jobs |
| 500 | Internal server error |