Upload Pipeline
Presigned URL uploads that go directly to storage, bypassing your API server.
How It Works
text
Client API R2/S3
│ │ │
│─── POST /presign ─────▶│ │
│◀── upload_url + key ───│ │
│ │ │
│─── PUT upload_url ────────────────────────────▶│
│◀── 200 OK ─────────────────────────────────────│
│ │ │
│─── POST /complete ────▶│ │
│◀── asset created ──────│── enqueue transcode ──▶│
│ │ │The file never touches your API server — it goes directly from the browser to R2/S3 via presigned URL. This keeps your API fast and avoids memory/bandwidth issues with large files.
Step 1: Request Presigned URL
bash
curl -X POST /api/mediakit/uploads/presign \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filename": "vacation.mp4",
"content_type": "video/mp4",
"file_size": 104857600,
"asset_type": "video",
"title": "Vacation Highlights"
}'Request Body
| Field | Type | Description |
|---|---|---|
| filename | string | Original filename |
| content_type | string | MIME type (video/mp4, image/jpeg, etc.) |
| file_size | number | File size in bytes |
| asset_type | string | "video" or "image" |
| title | string | Display title |
Step 2: Upload to Presigned URL
bash
curl -X PUT "PRESIGNED_URL" \
-H "Content-Type: video/mp4" \
--data-binary @vacation.mp4Or in JavaScript with progress tracking:
upload.ts
const xhr = new XMLHttpRequest();
xhr.open("PUT", presignedUrl);
xhr.setRequestHeader("Content-Type", file.type);
xhr.upload.onprogress = (e) => {
const percent = Math.round((e.loaded / e.total) * 100);
console.log(`Upload progress: ${percent}%`);
};
xhr.onload = () => {
if (xhr.status === 200) {
// Step 3: Confirm upload
completeUpload(assetId, key);
}
};
xhr.send(file);Step 3: Confirm Upload
bash
curl -X POST /api/mediakit/uploads/complete \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{"asset_id": 1, "key": "uploads/abc/vacation.mp4"}'After confirming, if the asset is a video, a transcode job is automatically enqueued. For images, the asset is marked as "ready" immediately.
Delete an Asset
bash
curl -X DELETE /api/mediakit/uploads/1 \
-H "Authorization: Bearer TOKEN"This deletes the asset record, all quality renditions, and the original file from storage.
Size Limits
Default max upload size is 10 GB (configurable via MAX_UPLOAD_SIZE_MB env var). Since uploads go directly to R2/S3, your API server's memory is not affected.