---
title: "Confirm Upload"
method: POST
path: "/v1/buckets/{bucket_identifier}/uploads/{upload_id}/confirm"
tags: ["Bucket Uploads"]
---

# Confirm Upload

`POST /v1/buckets/{bucket_identifier}/uploads/{upload_id}/confirm`

## Request

- Base URL: `https://api.mixpeek.com`
- URL: `https://api.mixpeek.com/v1/buckets/{bucket_identifier}/uploads/{upload_id}/confirm`
- Auth: HTTP bearer and API key in header `X-Namespace`

Verify S3 upload completion and create bucket object.

    After uploading to S3 using the presigned URL, call this endpoint to:
    1. Verify the file exists in S3
    2. Validate ETag and file size (if provided)
    3. Create bucket object (default, unless create_object_on_confirm=false)
    4. Update upload status to COMPLETED

    **Processing**: the created object is PENDING and is not processed by
    confirmation. Add it to a batch and submit the batch to start processing,
    or set `auto_submit_batch=true` on this request to create and submit a
    batch for the new object in the same call.

    **Sync vs Async**:
    - Files < 100MB: Processed synchronously (~100ms)
    - Files >= 100MB or async=true: Processed asynchronously (returns task_id)

    **Duplicate Detection**:
    - If file hash matches existing upload, marks as duplicate
    - References original object_id if available

    **Unique Keys**:
    - If the bucket has a unique_key, the object is created under an insertion
      policy: `?policy=insert|update|upsert` on this request, else the bucket's
      `unique_key.default_policy`. With neither, confirmation returns 422.

## Path parameters

- `bucket_identifier` string, required: The unique identifier of the bucket
- `upload_id` string, required: The unique identifier of the upload

## Query parameters

- `async` boolean: Process confirmation asynchronously (recommended for files >= 100MB)
- `policy` 'insert' | 'update' | 'upsert', nullable: Insertion policy for unique key enforcement on the object created at confirmation. Valid values: 'insert', 'update', 'upsert'. Only applies if the bucket has a unique_key. Overrides the bucket's default_policy, matching ?policy= on POST /objects. Required when the bucket has a unique_key and no default_policy.

## Request body

- ConfirmUploadRequest: Request to confirm S3 upload completion and create bucket object. ⚠️ THIS ENDPOINT IS REQUIRED AFTER UPLOADING TO S3! S3 presigned URLs have no callback mechanism - the API cannot detect when your upload completes. You MUST call this endpoint to finalize the upload. Why confirmation is required: - S3 doesn't notify us when uploads complete - We need to verify the file actually exists in S3 - We need to create the bucket object - We need to update quotas and tracking The system will: 1. Verify the S3 object exists (HeadObject call) 2. Validate ETag matches (if provided) - RECOMMENDED for integrity 3. Validate file size matches (if provided) 4. Create bucket object (default, unless create_object_on_confirm=false) 5. Update upload status to COMPLETED If you don't call confirm: - Upload stays in PENDING status - No bucket object is created - File is orphaned in S3
  - `etag` string, nullable: S3 ETag returned from the upload. OPTIONAL but RECOMMENDED. After uploading to S3, the response includes an ETag header. Providing this ensures the file wasn't corrupted during upload. If provided and doesn't match S3's ETag, confirmation will fail with error. Format: Usually an MD5 hash, may be enclosed in quotes.
  - `file_size_bytes` integer, nullable: Actual file size uploaded, in bytes. OPTIONAL but RECOMMENDED. If provided, will be validated against the actual S3 object size. Mismatch indicates upload corruption or network issues. If not provided, size validation is skipped.
  - `auto_submit_batch` boolean: If true, automatically create AND submit a batch containing the newly created object after confirmation. The returned ``task_id`` will be the submitted batch's task id, and ``batch_id`` will be populated. Eliminates the need for separate POST /batches and POST /batches/{id}/submit calls during bulk ingest. Has no effect if ``create_object_on_confirm`` is false or the object is a duplicate. If the batch is created but the submit is refused (for example a namespace daily budget, a quota or a validation error), the request fails with that error, and its details carry ``upload_id``, ``object_id`` and the DRAFT ``batch_id``: the upload and object are kept, and the batch can be submitted later with POST /batches/{id}/submit. Defaults to false for backwards compatibility — existing flows that batch many objects into one submission still work.

## Response `200`

Successful Response

- ConfirmUploadResponse: Response from upload confirmation.
  - `upload_id` string, required: Upload ID that was confirmed
  - `status` 'PENDING' | 'QUEUED' | 'IN_PROGRESS' | 'PROCESSING' | 'COMPLETED' | 'COMPLETED_WITH_ERRORS' | 'FAILED' | 'CANCELED' | 'INTERRUPTED' | 'UNKNOWN' | 'SKIPPED' | 'DRAFT' | 'ACTIVE' | 'ARCHIVED' | 'SUSPENDED' | 'DEACTIVATED', required: Enumeration of task statuses for tracking asynchronous operations. Task statuses indicate the current state of asynchronous operations like batch processing, object ingestion, clustering, and taxonomy execution. Status Categories: Operation Statuses: Track progress of async operations Lifecycle Statuses: Track entity state (buckets, collections, namespaces) Values: PENDING: Task is queued but has not started processing yet IN_PROGRESS: Task is currently being executed PROCESSING: Task is actively processing data (similar to IN_PROGRESS) COMPLETED: Task finished successfully with no errors COMPLETED_WITH_ERRORS: Task finished but some items failed (partial success) FAILED: Task encountered an error and could not complete CANCELED: Task was manually canceled by a user or system UNKNOWN: Task status could not be determined SKIPPED: Task was intentionally skipped DRAFT: Task is in draft state and not yet submitted ACTIVE: Entity is active and operational (for buckets, collections, etc.) ARCHIVED: Entity has been archived SUSPENDED: Entity has been temporarily suspended Terminal Statuses: COMPLETED, COMPLETED_WITH_ERRORS, FAILED, CANCELED are terminal statuses. Once a task reaches these states, it will not transition to another state. Partial Success Handling: COMPLETED_WITH_ERRORS indicates that the operation completed but some documents/items failed. The task result includes: - List of successful items - List of failed items with error details - Success rate percentage This allows clients to handle partial success scenarios appropriately. Polling Guidance: - Poll tasks in PENDING, QUEUED, IN_PROGRESS, or PROCESSING states - Stop polling when task reaches COMPLETED, COMPLETED_WITH_ERRORS, FAILED, or CANCELED - Use exponential backoff (1s → 30s) when polling
  - `etag` string, nullable: S3 ETag from uploaded object
  - `file_size_bytes` integer, nullable: Actual file size from S3
  - `file_hash` string, nullable: File content hash (from ETag)
  - `verified_at` string, date-time, nullable: When verification completed
  - `completed_at` string, date-time, nullable: When upload completed
  - `object_id` string, nullable: Created bucket object ID (if create_object_on_confirm was true)
  - `task_id` string, nullable: Task ID for async processing. Populated when auto_submit_batch=true (holds the submitted batch's first-tier task id) or when async=true.
  - `batch_id` string, nullable: Batch ID created and submitted by auto_submit_batch=true. Use it to poll status via GET /v1/buckets/{id}/batches/{batch_id}.
  - `message` string, nullable: Confirmation message

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not Found
- `422`: Unprocessable Entity
- `429`: Too Many Requests
- `500`: Internal Server Error
- `503`: Service Unavailable

## Changes

- **2026-10-09** `61a175e8eb9a`: 1 warning, 5 info
  - removed the optional property `detail` from the response with the `422` status
  - added the non-success response with the status `429`
  - added the non-success response with the status `503`
  - added the optional property `success` to the response with the `422` status
  - …2 more
- **2026-10-04** `38e0822db900`: 1 info
  - added the new optional `query` request parameter `policy`
- **2026-08-09** `5d4c905106b4`: 1 info
  - the endpoint scheme security `BearerAuth AND NamespaceHeader` was added to the API
- **2026-08-04** `9603dfdab463`: 1 warning
  - added the new `DEACTIVATED` enum value to the `status` response property for the response status `200`

[Operation history](https://skmtc.dev/mixpeek/apis/mixpeek-api/changes/v1/buckets/:bucket_identifier/uploads/:upload_id/confirm/post.md)

---

[API](https://skmtc.dev/mixpeek/apis/mixpeek-api.md) - [All operations](https://skmtc.dev/mixpeek/apis/mixpeek-api/llms.txt) - [OpenAPI document](https://skmtc.dev/mixpeek/apis/mixpeek-api/revisions/790bc16455f6?raw)
