---
title: "Create File"
method: POST
path: "/files"
tags: ["Files"]
---

# Create File

`POST /files`

Creates a file and returns a presigned destination to upload its bytes to. PUT the bytes to `upload_url` (single-part), or to each of `multipart_upload_urls` and then call Complete File Multipart Upload. Once the bytes land the file becomes `ready`, and its ID can be attached wherever a file is accepted — account legal documents, dispute evidence documents. For a step-by-step walkthrough of single-part and multipart uploads, see the [direct file uploads guide](/developer/guides/direct-file-uploads).

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `byte_size` integer — The file's size in bytes. Required when `multipart` is `true`. Multipart uploads support at most 10,000 parts of 5MB each (about 50 GB).
  - `filename` string, required — The name of the file including its extension, e.g. `terms.pdf`.
  - `multipart` boolean — Upload the file in 5MB parts. Required for files larger than 5GB; useful above ~100MB. The file must be larger than 5MB.
  - `visibility` 'public' | 'private' — `public` files are served via an unsigned CDN URL — use for assets anyone may see. `private` files are served via a signed, expiring URL — use for sensitive documents. Defaults to `private`.

## Response `201`

file created with a single-part upload destination

- File
  - `content_type` string, nullable, required — The file's MIME type, e.g. `application/pdf`.
  - `created_at` string, required — When the file was created, as an ISO 8601 timestamp.
  - `filename` string, nullable, required — The original filename, including its extension.
  - `id` string, required — The file's ID, prefixed `file_`.
  - `multipart_chunk_size` integer, nullable — The byte size each part (except the last) must be. Present only on create, and only for multipart uploads.
  - `multipart_upload_id` string, nullable — The ID of the multipart upload, passed back to `complete`. Present only on create, and only for multipart uploads.
  - `multipart_upload_urls` FileMultipartUrl[], nullable
    - `part_number` integer, required — The 1-based index of this part within the multipart upload.
    - `url` string, required — The presigned URL to PUT this part's bytes to.
  - `object` string, required — The type of this object, always `file`.
  - `size` integer, nullable, required — The file size in bytes. `null` until the upload has finished.
  - `upload_headers` object — Headers to send with the upload PUT. Present only on create.
  - `upload_status` 'pending' | 'processing' | 'ready' | 'failed', required — Where the file is in its upload lifecycle.
  - `upload_url` string, nullable — Presigned URL to PUT the file's bytes to. Present only on create, and only for single-part uploads.
  - `url` string, nullable, required — A URL to download the file: a permanent CDN URL for public files, a signed expiring URL for private ones. `null` until the upload has finished.
  - `visibility` 'public' | 'private', required — `public` files are served via an unsigned CDN URL; `private` files via a signed, expiring URL.

## Other responses

- `400` — Invalid Parameters
- `401` — Unauthorized
- `409` — Conflict

## Changes

- **2026-08-24** `e91d507bda45` — 4 breaking, 2 warning, 14 info
  - request property `visibility` was restricted to a list of enum values
  - removed `#/components/schemas/FileVisibility, subschema #2` from the `visibility` request property `oneOf` list
  - the `visibility` request property type/format changed from ``/`` to `string`/``
  - removed the success response with the status `200`
  - …16 more

[Change history](https://skmtc.dev/whop/apis/whop-api/changes/files/post.md)

---

[API](https://skmtc.dev/whop/apis/whop-api.md) · [All operations](https://skmtc.dev/whop/apis/whop-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/whop/whop-api/revisions/9e320991dd2f/schema)
