---
title: "Create upload transaction"
method: PUT
path: "/v2/media/s3/upload-transactions"
tags: ["Media - S3 Direct Upload"]
---

# Create upload transaction

`PUT /v2/media/s3/upload-transactions`

## Request

- Base URL: `https://app.metricool.com/api`
- URL: `https://app.metricool.com/api/v2/media/s3/upload-transactions`
- Auth: none declared

Creates a new upload transaction. Specify resourceType (e.g. PLANNER) and the list of parts. The backend derives the storage bucket and path from the resource type and your user ID. Single-part → simple presigned URL. Multi-part → multipart upload with per-part presigned URLs.

## Request body

- S3PresignedUploadRequest: Request to generate presigned URLs for direct S3 upload
  - `resourceType` 'planner' | 'studio-logo', required: Type of resource being uploaded. Determines the storage strategy (bucket and path). Case-insensitive. Supported values: 'planner', 'studio-logo'.
  - `contentType` string, required: MIME type of the file
  - `parts` S3UploadPart[], required: List of parts that compose the file. Each part includes size, byte range, and verification hash. Parts must be consecutive without gaps, and the total must cover the entire file. A single-part list results in a simple upload. Multiple parts trigger multipart upload.
    - `size` integer, required: Size of this part in bytes
    - `startByte` integer, required: Starting byte position in the original file (0-based, inclusive)
    - `endByte` integer, required: Ending byte position in the original file (0-based, exclusive)
    - `hash` string, required: Base64-encoded SHA-256 hash of this part's content. Used for integrity verification with S3 Object Lock.
  - `fileExtension` string: Optional file extension hint (e.g., 'mp4', 'jpg'). If not provided, derived from contentType.

## Response `200`

Upload transaction created successfully

- JsonOkResponseS3UploadResponse
  - `metadata` object
  - `page` JsonPaging
    - `next` string
  - `data` S3UploadResponse: Response containing presigned URLs for S3 upload (simple or multipart)
    - `key` string, required: S3 object key where the file will be stored
    - `bucket` string, required: S3 bucket name
    - `expiresAt` string, date-time, required: Expiration time of the presigned URLs
    - `fileUrl` string: Final file URL (available after upload completes)
    - `presignedUrl` string: Presigned URL for simple upload (only for files < 5MB)
    - `uploadId` string: Upload ID for multipart upload (only for files >= 5MB)
    - `parts` S3PartPresignedUrl[]: List of parts with presigned URLs for multipart upload (only for files >= 5MB)
      - `partNumber` integer, required: Part number (1-based index)
      - `presignedUrl` string, required: Presigned URL to upload this part
      - `partSize` integer, required: Size of this part in bytes
      - `startByte` integer, required: Start byte offset of this part in the original file
      - `endByte` integer, required: End byte offset of this part in the original file (exclusive)
    - `totalSize` integer: Total file size in bytes
    - `uploadType` string, required: Upload type: SIMPLE or MULTIPART

## Other responses

- `400`: Invalid request parameters or part configuration
- `401`: User not authenticated
- `403`: Feature not enabled for user

---

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