Media Upload API
Upload images and videos to get hosted URLs that can be used with the Publishing API.
Overview
The Media Upload API allows you to upload files directly to Boring's cloud storage and receive a public URL. This is useful when:
- You have local files instead of public URLs
- You want to host media files on Boring's CDN
- You need to upload files before publishing to social platforms
Files are automatically assigned unique random filenames (UUID) to prevent collisions between users.
Endpoint
POST /api/v2/media/upload
Authentication
Requires API Key authentication:
boring-api-key: boring_xxxxxxxxxxxxx
Request Format
Content-Type
Content-Type: multipart/form-data
Form Fields
| Field | Type | Required | Description |
|---|---|---|---|
file |
File | Yes | The image or video file to upload |
Supported File Types
Images:
- JPEG (.jpg, .jpeg)
- PNG (.png)
- GIF (.gif)
- WebP (.webp)
Videos:
- MP4 (.mp4)
- MOV (.mov)
- AVI (.avi)
- WebM (.webm)
File Size Limits
| Type | Max Size |
|---|---|
| Images | 10 MB |
| Videos | 500 MB |
Response
Success Response
{
"success": true,
"data": {
"url": "https://storage.googleapis.com/boring-video-uploads/media/550e8400-e29b-41d4-a716-446655440000.jpg",
"filename": "550e8400-e29b-41d4-a716-446655440000.jpg",
"content_type": "image/jpeg",
"size": 102400,
"uploaded_at": "2024-12-17T10:30:00Z"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
url |
String | Public URL of the uploaded file |
filename |
String | Generated unique filename (UUID format) |
content_type |
String | MIME type of the file |
size |
Integer | File size in bytes |
uploaded_at |
String | ISO 8601 timestamp |
Error Responses
400 Bad Request - No file provided:
{
"success": false,
"error": "No file provided"
}
400 Bad Request - Invalid file type:
{
"success": false,
"error": "Invalid file type. Supported: jpg, jpeg, png, gif, webp, mp4, mov, avi, webm"
}
400 Bad Request - File too large:
{
"success": false,
"error": "File too large. Max size: 10MB for images, 500MB for videos"
}
401 Unauthorized:
{
"success": false,
"error": "Invalid API key"
}
Examples
cURL - Upload Image
curl -X POST https://boring.aiagent-me.com/api/v2/media/upload \
-H "boring-api-key: boring_xxxxxxxxxxxxx" \
-F "file=@/path/to/image.jpg"
cURL - Upload Video
curl -X POST https://boring.aiagent-me.com/api/v2/media/upload \
-H "boring-api-key: boring_xxxxxxxxxxxxx" \
-F "file=@/path/to/video.mp4"
Python
import requests
api_key = "boring_xxxxxxxxxxxxx"
url = "https://boring.aiagent-me.com/api/v2/media/upload"
# Upload an image
with open("image.jpg", "rb") as f:
response = requests.post(
url,
headers={"boring-api-key": api_key},
files={"file": f}
)
result = response.json()
if result["success"]:
media_url = result["data"]["url"]
print(f"Uploaded: {media_url}")
JavaScript (Node.js)
const fs = require('fs');
const FormData = require('form-data');
const fetch = require('node-fetch');
const apiKey = 'boring_xxxxxxxxxxxxx';
const url = 'https://boring.aiagent-me.com/api/v2/media/upload';
const form = new FormData();
form.append('file', fs.createReadStream('image.jpg'));
const response = await fetch(url, {
method: 'POST',
headers: {
'boring-api-key': apiKey,
},
body: form,
});
const result = await response.json();
if (result.success) {
console.log('Uploaded:', result.data.url);
}
JavaScript (Browser)
const apiKey = 'boring_xxxxxxxxxxxxx';
const url = 'https://boring.aiagent-me.com/api/v2/media/upload';
// Assuming you have a file input element
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
const formData = new FormData();
formData.append('file', file);
const response = await fetch(url, {
method: 'POST',
headers: {
'boring-api-key': apiKey,
},
body: formData,
});
const result = await response.json();
if (result.success) {
console.log('Uploaded:', result.data.url);
}
Usage with Publishing API
After uploading media, use the returned URL with the Publishing API:
# Step 1: Upload image
curl -X POST https://boring.aiagent-me.com/api/v2/media/upload \
-H "boring-api-key: boring_xxxxxxxxxxxxx" \
-F "file=@photo.jpg"
# Response: {"success": true, "data": {"url": "https://storage.googleapis.com/boring-video-uploads/media/550e8400-e29b-41d4-a716-446655440000.jpg", ...}}
# Step 2: Publish with the uploaded URL
curl -X POST https://boring.aiagent-me.com/api/v2/posts \
-H "boring-api-key: boring_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"post": {
"accountId": "your-account-id",
"content": {
"text": "Check out this photo!",
"mediaUrls": ["https://storage.googleapis.com/boring-video-uploads/media/550e8400-e29b-41d4-a716-446655440000.jpg"]
},
"target": {
"targetType": "instagram"
}
}
}'
Multiple File Upload
To upload multiple files, make separate requests for each file:
import requests
api_key = "boring_xxxxxxxxxxxxx"
url = "https://boring.aiagent-me.com/api/v2/media/upload"
files_to_upload = ["image1.jpg", "image2.jpg", "image3.jpg"]
uploaded_urls = []
for filepath in files_to_upload:
with open(filepath, "rb") as f:
response = requests.post(
url,
headers={"boring-api-key": api_key},
files={"file": f}
)
result = response.json()
if result["success"]:
uploaded_urls.append(result["data"]["url"])
print(f"Uploaded {len(uploaded_urls)} files")
# Use uploaded_urls with Publishing API
File Retention
- Uploaded files are stored permanently
- Files are publicly accessible via the returned URL
- No automatic cleanup or expiration
Rate Limits
| Plan | Requests/minute | Max file size |
|---|---|---|
| Free | 10 | 10 MB |
| Pro | 60 | 500 MB |
Best Practices
- Validate files locally before uploading to avoid errors
- Use appropriate formats - JPEG for photos, PNG for graphics, MP4 for videos
- Compress large files before uploading to reduce upload time
- Store returned URLs for later use with the Publishing API
- Handle errors gracefully - implement retry logic for failed uploads
See Also
- Publishing API - Use uploaded media URLs to publish posts
- Errors - Complete error reference
- API Keys - How to get and manage API keys