Медиа
Файлы прикрепляются к сообщениям в два шага: сначала загружаете файл и получаете его id, затем передаёте список id в media_ids при отправке через POST /api/v1/tickets/{id}/messages. Другие эндпоинты вложений не принимают. Id должен быть файлом этого проекта, иначе 422. Файл, уже прикреплённый к другому сообщению, копируется: у копии новый id, а прежнее сообщение файл не теряет.
/api/v1/media/uploadЗагрузить файл
Multipart-запрос с полем file. Тип файла не ограничен, размер — до 200 МБ (больше — 413 MEDIA_TOO_LARGE).
mime_typeберётся из Content-Type частиfile; если его нет —application/octet-streamwidthиheightзаполняются для изображений (image/*, кроме SVG), иначеnullfile_type— расширение файла в нижнем регистре (png,pdf); без расширения —binurl— относительный путь для скачивания через API
curl -X POST https://api.support.forestsnet.com/api/v1/media/upload \
-H "Authorization: Bearer sk_xxx" \
-F "file=@/путь/к/screenshot.png;type=image/png"{
"id": "m1...",
"url": "/api/v1/media/m1...",
"mime_type": "image/png",
"original_name": "screenshot.png",
"file_type": "png",
"width": 1280,
"height": 720,
"size": 184523
}media = client.media.upload("screenshot.png", content_type="image/png")
print(media.id, media.url)Без content_type SDK отправляет application/octet-stream, и размеры картинки не определяются.
/api/v1/media/{media_id}Скачать файл
Отдаёт только файлы проекта, к которому относится ключ; чужой или несуществующий id — 404. Если файлы лежат в хранилище SupportHub, ответ — сам файл с Content-Type из mime_type и Content-Disposition: attachment с исходным именем. Если файл лежит в S3-бакете проекта, ответ — 302 на подписанную ссылку на объект, которая действует час и отдаёт тот же Content-Type и имя файла; бакет может быть приватным. Переходите по ссылке сразу (curl -L), не сохраняйте её.
curl -L -o file.png https://api.support.forestsnet.com/api/v1/media/m1... \
-H "Authorization: Bearer sk_xxx"Прикрепление к сообщению
import requests
API = "https://api.support.forestsnet.com/api/v1"
HEAD = {"Authorization": "Bearer sk_xxx"}
# 1. Загружаем файл
with open("screenshot.png", "rb") as fh:
up = requests.post(
f"{API}/media/upload",
headers=HEAD,
files={"file": ("screenshot.png", fh, "image/png")},
).json()
# 2. Отправляем сообщение с вложением (текст обязателен)
requests.post(
f"{API}/tickets/{ticket_id}/messages",
headers=HEAD,
json={"content": "Вот скриншот ошибки", "media_ids": [up["id"]]},
)Сообщение с вложением
{
"id": "f1...",
"ticket_id": "8a3f...",
"sender_type": "bot",
"content": "Вот скриншот ошибки",
"is_internal": false,
"media": [
{
"id": "m1...",
"url": "/api/v1/media/m1...",
"mime_type": "image/png",
"original_name": "screenshot.png",
"file_type": "png",
"width": 1280,
"height": 720,
"size": 184523
}
],
"created_at": "2026-04-07T09:00:00",
...
}
