Skip to main content

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"
```
MethodPath
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

StatusDescription
200Upload started successfully - use operation_id to track progress
400Validation error - too many files, file too large, or unsupported format (see error codes)
401Authentication required (see error codes)
413Payload too large - file exceeds 50MB or total exceeds 1GB (see error codes)
422Validation Error (see error codes)
429Rate limit exceeded - max 50 uploads per minute (see error codes)
500Upload 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())

See also