Zapnoty — Files — sharing attachments

API Documentation

REST API for notifications via Telegram and Max. Subscribers, OTP, broadcasts, forms, helpdesk.

Files — sharing attachments

Photos, video and documents in tickets and agent conversations. Uploading, sending attachments, search by description, storage quota.

How it works

A customer sends a photo or document to the bot — the file lands in storage and is attached to the ticket message or agent conversation. The same works in reverse: operators and agents attach files to a reply and the person receives them in the same messenger they wrote from. Everything uploaded gathers in the cabinet’s Files section — with search, descriptions and reuse: the same price list never needs uploading twice.

What you can upload

Images 10 MB

jpeg, png, webp, gif

Video 50 MB

mp4, mov, webm

Documents 20 MB

pdf, docx, xlsx, pptx, txt, csv, json, xml, zip

The type is detected from the file contents, not the extension: a renamed executable will not pass. Anything outside the list is rejected. A single customer can send at most 25 files and 50 MB per day — this protects your space from being filled from outside.

Space

The quota is per account rather than per project and depends on the plan: 100 MB on Free, 300 MB on Lite, 700 MB on Basic, 1.5 GB on Standard and more on higher plans. Identical files take up space once. Star what matters and auto-cleanup will skip it.

Endpoints

POST /v1/agent/media — upload a file (multipart)
GET /v1/agent/media/{id} — download: 302 to a temporary link
GET /v1/agent/files — find a file by name or description
POST /v1/agent/say — send a message with attachments
POST /v1/helpdesk/tickets/{id}/reply — ticket reply with attachments

1. Uploading a file

A file is uploaded in a separate request and receives an identifier. Sending the message is the second step: the agent can prepare an attachment in advance, and a failed upload does not lose the text.

POST /v1/agent/media
Authorization: Bearer agtk_...
Content-Type: multipart/form-data
file=@report.pdf
{
"id": "med_7hQ2mzT1kR",
"kind": "file",
"mime": "application/pdf",
"name": "report.pdf",
"size_bytes": 284133,
"uploaded_by": "agent",
"created_at": "2026-08-15T09:12:44Z"
}

2. Sending with an attachment

The attachments field lists file identifiers — up to 10 per message. The files must belong to the same project as the key.

POST /v1/agent/say
Authorization: Bearer agtk_...
{
"text": "The July report is ready",
"attachments": ["med_7hQ2mzT1kR"]
}

3. Finding an existing file

Files you uploaded in the cabinet are available to the agent of the same project. Add a description in the file details — that is what the agent searches by, instead of uploading a copy.

GET /v1/agent/files?query=contract
Authorization: Bearer agtk_...
{
"files": [
{
"id": "med_3nB8xwQ5tE",
"kind": "file",
"name": "contract-template.docx",
"description": "Services contract template",
"size_bytes": 48211
}
]
}
GET /v1/agent/media/med_3nB8xwQ5tE
Authorization: Bearer agtk_...
302 Found
Location: https://s3.twcstorage.ru/...

The link is temporary and lives for 10 minutes. Files have no permanent public addresses — storage is private and every request checks permissions.

4. Ticket reply with a file

POST /v1/helpdesk/tickets/{id}/reply
Authorization: Bearer zn_live_...
{
"text": "Instructions attached",
"attachments": ["med_7hQ2mzT1kR"]
}

5. A file in a broadcast

An attachment on any message is set either by a link (url) or by a storage file (media_id) — never both. For a storage file the address is issued at send time, so the attachment never goes stale in a scheduled or recurring broadcast, however long it waits.

POST /v1/broadcast
Authorization: Bearer zn_live_...
{
"text": "September price list attached",
"media": { "media_type": "file", "media_id": "med_3nB8xwQ5tE" },
"tags_any": ["clients"]
}

Related sections