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

# Create file

`POST /files`

## Request

- Base URL: `https://api.crevio.co/v1`
- URL: `https://api.crevio.co/v1/files`
- Auth: API key in header `Authorization`

Create a file. The endpoint discriminates between three intents based on which fields you send:

**1. Presigned upload — `{ "filename": "photo.png" }`**
Returns an `upload_url` and `upload_headers`. PUT your bytes to that URL, then call `POST /v1/files/{id}/uploaded` to transition the file from `pending` to `ready`.

**2. Server-side URL import — `{ "url": "https://..." }`**
Crevio downloads the bytes for you. Returns immediately with `upload_status: "processing"`. The status flips to `ready` (or `failed`) once the background download completes; poll `GET /v1/files/{id}` to check.

**3. External video embed — `{ "kind": "external_video", "url": "https://youtube.com/..." }`**
Pins a YouTube, Vimeo, or Wistia URL as an embeddable reference. No bytes are stored; status returns as `ready` immediately. Non-embed URLs are rejected with 422.

## Headers

- `Idempotency-Key` string

## Request body

- FileRequest
  - `kind` 'file' | 'external_video' | 'null', nullable: Defaults to 'file'. Set to 'external_video' to pin a YouTube, Vimeo, or Wistia URL as an embed.
  - `url` string, nullable: Required when kind=external_video, or for server-side URL imports of files.
  - `filename` string, nullable: Required for presigned uploads. Optional for URL imports.

## Response `201`

File created

- FileCreateResponse
  - `object` string, required
  - `id` string, required
  - `kind` 'file' | 'external_video', required
  - `upload_status` 'pending' | 'processing' | 'ready' | 'failed', required
  - `source` 'upload' | 'url_import' | 'external_video' | 'generation', required
  - `title` string, nullable, required
  - `description` string, nullable, required
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `url` string, nullable, required
  - `tags` string[], nullable, required
  - `source_job_id` string, nullable, required
  - `filename` string, nullable, required
  - `content_type` string, nullable, required
  - `size` integer, nullable, required
  - `provider` string, nullable, required
  - `file_url` string, nullable, required
  - `upload_url` string, nullable
  - `upload_headers` object, nullable

## Other responses

- `400`: Bad request
- `401`: Authentication required
- `403`: Forbidden
- `422`: Validation error
- `429`: Rate limit exceeded — 600 requests per minute per credential. Retry after the number of seconds in `Retry-After`.
- `500`: Internal server error

---

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