# Байты файла по подписанной ссылке

`GET https://api.souz.ai/v1/files/{id}/{filename}`

Ссылка из `url` файла; ключ не нужен — подпись и есть авторизация. Работают `HEAD`,
`Range`, `If-None-Match`; `?download=1` отдаёт как вложение. Хост — `media.souz.ai`,
CORS `*`: файл можно встраивать на любые страницы.

## Параметры

| Имя | Где | Обязательно | Тип | Описание |
|---|---|---|---|---|
| `id` | path | да | `string` | Id файла. |
| `filename` | path | да | `string` |  |
| `exp` | query | да | `integer, int64` | До какого момента (unix-секунды) действует ссылка. |
| `sig` | query | да | `string` | Подпись ссылки. |
| `download` | query | нет | `string`; значения: `1` | `1` — отдать как вложение (`Content-Disposition: attachment`). |
| `Range` | header | нет | `string` | Часть файла, `bytes=начало-конец` — ответ `206`. |

## Пример запроса

```bash
curl -X GET 'https://api.souz.ai/v1/files/{id}/{filename}?exp=<exp>&sig=<sig>'
```

```python
import requests

response = requests.get(
    "https://api.souz.ai/v1/files/{id}/{filename}?exp=<exp>&sig=<sig>",
)
print(response.json())
```

```ts
const response = await fetch("https://api.souz.ai/v1/files/{id}/{filename}?exp=<exp>&sig=<sig>", {
  method: "GET",
});
console.log(await response.json());
```

## Ответы

### 200

Байты файла; тип — тот, что в `content_type` файла.

- `application/json`
- `application/octet-stream`
- `audio/mpeg`
- `audio/wav`
- `image/jpeg`
- `image/png`
- `image/webp`
- `video/mp4`
- `video/quicktime`

### 206

Запрошенный `Range`.

- `application/json`
- `application/octet-stream`
- `audio/mpeg`
- `audio/wav`
- `image/jpeg`
- `image/png`
- `image/webp`
- `video/mp4`
- `video/quicktime`

### 304

Не изменилось с прошлого раза: `If-None-Match` совпал с `ETag`.

### 400

Запрос отклонён; `error.detail[]` называет поля и допустимые значения.

- `application/json`, схема `Error`

```json
{
  "error": {
    "code": "capability_mismatch",
    "detail": [
      {
        "allowed": [
          "1:1",
          "16:9",
          "9:16"
        ],
        "path": "aspect_ratio",
        "reason": "unsupported_value"
      }
    ],
    "message": "the model does not support this value",
    "type": "invalid_request_error"
  }
}
```

### 403

Нельзя: у ключа не тот вид (модели запускает API-ключ, аккаунт — ключ управления), у роли участника нет права или подпись ссылки на файл не сходится. `detail[].reason` говорит, что именно: `requires_api_key`, `requires_management_key`, `cabinet_only` (только в кабинете), `insufficient_role` (в `allowed` — роли, которым можно), `not_key_author` (секрет ключа открывает только тот, кто его создал).

- `application/json`, схема `Error`

```json
{
  "error": {
    "code": "forbidden",
    "detail": [
      {
        "reason": "requires_api_key"
      }
    ],
    "message": "this endpoint takes an API key; a management key manages the account only",
    "type": "permission_error"
  }
}
```

### 404

Нет такого объекта у этого аккаунта.

- `application/json`, схема `Error`

### 410

Срок жизни файла вышел, байты удалены.

- `application/json`, схема `Error`

---

Оглавление документации: https://souz.ai/llms.txt. Всё руководство одним файлом: https://souz.ai/llms-full.txt. Справочник методов: https://souz.ai/docs/api-reference.md.
