curl --request POST \
--url https://api.poyo.ai/api/common/upload/stream \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form file=@example-file{
"success": true,
"code": 200,
"msg": "File uploaded successfully",
"data": {
"file_id": "872defd8180ee9c6d32265ef4e8d255b",
"file_name": "test-stream.png",
"file_size": 3242,
"mime_type": "image/png",
"file_url": "https://storage.poyo.ai/temp/videos/input-video.mp4",
"download_url": "https://storage.poyo.ai/temp/videos/input-video.mp4",
"expires_at": "2026-01-01T13:09:04.731057",
"original_name": "uploaded-file.png",
"upload_path": "temp/videos",
"upload_time": "2025-12-29T13:09:04.731057"
}
}Upload File Stream
Upload files to PoYo AI using multipart/form-data format for direct file uploads
curl --request POST \
--url https://api.poyo.ai/api/common/upload/stream \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form file=@example-file{
"success": true,
"code": 200,
"msg": "File uploaded successfully",
"data": {
"file_id": "872defd8180ee9c6d32265ef4e8d255b",
"file_name": "test-stream.png",
"file_size": 3242,
"mime_type": "image/png",
"file_url": "https://storage.poyo.ai/temp/videos/input-video.mp4",
"download_url": "https://storage.poyo.ai/temp/videos/input-video.mp4",
"expires_at": "2026-01-01T13:09:04.731057",
"original_name": "uploaded-file.png",
"upload_path": "temp/videos",
"upload_time": "2025-12-29T13:09:04.731057"
}
}Usage Guide
- This endpoint enables direct file uploads using the standard
multipart/form-dataformat - Supports uploading files directly from local storage with automatic file type identification
- Best suited for local file uploads from desktop applications, mobile apps, or web forms
- Files are immediately accessible via the returned URL. Images remain available for 72 hours; videos remain available for 24 hours when stored under the
temp/videoslifecycle prefix
Parameter Details
-
File Upload Requirement:
-
The
filefield must contain binary file data - Supported image formats: JPEG, PNG, GIF, WebP
- Supported video formats: MP4, WebM, MOV/QuickTime, AVI, MKV
- Maximum upload limit: 1 file per request. Videos are limited to 100MB
- The system automatically identifies the file type from the binary data
-
The
-
Parameter Naming Convention:
- This endpoint supports both snake_case and camelCase naming conventions
-
upload_pathoruploadPath- both are accepted -
file_nameorfileName- both are accepted - Use whichever convention matches your application’s coding style
-
Storage Configuration:
-
All files are automatically stored with a
temp/prefix in the storage path -
If you specify
upload_path: "photos", the actual path will betemp/photos - Images expire and are automatically deleted 72 hours after upload
-
Videos uploaded with the default path are stored under
temp/videos/and expire after 24 hours when the R2 lifecycle rule is configured for that prefix
-
All files are automatically stored with a
-
File Naming:
-
If
file_nameis not provided, the system generates a unique name in the format:{timestamp}_{random}_{extension} -
Example auto-generated name:
20251229130857_a8B9cD2e.png
-
If
Developer Notes
-
When to use file stream upload:
- Direct file uploads from user’s local storage
- Form-based file uploads from web applications
- Mobile app file uploads
- Server-to-server file transfers
- This is the most efficient upload method for files already stored on disk
- The multipart/form-data format is standard across all programming languages and HTTP clients
- For persistent storage needs, download and save the file locally before expiration: 72 hours for images, 24 hours for videos
Rate Limits and Quotas
- Rate Limit: 10 requests per 60-second fixed window per authenticated user, per upload endpoint
-
When the rate limit is exceeded, you will receive a
429 Too Many Requestserror - The fixed window starts with the first request in the window and is shared by JWT and API key requests from the same user
- Implement exponential backoff retry logic for handling rate limit errors
Common Error Scenarios
- Missing File: No file was provided in the request body (422 error)
- Unsupported File Type: The uploaded file is not a supported image format (JPEG, PNG, GIF, WebP) or video format (MP4, WebM, MOV/QuickTime, AVI, MKV)
- Video Too Large: The uploaded video exceeds the 100MB limit (413 error)
- Empty File: The uploaded file has zero bytes or is corrupted
- Authentication Error: Missing or invalid API key in the Authorization header
Example Usage
cURL Example
curl -X POST "https://api.poyo.ai/api/common/upload/stream" \
-H "Authorization: Bearer PoYo_API_KEY" \
-F "file=@/path/to/image.png" \
-F "file_name=my-image.png"
Python Example
import requests
url = "https://api.poyo.ai/api/common/upload/stream"
headers = {"Authorization": "Bearer PoYo_API_KEY"}
files = {"file": open("/path/to/image.png", "rb")} # or /path/to/video.mp4
data = {"file_name": "my-image.png"}
response = requests.post(url, headers=headers, files=files, data=data)
print(response.json())
JavaScript Example (Node.js)
const FormData = require('form-data');
const fs = require('fs');
const axios = require('axios');
const form = new FormData();
form.append('file', fs.createReadStream('/path/to/image.png')); // or /path/to/video.mp4
form.append('file_name', 'my-image.png');
axios.post('https://api.poyo.ai/api/common/upload/stream', form, {
headers: {
'Authorization': 'Bearer PoYo_API_KEY',
...form.getHeaders()
}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
Video Upload Example
curl -X POST "https://api.poyo.ai/api/common/upload/stream" -H "Authorization: Bearer PoYo_API_KEY" -F "file=@/path/to/video.mp4" -F "file_name=my-video.mp4"
temp/videos/. Configure the R2 lifecycle rule for this prefix to expire objects after 1 day.Authorizations
All API endpoints require Bearer Token authentication
Get your API Key:
Visit the API Key Management Page to get your API Key
Add it to the request header:
Authorization: Bearer PoYo_API_KEY
Body
File binary data to upload.
Supported image formats: JPEG, PNG, GIF, WebP
Supported video formats: MP4, WebM, QuickTime/MOV, AVI, MKV
Maximum: 1 file per request. Videos are limited to 100MB.
Retention: Images expire after 72 hours. Videos expire after 24 hours when stored under the temp/videos lifecycle prefix.
Note: The system automatically identifies and categorizes file types.
Custom storage directory path.
Supports both naming conventions:
- snake_case:
upload_path - camelCase:
uploadPath
If not specified, the system uses temp. Video uploads using the default temp path are stored as temp/videos.
Note: API routing normalizes custom paths under the temp/ prefix.
"photos"
Custom filename for the uploaded file.
Supports both naming conventions:
- snake_case:
file_name - camelCase:
fileName
If not specified, the system will generate a unique filename in the format: {timestamp}_{random}_{extension}
Example auto-generated name: 20251229130857_a8B9cD2e.png
"photo.png"
