add exact model lookup by telegram document id GET /document/:id…

+ add exact model lookup by telegram document id
GET /document/:id - download the model a document id (or bot api file_unique_id) belongs to, same formats as /model (.tgs, .json, .png, .png?size=128, .svg)
GET /document/:id/info - { documentId, current, gift, giftId, model } where model is the /models/:gift entry

cdn.changes.tg/gifts/documents.json - every known document id mapped to { gift, giftId, model, current }


~ add telegramName, documentId, documentIds fields to models
GET /models/:gift - list of all gift models. add ?sorted to sort by rarity
GET /model/:gift/:model/info - detailed info about a certain gift model
GET /gift/:gift - detailed info about a certain gift

cdn.changes.tg/gifts/models/<gift>/models.json


Model names aren't unique. Some gifts have two different models with the same name, sometimes even with the same rarity: Santa Hat has two Rave, Cookie Heart two Strawberry, Jelly Bunny two Violet Joy and Genie Lamp two Lava Lamp. We keep both and add a -1 suffix to the second one (Rave-1). Telegram itself never uses that suffix, so a name alone can't always tell you which model an NFT has.

Telegram identifies a model by the document ID of its animation, so that's now the exact key:
- MTProto: starGiftAttributeModel.document.id on the NFT → /document/<id>;
- Bot API: UniqueGift.model.sticker.file_unique_id → /document/<file_unique_id> (pass it as is, we will decode the document ID from the file_unique_id automatically);
- only a name and a rarity (e.g. t.me/nft/<slug> shows "Rave 0.2%"): match telegramName and rarity in /models/:gift. This is exact unless both models share a rarity.

telegramName is the name Telegram shows (e.g. "Rave" for both Rave and Rave-1). Don't get it by removing the suffix from name, because some real names end in a number (e.g. Sputnik-1). documentId is the model's current document. documentIds lists every document the model has had: when Telegram redraws a model, it gives it a new document and moves every existing NFT over, but the old id still resolves to the same model.

If anything looks off, or doesn't work as you expected, please tell us in the comments. Thanks!
❤5
November 2, 2026 424