Media and getFile
Bots send files with sendPhoto, sendVideo and sendDocument, and download files they receive with getFile. Files go through the same pipeline as people's: location data and camera details are stripped from pictures.
Sending a file#
Upload the file with multipart/form-data under the method's own field name, or reuse a file_id your bot received or sent:
curl -s https://bots.qivuna.com/v1/sendPhoto \
-H "Authorization: Bot $QIVUNA_BOT_TOKEN" \
-F chat_id=-4503600130020245 \
-F photo=@chart.png \
-F caption="Weekly results"
{"chat_id": -4503600130020245, "photo": "3f9c0a7e4b1d2c5e6f708192a3b4c5d6e7f80912"}
| Method | Field | Accepted |
|---|---|---|
sendPhoto | photo | JPEG, PNG, WebP; HEIC/HEIF is converted to JPEG. At most 8,000 pixels a side and 25 megapixels. |
sendVideo | video | MP4, MOV, WebM, 3GP. |
sendDocument | document | The file types people can send in chats. |
- One file per message, at most 20 MB (413
payload_too_large). The other form fields together stay under 1 MB. - The type is decided from the file's bytes, not its name or the declared type. A file that does not fit the method answers
400 bad_requestnaming the field. File names have direction and invisible characters removed, and pass the content rules. captionup to 1,024 characters, withcaption_entities(orentities) orparse_mode: "HTML".reply_markup,reply_to_message_id,disable_notificationandprotect_contentwork as insendMessage.- A
file_idsent again is copied: the new message has its own file, and it counts toward the daily upload volume again. An unknownfile_idanswers400 bad_request. - Only these three methods take files; a file sent to any other method answers 413.
Where media can go#
- Groups: the grant needs
can_send_media(andcan_sendfor a caption), and the group must allow members to send media. - Channels:
can_postandcan_send_media. - 1:1 chats with plain bots: as
sendMessage(started, not stopped, unsolicited cap). - Not in encrypted bots' private chats (
403 e2ee_required) or encrypted groups (403 e2ee_unsupported): files are not part of encrypted bot messages in v1.
Every refusal happens before anything is stored or counted.
Upload limits#
| Tier | new | standard | verified |
|---|---|---|---|
| Upload volume per UTC day | 200 MB | 1 GB | 5 GB |
Past the volume, 429 rate_limited with retry_after until the next UTC midnight. Pictures are decoded one at a time per bot, in a pool shared by bots; when it is busy you get 429 with a short retry_after — retry then.
Files your bot receives#
A message with files carries the first one as photo, video or document (by its stored type) — a single File, not a list of sizes — and its text as caption. People can send up to 10 files in one message; then attachments lists all of them in order, each as {type, …File}.
"photo": {"file_id": "3f9c0a7e4b1d2c5e6f708192a3b4c5d6e7f80912",
"file_unique_id": "Qm7bX0k2_Lr9TzP1",
"file_size": 248113, "mime_type": "image/jpeg", "file_name": "IMG_2041.jpg"}
End-to-end encrypted files are never presented to bots.
Downloading with getFile#
curl -s "https://bots.qivuna.com/v1/getFile?file_id=3f9c0a7e4b1d2c5e6f708192a3b4c5d6e7f80912" \
-H "Authorization: Bot $QIVUNA_BOT_TOKEN"
# → {"ok":true,"result":{"file_id":"3f9c…","file_unique_id":"Qm7b…","file_size":248113,
# "mime_type":"image/jpeg","file_name":"IMG_2041.jpg","file_path":"<43 characters>"}}
curl -s -o photo.jpg "https://bots.qivuna.com/v1/file/<file_path>" \
-H "Authorization: Bot $QIVUNA_BOT_TOKEN"
- The download needs the same bot's
Authorizationheader; the link alone opens nothing, and it lasts 1 hour. - Each download is checked again: the message still exists and is not deleted or expired, and your bot is still in that room (or a party to that 1:1 chat). Otherwise
404 file_not_found. - A
file_idis valid for your bot only, for at most 30 days.file_unique_idstays the same for the same file across the bots of your id namespace and cannot be linked across developers. - Downloads are served with
Cache-Control: private, no-store. Store what you need yourself, and delete it when you no longer need it.