Upload media files
Upload multiple media files with cloud storage, optimization, and CDN delivery.
## File Limits
- **Maximum files**: 200 files per request
- **Maximum size**: 50MB per file
- **Total size**: 1GB per request
- **Supported formats**: JPEG, PNG, WebP, GIF, MP4, PDF
## Image Processing (Automatic)
When uploading images, 6 variants are auto-generated:
- **thumbnail**: 150x150 (preview)
- **web**: 2560x1700 (web display, WebP 90% quality)
- **mls**: 1280x850 (MLS listing size, JPEG 95%)
- **print**: Original size (JPEG 95%)
- **webp_web**: 2560x1700 (WebP format)
- **webp_thumb**: 400x400 (WebP thumbnail)
## Storage Strategies
- **cloud** (default): DigitalOcean Spaces with CDN
- **local**: Server filesystem (dev/testing only)
- **hybrid**: Critical files to cloud, others local
## Performance
- **Timeout**: 60 seconds
- **Expected Duration**: 2-30 seconds (depends on file count/size)
- **Progress Tracking**: SSE stream at `/v1/progress/{operation_id}`
- **Rate Limit**: 50 uploads per minute per user
## Authorization
- **Required**: Any authenticated user
- **Rate Limited**: 50 req/min
## Examples
```bash
# Upload single image
curl -X POST https://dash.jacoballenmedia.com/api/v1/media/upload \
-H "Cookie: better-auth-session=..." \
-F "files=@photo.jpg" \
-F "related_entity_type=tour" \
-F "related_entity_id=hmrek1t"
# Upload multiple files with optimization
curl -X POST /api/v1/media/upload \
-F "files=@photo1.jpg" \
-F "files=@photo2.jpg" \
-F "storage_strategy=cloud" \
-F "enable_optimization=true"
```
| Method | Path |
|---|---|
POST | /api/v1/media/upload |
Primary host: https://valara.cloud (legacy alias: https://dash.jacoballenmedia.com).
Parameters
(no path or query parameters)
Request body
(no request body)
Response
null
Responses
| Status | Description |
|---|---|
200 | Upload started successfully - use operation_id to track progress |
400 | Validation error - too many files, file too large, or unsupported format (see error codes) |
401 | Authentication required (see error codes) |
413 | Payload too large - file exceeds 50MB or total exceeds 1GB (see error codes) |
422 | Validation Error (see error codes) |
429 | Rate limit exceeded - max 50 uploads per minute (see error codes) |
500 | Upload failed - storage service unavailable or processing error (see error codes) |
Examples
curl
curl -X POST "https://valara.cloud/api/v1/media/upload" \
-H "Authorization: Bearer $VALARA_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: $(uuidgen)"
Python
import os
import uuid
import httpx
res = httpx.request(
"POST",
"https://valara.cloud/api/v1/media/upload",
headers={
"Authorization": f"Bearer {os.environ['VALARA_API_KEY']}",
"Content-Type": "application/json",
"X-Idempotency-Key": str(uuid.uuid4()),
},
)
res.raise_for_status()
print(res.json())