# Upload file

`POST https://api.tentary.com/v1/files`

Source: https://tentary.com/en/help/api/upload-file/
Area: Products and files
MCP tool: `upload_file`. Changes data at once.

---

Stores a file that buyers get, as content of a product or a lesson: for example a PDF, ZIP, video, audio or image. For images on a sales page, use [`POST /v1/images`](https://tentary.com/en/help/api/upload-image/) or put a URL into `images`.

There are two ways:

1. **Upload with PUT** (preferred, up to 5 GB). Send `file_name` and `size_bytes` without `url`. The answer has an `upload_url`. Send the bytes there with HTTP PUT, for example with curl, then call [`POST /v1/files/{file_id}/finish`](https://tentary.com/en/help/api/finish-upload/).
2. **Copy from a URL** (up to 10 MB). Send `url`, and Tentary copies the file from the public https URL at once. No finish step is needed. Use this only if you cannot send a PUT.

Larger files without PUT: the account owner uploads them in the Tentary app.

Then add the file to a content block of [`PATCH /v1/products/{product_id}`](https://tentary.com/en/help/api/update-product/), [`POST /v1/courses/{course_id}/lessons`](https://tentary.com/en/help/api/create-lesson/) or [`PATCH /v1/lessons/{lesson_id}`](https://tentary.com/en/help/api/update-lesson/), for example `{"type": "video", "file_id": ...}`.

- Block types `image`, `video` and `audio` show the file in a player. Type `file` gives a download, also for a video or an image.
- `kind` in the answer is the block type that fits the file.
- Videos in a video block are converted for streaming. This takes some minutes.

See [File uploads](https://tentary.com/en/help/api/file-uploads/).

## Authorization

`Authorization: Bearer <API key>`

A personal API key (tnt_...). Create it in the Tentary app on the page AI & API.

## Request body

- `url` (string): Public https URL of the file (at most 10 MB). Limits: maxLength 2048.
- `file_name` (string): Name with extension, like "Workbook.pdf". With url: optional (default from the URL). Limits: maxLength 250.
- `size_bytes` (integer): Without url: the exact file size. Limits: min 1, max 5368709120.

## Response

Without url: the upload_url for the PUT. With url: the stored file.

### Variant 1 of 2

- `file_id` (integer): Call finish_upload with it after the PUT.
- `upload_url` (string<uri>): Send the bytes here with HTTP PUT, without extra headers.
- `method` (string): The HTTP method for the upload. Allowed values: `PUT`.
- `expires_in_seconds` (integer): The upload_url works this long.
- `next_step` (string): What to do next (PUT, then finish_upload).

### Variant 2 of 2

- `file_id` (integer): Use it in a content block.
- `name` (string): The name.
- `file_type` (string): File extension, like pdf.
- `kind` (string): The content block type that fits the file. Allowed values: `image`, `video`, `audio`, `file`.
- `size_bytes` (integer): File size in bytes.

## Example request

```bash
curl -X POST "https://api.tentary.com/v1/files" \
  -H "Authorization: Bearer $TENTARY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "file_name": "Workbook.pdf",
  "size_bytes": 2483011
}'
```

## Example response

```json
{
  "file_id": 601,
  "upload_url": "https://tentary-files.s3.eu-central-1.amazonaws.com/files/workbook_4856795675118855267-1793091108.pdf?X-Amz-Expires=1200&X-Amz-Signature=3f9a2c71e0b4",
  "method": "PUT",
  "expires_in_seconds": 1200,
  "next_step": "Send the file bytes with HTTP PUT to upload_url (no extra headers), for example: curl -T <file> \"<upload_url>\". Then call finish_upload with file_id."
}
```
