LLM Documentation
Complete API reference for AI assistants and code generation
LLM Context Document
Copy this entire document and paste it into your LLM context for complete API understanding.
Usage Instructions
Paste this context document into your AI assistant (Claude, GPT, etc.) when you need it to:
- Write code that interacts with this API
- Generate scripts for batch operations
- Debug API integration issues
- Create custom tooling around the media service
# Media Service API - LLM Context Document
## Overview
This is a REST API for managing media files (images and videos) with folder organization, automatic image optimization, and video transcoding.
**Base URL:** http://localhost:3000/api
## Authentication
All endpoints require an API key via one of:
- Header: `Authorization: Bearer mds_<key>`
- Header: `X-API-Key: mds_<key>`
- Query: `?api_key=mds_<key>`
## Resource IDs
- Folders: UUID format (e.g., `550e8400-e29b-41d4-a716-446655440000`)
- Images: `img_<nanoid>` (e.g., `img_abc123xyz`)
- Videos: `vid_<nanoid>` (e.g., `vid_abc123xyz`)
## Status Values
- `uploading` - File upload in progress
- `processing` - Transcoding/variant generation in progress
- `ready` - Asset ready for use
- `failed` - Processing failed
---
## ENDPOINTS REFERENCE
### Folders
#### List Folders
```
GET /api/folders
Query: type=image|video, search=string, include_stats=true|false
Response: Array<Folder>
```
#### Create Folder
```
POST /api/folders
Body: { "name": string, "type": "image"|"video" }
Response: Folder
```
#### Get Folder
```
GET /api/folders/:id
Query: include_stats=true|false
Response: Folder with images/videos arrays
```
#### Update Folder
```
PATCH /api/folders/:id
Body: { "name": string }
Response: Folder
```
#### Delete Folder
```
DELETE /api/folders/:id
Query: delete_contents=true|false (default: false, items become unfiled)
Response: { "success": true }
```
---
### Images
#### List Images
```
GET /api/image
Query: limit=50, offset=0, folder_id=string|null, status=string, search=string, sort_by=createdAt|updatedAt|title, sort_order=asc|desc
Response: { items: Image[], total: number, limit: number, offset: number, hasMore: boolean }
```
#### Initialize Image Upload
```
POST /api/image/init
Body: { "filename": string, "contentType": string, "title"?: string, "folderId"?: string }
Response: { "imageId": string, "uploadUrl": string, "originalKey": string, "folderId"?: string }
```
#### Complete Image Upload
```
POST /api/image/complete
Body: { "imageId": string }
Response: { "success": true, "imageId": string, "status": "processing" }
```
#### Get Image
```
GET /api/image/:id
Response: Image with variants object
```
---
### Videos
#### List Videos
```
GET /api/video
Query: limit=50, offset=0, folder_id=string|null, status=string, search=string, sort_by=createdAt|updatedAt|title, sort_order=asc|desc
Response: { items: Video[], total: number, limit: number, offset: number, hasMore: boolean }
```
#### Initialize Video Upload
```
POST /api/video/init
Body: { "title": string, "folderId"?: string }
Response: { "videoId": string, "uploadUrl": string, "uploadId": string }
```
#### Get Video Status
```
GET /api/video/:id/status
Response: { "id": string, "status": string, "muxAssetId"?: string, "muxPlaybackId"?: string, "progress"?: number, "hlsUrl"?: string, "posterUrl"?: string }
```
#### Get Video
```
GET /api/video/:id
Response: Video with hlsUrl, posterUrl, gifUrl
```
---
### Bulk Operations
#### Bulk Move
```
POST /api/bulk/move
Body: { "itemIds": string[], "targetFolderId": string|null, "itemType": "image"|"video" }
Response: { "success": true, "movedCount": number, "targetFolderId": string|null }
```
#### Bulk Delete
```
POST /api/bulk/delete
Body: { "itemIds": string[], "itemType": "image"|"video" }
Response: { "success": true, "deletedCount": number }
```
#### Bulk Upload (Images only)
```
POST /api/bulk/upload
Body: { "uploads": Array<{filename, contentType, title?}>, "folderId"?: string, "itemType": "image" }
Response: { "success": true, "totalRequested": number, "successCount": number, "failureCount": number, "results": Array<{success, imageId?, uploadUrl?, filename, error?}> }
```
---
## DATA SCHEMAS
### Folder
```typescript
{
id: string; // UUID
name: string;
type: "image" | "video";
createdAt: string; // ISO 8601
updatedAt: string; // ISO 8601
_count?: { videos: number; images: number };
storage?: { count: number; size: number }; // if include_stats=true
videos?: Video[]; // if fetching single folder
images?: Image[]; // if fetching single folder
}
```
### Image
```typescript
{
id: string; // img_<nanoid>
title: string | null;
status: "uploading" | "processing" | "ready" | "failed";
folderId: string | null;
folder?: { id: string; name: string };
originalKey: string | null;
variantBase: string | null;
widths: number[]; // [320, 640, 960, 1280, 1920]
formats: string[]; // ["webp", "avif", "jpeg"]
thumbnailUrl?: string;
createdAt: string; // ISO 8601
updatedAt: string; // ISO 8601
variants?: { // when fetching single image
[width: string]: {
webp: string;
avif: string;
jpeg: string;
}
}
}
```
### Video
```typescript
{
id: string; // vid_<nanoid>
title: string;
status: "uploading" | "processing" | "ready" | "failed";
durationSec: number | null;
folderId: string | null;
folder?: { id: string; name: string };
muxAssetId: string | null;
muxPlaybackId: string | null;
hlsUrl?: string; // https://stream.mux.com/{playbackId}.m3u8
posterUrl?: string; // https://image.mux.com/{playbackId}/thumbnail.jpg
gifUrl?: string; // https://image.mux.com/{playbackId}/animated.gif
createdAt: string; // ISO 8601
updatedAt: string; // ISO 8601
}
```
---
## COMMON WORKFLOWS
### Upload Single Image
```bash
# 1. Initialize upload
curl -X POST "http://localhost:3000/api/image/init" \
-H "Authorization: Bearer mds_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"filename":"photo.jpg","contentType":"image/jpeg","folderId":"FOLDER_ID"}'
# Returns: { imageId, uploadUrl, originalKey }
# 2. Upload file to R2
curl -X PUT "UPLOAD_URL_FROM_STEP_1" \
-H "Content-Type: image/jpeg" \
--data-binary "@photo.jpg"
# 3. Complete upload (triggers variant generation)
curl -X POST "http://localhost:3000/api/image/complete" \
-H "Authorization: Bearer mds_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"imageId":"IMAGE_ID_FROM_STEP_1"}'
```
### Upload Single Video
```bash
# 1. Initialize upload
curl -X POST "http://localhost:3000/api/video/init" \
-H "Authorization: Bearer mds_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"My Video","folderId":"FOLDER_ID"}'
# Returns: { videoId, uploadUrl, uploadId }
# 2. Upload file to Mux
curl -X PUT "MUX_UPLOAD_URL_FROM_STEP_1" \
-H "Content-Type: video/mp4" \
--data-binary "@video.mp4"
# 3. Poll status until ready (2-3 min typical)
curl "http://localhost:3000/api/video/VIDEO_ID/status" \
-H "Authorization: Bearer mds_YOUR_KEY"
```
### Get All Ready Images in a Folder
```bash
curl "http://localhost:3000/api/image?folder_id=FOLDER_ID&status=ready&limit=100" \
-H "Authorization: Bearer mds_YOUR_KEY"
```
### Move Items to Different Folder
```bash
curl -X POST "http://localhost:3000/api/bulk/move" \
-H "Authorization: Bearer mds_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"itemIds":["img_a","img_b"],"targetFolderId":"NEW_FOLDER_ID","itemType":"image"}'
```
---
## RATE LIMITS
- List endpoints: 100 req/min
- Create endpoints: 30-50 req/min
- Delete endpoints: 10 req/min
- Bulk operations: 10-20 req/min
Rate limit headers:
- `X-RateLimit-Limit`: Max requests
- `X-RateLimit-Remaining`: Remaining requests
- `X-RateLimit-Reset`: Reset timestamp (ms)
---
## ERROR RESPONSES
```json
{ "error": "Error message" }
```
HTTP Status Codes:
- 400: Bad request / Invalid parameters
- 401: Unauthorized / Invalid API key
- 404: Resource not found
- 429: Rate limit exceeded
- 500: Server error
---
## SUPPORTED CONTENT TYPES
### Images
- image/jpeg
- image/png
- image/webp
- image/gif
- image/avif
### Videos
- video/mp4
- video/quicktime
- video/webm
- video/x-msvideo
---
## IMAGE VARIANT URLs
After processing, images are available at:
```
https://R2_PUBLIC_URL/images/variants/{imageId}/{width}.{format}
Examples:
- /images/variants/img_abc123/320.webp
- /images/variants/img_abc123/1920.avif
- /images/variants/img_abc123/640.jpeg
```
Available widths: 320, 640, 960, 1280, 1920
Available formats: webp, avif, jpeg
---
## VIDEO STREAMING URLs
After processing, videos are available via Mux CDN:
```
HLS Stream: https://stream.mux.com/{playbackId}.m3u8
Thumbnail: https://image.mux.com/{playbackId}/thumbnail.jpg
Animated: https://image.mux.com/{playbackId}/animated.gif
```