Media
For Developers

Media

Files are attached to messages in two steps: upload the file and get its id, then pass the ids in media_ids when you post with POST /api/v1/tickets/{id}/messages. No other endpoint takes attachments. An id must be a file of this project, otherwise you get 422. A file already attached to another message is copied: the copy gets a new id, and the earlier message keeps its file.

POST/api/v1/media/upload

Upload a file

A multipart request with a file field. Any file type, up to 200 MB (larger gives 413 MEDIA_TOO_LARGE).

  • mime_type comes from the Content-Type of the file part; without one it’s application/octet-stream
  • width and height are filled for images (image/*, except SVG), otherwise null
  • file_type is the file extension in lower case (png, pdf); with no extension it’s bin
  • url is the relative path for downloading through the API
curl
curl -X POST https://api.support.forestsnet.com/api/v1/media/upload \
  -H "Authorization: Bearer sk_xxx" \
  -F "file=@/path/to/screenshot.png;type=image/png"
201 Created
{
  "id": "m1...",
  "url": "/api/v1/media/m1...",
  "mime_type": "image/png",
  "original_name": "screenshot.png",
  "file_type": "png",
  "width": 1280,
  "height": 720,
  "size": 184523
}
Python SDK
media = client.media.upload("screenshot.png", content_type="image/png")
print(media.id, media.url)

Without content_type the SDK sends application/octet-stream, and the image size isn’t detected.

GET/api/v1/media/{media_id}

Download a file

Serves only files of the key’s project; another project’s id or an unknown id gives 404. If the files are in SupportHub storage, the response is the file itself, with Content-Type from mime_type and Content-Disposition: attachment with the original name. If the file is in the project’s S3 bucket, the response is a 302 to a signed link to the object, valid for an hour, that answers with the same Content-Type and file name; the bucket can be private. Follow it right away (curl -L) rather than storing it.

curl
curl -L -o file.png https://api.support.forestsnet.com/api/v1/media/m1... \
  -H "Authorization: Bearer sk_xxx"

Attaching to a message

Python
import requests

API = "https://api.support.forestsnet.com/api/v1"
HEAD = {"Authorization": "Bearer sk_xxx"}

# 1. Upload the file
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. Post a message with the attachment (the text is required)
requests.post(
    f"{API}/tickets/{ticket_id}/messages",
    headers=HEAD,
    json={"content": "Here is a screenshot of the error", "media_ids": [up["id"]]},
)

A message with an attachment

message
{
  "id": "f1...",
  "ticket_id": "8a3f...",
  "sender_type": "bot",
  "content": "Here is a screenshot of the error",
  "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",
  ...
}
Files in SupportHub storage are kept for the period set in Settings → Media Storage (90 days by default) and then deleted. After that, downloading gives 404.
Was this page helpful?