English
Get Media
GET/media/{telegramId}/{chatId}/{messageId}/{variant}/{signature}.{ext}Telegram media has no public URL. So whenever Zate gives you an image, video, sticker, document, or profile photo, whether from Get Channel Messages or the webhook, it comes as a link to this endpoint.
You never need to build the link yourself. Just use the url or thumbnail Zate gives you as is.
Endpoint Details
- Base URL:
https://api-zate.azickri.com - Headers: none, the link is already signed
- Streaming: supports the
Rangeheader, so videos play right away and can be seeked
Parameters
Every part of the path is filled in by Zate. This table is just for the curious.
| Parameter | In | Description |
|---|---|---|
telegramId | path | The Zate session id that has access to the media. |
chatId | path | ID of the chat the media lives in, like -1001234567890. |
messageId | path | Message ID. For profile photos, it holds the photo ID. |
variant | path | photo (largest image size), thumb (thumbnail), file (video, sticker, or document), or profile (small profile photo). |
signature | path | Signature that makes the link impossible to guess or alter. |
ext | path | File extension, like jpg, mp4, or webp. |
Range | header | Optional. For example bytes=0-1048575 for the first 1 MB. |
Usage Examples
html
<!-- Images and thumbnails -->
<img src="https://api-zate.azickri.com/media/68b3f0a2c1d4e5f6a7b8c9d0/-1001234567890/181/photo/Xk3d9QmPz0aB1cD2eF3gH4.jpg" alt="" />
<!-- Video, seekable right away -->
<video
controls
poster="https://api-zate.azickri.com/media/68b3f0a2c1d4e5f6a7b8c9d0/-1001234567890/180/thumb/Gh9iJk0lMn1oPq2rSt3uVw.jpg"
src="https://api-zate.azickri.com/media/68b3f0a2c1d4e5f6a7b8c9d0/-1001234567890/180/file/Pq4rSt5uVw6xYz7aBc8dEf.mp4"
></video>bash
# Download the whole file
curl -o image.jpg "https://api-zate.azickri.com/media/68b3f0a2c1d4e5f6a7b8c9d0/-1001234567890/181/photo/Xk3d9QmPz0aB1cD2eF3gH4.jpg"
# Just the first 1 MB
curl -r 0-1048575 -o part.mp4 "https://api-zate.azickri.com/media/68b3f0a2c1d4e5f6a7b8c9d0/-1001234567890/180/file/Pq4rSt5uVw6xYz7aBc8dEf.mp4"javascript
const url = 'https://api-zate.azickri.com/media/68b3f0a2c1d4e5f6a7b8c9d0/-1001234567890/181/photo/Xk3d9QmPz0aB1cD2eF3gH4.jpg';
const response = await fetch(url);
if (response.status === 503) {
const wait = Number(response.headers.get('Retry-After'));
console.log(`Telegram asks to wait ${wait} seconds`);
}
const buffer = Buffer.from(await response.arrayBuffer());Response
On success the body is the file itself, not JSON:
| Status | When |
|---|---|
200 | The whole file, for a request without Range. |
206 | Part of the file, matching the Range you asked for. Comes with a Content-Range header. |
| Response header | Description |
|---|---|
Content-Type | File type, like image/jpeg or video/mp4. |
Content-Length | Size of the part being sent, in bytes. |
Accept-Ranges | Always bytes. |
Cache-Control | public, max-age=86400, so browsers may keep it for up to a day. |
On failure, the error has the same shape as every other endpoint:
json
// The link was tampered with
{
"statusCode": 400,
"message": "telegramId must be a mongodb id"
}json
// Signature doesn't match, or the message was deleted
{
"statusCode": 404,
"message": "media not found"
}json
// Range outside the file size
{
"statusCode": 416,
"message": "range not satisfiable"
}json
// The session that owns the link isn't connected
{
"statusCode": 500,
"message": "session not connected"
}json
// Comes with a Retry-After header
{
"statusCode": 503,
"message": "telegram asked to wait 120s"
}How It Works
- Never downloaded whole. Zate fetches the file from Telegram in 512 KB chunks, only when the viewer actually reaches that part. A 2 GB video only "costs" the part that's watched, and closing or seeking the video stops the fetching right away.
- Fetched chunks are cached for 1 hour after they were last opened. Replaying or seeking back doesn't go to Telegram again.
- The session must be connected, unless every requested chunk is still in the cache.
- Image sizes:
photois the largest size (up to 2560 pixels), an imagethumbis about 800 pixels, and a videothumbis 320 pixels, the size Telegram keeps. - A new profile photo = a new link, so browsers never show the old photo from their cache.
These links are public
Anyone holding the link can open the media without headers, including media from private channels. Treat links to private channel media as sensitive and don't put them on public pages.