Generate a presigned URL for direct S3 upload.
This endpoint validates all requirements BEFORE generating the presigned URL, ensuring immediate feedback if something is wrong (bucket inactive, quota exceeded, etc.).
Duplicate Detection (Enabled by Default):
file_hash provided and skip_duplicates=true: Checks for existing uploadis_duplicate=trueis_duplicate=falseTwo-Step Flow:
REQUIRED: Bearer token authentication using your API key. Format: 'Bearer sk_xxxxxxxxxxxxx'. You can create API keys in the Mixpeek dashboard under Organization Settings.
"Bearer YOUR_API_KEY"
"Bearer YOUR_STRIPE_API_KEY"
REQUIRED: Namespace identifier for scoping this request. All resources (collections, buckets, taxonomies, etc.) are scoped to a namespace. You can provide either the namespace name or namespace ID. Format: ns_xxxxxxxxxxxxx (ID) or a custom name like 'my-namespace'
"ns_abc123def456"
"production"
"my-namespace"
The unique identifier of the bucket
Request to generate a presigned URL for direct S3 upload.
⚠️ ⚠️ ⚠️ THIS IS THE PRESIGNED URL SYSTEM ⚠️ ⚠️ ⚠️
This endpoint (POST /buckets/{id}/uploads) is the COMPLETE presigned URL system. It handles:
DO NOT CREATE A NEW PRESIGNED UPLOAD ENDPOINT! If you need presigned URLs, use this existing system.
If you think you need a new endpoint:
Integration Points:
Workflow:
⚠️ IMPORTANT: Step 3 (confirm) is REQUIRED! S3 presigned URLs have no callback mechanism - the API cannot detect when your upload to S3 completes. You MUST call the confirm endpoint to:
If you don't confirm:
Use Cases: - Simple: Upload → confirm → object created automatically (default) - Advanced: Upload multiple files with create_object_on_confirm=false, then POST /buckets/{id}/objects with all upload_ids to create one object
Requirements: - filename: REQUIRED, will be validated (no path traversal) - content_type: REQUIRED, must be valid MIME type - bucket_id: Comes from URL path parameter, not request body - All other fields: OPTIONAL with sensible defaults
Note: The bucket_id comes from the URL path (/v1/buckets/{bucket_id}/uploads), not from the request body. The bucket is validated before generating presigned URL.
Name of the file to upload. REQUIRED. Must be a valid filename without path traversal characters (../, ). The filename is used to derive the blob_property if not explicitly provided. Examples: 'product_video.mp4', 'thumbnail.jpg', 'transcript.txt'
1 - 255"product_video.mp4"
"thumbnail.jpg"
"document.pdf"
MIME type of the file. REQUIRED. Must be a valid MIME type (e.g., 'video/mp4', 'image/jpeg', 'application/pdf'). The presigned URL will enforce this content type during upload. Used to validate compatibility with bucket schema if create_object_on_confirm=true.
"video/mp4"
"image/jpeg"
"image/png"
"application/pdf"
"text/plain"
Expected file size in bytes. OPTIONAL but RECOMMENDED. If provided, will be validated against: 1. Tier-based file size limits (100MB free, 5GB pro, 50GB enterprise) 2. Storage quota availability 3. Actual uploaded file size during confirmation. If not provided, quota checking is skipped until confirmation.
x >= 110485760
How long the presigned URL is valid, in seconds. OPTIONAL, defaults to 3600 (1 hour). Valid range: 60 seconds (1 minute) to 86400 seconds (24 hours). After expiration, the URL cannot be used and you must request a new one. Recommendation: Use shorter expiration (300-900 seconds) for security-sensitive files, longer expiration (3600-7200 seconds) for large files that take time to upload.
60 <= x <= 864003600
7200
900
Custom metadata for tracking purposes. OPTIONAL. Stored with the upload record for filtering and analytics. Does NOT affect the created bucket object (use object_metadata for that). Common uses: campaign tracking, user identification, upload source.
{
"campaign": "summer_2024",
"source": "mobile_app",
"user_id": "user_123"
}{
"department": "marketing",
"priority": "high"
}Whether to automatically create a bucket object when upload is confirmed. OPTIONAL, defaults to TRUE (object is created automatically). If true (default): - Bucket MUST have a schema defined - blob_property must exist in bucket schema - content_type must match schema field type - Validation happens BEFORE generating presigned URL - Object is created automatically on confirmation. If false: - Upload is confirmed but no object is created - Use this when combining multiple uploads into one object - Reference the upload_id later in POST /buckets/{id}/objects.
Metadata to attach to the created bucket object. OPTIONAL. Only used if create_object_on_confirm=true. This metadata will be: 1. Validated against bucket schema (if keys match schema fields) 2. Attached to the bucket object 3. Passed to downstream documents in connected collections. Example: {'priority': 'high', 'category': 'products', 'tags': ['featured']}
{
"category": "products",
"priority": "high"
}Property name for the blob in the bucket object. OPTIONAL. Defaults to filename without extension (e.g., 'product_video.mp4' → 'product_video'). If create_object_on_confirm=true: - Must exist in bucket schema - Must be alphanumeric with underscores only - Will be validated BEFORE generating presigned URL. Common values: 'video', 'image', 'thumbnail', 'transcript', 'content'.
"video"
Type of blob. OPTIONAL. Defaults to type derived from content_type (e.g., 'video/mp4' → 'VIDEO'). Must be a valid BucketSchemaFieldType if provided. Valid values: IMAGE, VIDEO, AUDIO, TEXT, PDF, DOCUMENT, etc. If create_object_on_confirm=true, will be validated against bucket schema field type.
"VIDEO"
SHA256 hash of the file content for duplicate detection. OPTIONAL. If provided: - System checks for existing confirmed uploads with same hash - If duplicate found and skip_duplicates=true, returns existing upload - Hash will be validated against actual S3 ETag during confirmation. If not provided: - Hash is calculated from S3 ETag after upload - Duplicate detection only happens during confirmation. Use case: Pre-calculate hash client-side to avoid uploading duplicates. Format: 64-character hexadecimal string (SHA256).
64"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
Skip upload if a file with the same hash already exists. OPTIONAL, defaults to TRUE. If true (default): - If file_hash provided: System checks MongoDB for existing completed upload with same hash - If duplicate found: Returns existing upload details WITHOUT generating new presigned URL - If file_hash NOT provided: Duplicate check happens during confirmation using S3 ETag - Saves bandwidth, storage, and upload time by reusing existing files. If false: - Always generates new presigned URL even if file already uploaded - Creates separate upload record for same file content - Useful when you need distinct upload tracking for identical files. Recommendation: Keep default (true) unless you specifically need multiple upload records for same file.
Successful Response
Response containing presigned URL and upload tracking information.
This response includes everything needed to:
The presigned_url is time-limited and specific to this upload. After uploading to S3, call POST /v1/buckets/{bucket_id}/uploads/{upload_id}/confirm.
Unique identifier for this upload. Auto-generated.
⚠️ NEXT STEP: After uploading to S3, you MUST confirm: POST /v1/uploads/{upload_id}/confirm
Other operations: - Check status: GET /v1/uploads/{upload_id} - Cancel upload: DELETE /v1/uploads/{upload_id}
Format: 'upl_' followed by 16 random characters.
"upl_a1b2c3d4e5f6"
"upl_x9y8z7w6v5u4"
Target bucket ID where object will be created
"bkt_abc123"
Name of the file to upload
"product_video.mp4"
MIME type enforced by the presigned URL
"video/mp4"
How long the presigned URL is valid, in seconds
3600
Full S3 object key where the file will be stored. Format: {internal_id}/{namespace_id}/api_buckets_uploads_create/{upload_id}/{filename}. Used internally for verification and object creation.
"int_xyz/ns_abc/api_buckets_uploads_create/upl_123/video.mp4"
Current upload status. After creation, always PENDING. Possible statuses: PENDING → IN_PROGRESS → PROCESSING → COMPLETED/FAILED/CANCELED
PENDING, IN_PROGRESS, PROCESSING, COMPLETED, COMPLETED_WITH_ERRORS, FAILED, CANCELED, UNKNOWN, SKIPPED, DRAFT, ACTIVE, ARCHIVED, SUSPENDED "PENDING"
Whether bucket object will be auto-created on confirmation
When this upload record was created (ISO 8601 format)
"2024-01-15T10:30:00Z"
When the presigned URL expires (ISO 8601 format). After this time: - The presigned URL cannot be used - Upload status will be marked as FAILED if not completed - The upload record will be auto-deleted 30 days later (MongoDB TTL)
"2024-01-15T11:30:00Z"
Expected file size in bytes if provided in request. Will be validated during confirmation.
10485760
Time-limited HTTPS URL for uploading directly to S3.
Step 1 - Upload to S3: curl -X PUT '{presigned_url}' -H 'Content-Type: {content_type}' --upload-file {filename}
Step 2 - REQUIRED: Confirm the upload: POST /v1/uploads/{upload_id}/confirm (S3 has no callback - you MUST call confirm to finalize)
The URL includes authentication and expires after presigned_url_expiration seconds. S3 returns an ETag header on success - pass it to confirm for integrity validation. NOTE: This will be null if is_duplicate=true (duplicate found, no upload needed).
1 - 2083Custom metadata for tracking
Metadata for the bucket object (if create_object_on_confirm=true)
Property name for the blob in bucket object
Type of blob (IMAGE, VIDEO, etc.)
SHA256 hash of the file content. Set during confirmation from S3 metadata or provided in request. Used for duplicate detection.
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
Whether duplicate detection was enabled for this upload
Whether this upload was identified as a duplicate of an existing file. If true: - duplicate_of_upload_id contains the original upload - presigned_url will be null (no upload needed) - You can use the original upload's S3 object. This saves bandwidth and storage costs.
If skip_duplicates=true and duplicate found, this is the original upload_id. The response will reference the existing upload instead of creating a new one.
"upl_original123"
Whether this upload was skipped because the unique key already exists in the bucket. If true: - existing_object_id contains the ID of the existing object - presigned_url will be null (no upload needed) - No S3 upload is required This saves bandwidth and prevents duplicate objects.
If skipped_unique_key=true, this is the object_id of the existing object that has the same unique key values. The upload was skipped to prevent duplicates.
"obj_abc123xyz789"
Human-readable message about the upload. Provided when is_duplicate=true or other special conditions. Example: 'File already exists with the same content hash. No upload needed - returning existing upload.'
When the upload was completed and verified (ISO 8601 format)
"2024-01-15T10:35:00Z"
When S3 object existence was verified (ISO 8601 format)
"2024-01-15T10:35:00Z"
S3 ETag from the uploaded object (set during confirmation)
"d41d8cd98f00b204e9800998ecf8427e"
Created bucket object ID (if create_object_on_confirm was true)
"obj_a1b2c3d4e5f6"
Celery task ID for async confirmation (if processed asynchronously)
"task_abc123"