# Files

> Upload videos, images and PDFs.

Source: https://www.onlucra.com/docs/api-files

Upload a file by sending its bytes with a `purpose`, and use the file ID it returns, like a submission's `file` or an account's `profilePicture`.

## Upload

Send the raw bytes as the request body. `purpose` and `name` go in the query:

```bash
curl -X POST "https://api.onlucra.com/v1/files?purpose=product_image&name=hero.jpg" \
  -H "Authorization: Bearer $LUCRA_API_KEY" \
  -H "Lucra-Version: 2026-10-01" \
  --data-binary @hero.jpg
```

With the SDK, pass a `Blob` or `File` as the body:

```ts
import { readFile } from "node:fs/promises"

const { data: file } = await lucra.files.create({
  query: { purpose: "product_image", name: "hero.jpg" },
  body: new Blob([await readFile("hero.jpg")]),
})
```

Upload as the account that will use the file. A creator's video is uploaded acting as the creator (`Lucra-Account: crtr_…`).

## Purposes

| `purpose`                 | What                                   |
| ------------------------- | -------------------------------------- |
| `submission`              | A creator's video for a program        |
| `ad_creative`             | A brand's own video for its library    |
| `product_image`           | A product image                        |
| `profile_picture`         | A logo or profile photo                |
| `program_brief`           | A PDF brief                            |
| `program_reference_video` | An example video for creators          |
| `agreement`               | A PDF agreement                        |
| `chat_attachment`         | A file attached to a message           |

## Large files

For a large video, reserve the upload instead: send `size` and `contentType` (and optionally `checksum`, its SHA-256) with an empty body. The response's `upload` says where to `PUT` the bytes. Then finish with `PATCH /v1/files/:id` and `{ "status": "processing" }`.

## Processing

Images are ready at once. Videos stay `processing` while Lucra checks and prepares them; poll `GET /v1/files/:id`, or wait for the `file.ready` [webhook](https://www.onlucra.com/docs/webhooks). A submission's video, or a program's example video, can be used while it's still `processing`: it shows once processing finishes. Using any other file before it's `ready` returns `409 file_processing`.

## Endpoints

- `POST /v1/files` (write, SDK `lucra.files.create`): Upload a file
- `GET /v1/files` (read, SDK `lucra.files.list`): List files
- `GET /v1/files/:id` (read, SDK `lucra.files.retrieve`): Get a file
- `PATCH /v1/files/:id` (write, SDK `lucra.files.update`): Finish or delete an upload
