api.changes.tg/
1.36K subscribers
4 photos
8 links
@GiftChanges API that is available to everyone!
Download Telegram
+ add /dates
GET /dates - release and upgrade-enabled dates for every gift, unix seconds (UTC), oldest release first

~ add releasedAt, releasedAtSource, upgradableAt, upgradableAtSource, upgradable fields
GET /gift/:gift - detailed info about a certain gift


Added gift release dates, along with the dates on which upgrades got released for the specified gifts.
NOTE: some gifts (especially the first unlimited ones) have their release dates set to arbitrary Oct 5, 2024, 9:00 AM UTC+0.
❤3💘1
~ add crafted, rarityTier fields
GET /models/:gift - list of all gift models. add ?sorted to sort by rarity


If a gift has some models that are crafted-only (such as Desk Calendar's), those models now show crafted: true and their crafted rarity in rarityTier.
🔥2
~ add rarity and rarityPermille to every model, backdrop and symbol
GET /models/:gift - list of all gift models. add ?sorted to sort by rarity
GET /backdrops/:gift - list of all gift backdrops. add ?sorted to sort by rarity
GET /symbols/:gift - list of all gift symbols. add ?sorted to sort by rarity
GET /gift/:gift - detailed info about a certain gift
GET /emoji/:gift - get customEmojiId mapping for a specific gift

(+ all of the /info routes)

~ add backdropId, customEmojiId fields
GET /backdrops/:gift - list of all gift backdrops. add ?sorted to sort by rarity
GET /backdrop/:gift/:backdrop/info - detailed info about a certain gift backdrop


~ return full models, backdrops and symbols
GET /gift/:gift - detailed info about a certain gift


~ fix model emojis
GET /emoji/:gift - get customEmojiId mapping for a specific gift


~ fix similar symbol names
GET /symbol/:gift/:symbol - download this gift pattern


~ errors are now JSON
GET * - { error, message, statusCode }


Rarity used to come as rarityPermille on some routes and as a percentage in rarity on others. Now every model, backdrop and symbol has both, everywhere. Crafted models are now sorted by tier (legendary → epic → rare → uncommon) and still go first. Models with the same rarity are now ordered by name.

/gift/:gift now returns the same entries as /models, /backdrops and /symbols. Backdrops now always include backdropId and customEmojiId.

/emoji/:gift had outdated rarities for some gifts (Desk Calendar, Jingle Bells, Big Year, etc.). They now match /models. Every model is listed now, even if it has no emoji (customEmojiId: null). Cookie Heart's Strawberry/Strawberry-1 and Santa Hat's Rave-1 had the wrong emoji, which is fixed now.

Symbols like Sea Horse and Seahorse used to resolve to the same symbol. Both work properly now. Some symbol lists also contained leftover raw Telegram document data, which is removed.

Errors used to be plain text and are now JSON. Status codes and messages are the same, but if you read the error body as text, you might want to update your code.

If anything looks off, please tell us in the comments. Thanks!
❤6👍2🔥1
~ add SVG generation for gift models (including originals)
GET /model/:gift/:model.svg - download the first frame of this gift model as an svg
GET /original/:id.svg - download the first frame of this gift as an svg
👍3❤2
+ add everything related to crafts
GET /crafts - gifts that are craftable right now or have crafted models, with every crafted model (tier, customEmojiId) and the crafted emoji/sticker set links


+ add everything related to auctions
GET /auctions - every gift auction with recorded rounds: dates, rounds, gifts per round, gifts sold, stars spent, average price paid, finished flag. newest first
GET /auction/:gift/rounds - round-by-round history of a gift auction (gift name, auction slug or id): round times, gifts sold, min bid, clearing price, top bid, winning bids sum, bid levels, gifts left
❤2👍1
~ add original rarities to models if we have data on them
GET /models/:gift - list of all gift models. add ?sorted to sort by rarity
GET /backdrops/:gift - list of all gift backdrops. add ?sorted to sort by rarity
GET /symbols/:gift - list of all gift symbols. add ?sorted to sort by rarity
GET /gift/:gift - detailed info about a certain gift
GET /emoji/:gift - get customEmojiId mapping for a specific gift


Due to how Resistance Dog's rarity works, the methods listed above were updated and now contain such fields as originalRarity and originalRarityPermille if our API has data on them.
API and CDN websites might be down for a minute or two. Hosting provider went maintenance due to them patching virtualization nodes for CVE-2026-99999. We will post an update when the maintenance ends.
+ 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
+ add batch lookup
GET /documents?ids=a,b,c - the same as /document/:id/info for up to 100 ids at once, keyed by each id (null if unknown)


+ add an openapi spec
GET /openapi.json - OpenAPI 3.1 spec of every endpoint


~ add telegramName, documentId, documentIds fields
GET /emoji/:gift - get customEmojiId mapping for a specific gift
❤3
+ add a feed of everything that changes in our data (beta, might be removed or might work incorrectly)
GET /changes - changes to models, symbols and backdrops, plus new gifts, upgrades and crafts (once their files are rendered), oldest first
/changes?since=<id or unix ms> - only what came after an event id (or from a moment); pass the returned next to keep polling
/changes?types=model.redrawn,model.renamed&gift=myth-mask&limit=500 - filter by type and gift (limit 1-1000, default 100)


What goes into the feed:
- gift.added — a new gift was released;
- gift.upgrades_added — a gift got upgrades;
- crafts.added — new crafted models (with tiers and document ids);
- model.added, model.renamed, model.redrawn, model.reclassified;
- model.tier_changed, model.rarity_changed;
- symbol.added, symbol.rarity_changed, backdrop.rarity_changed.

An event only appears once we're fully done with it: new gifts after their files are rendered, new upgrades after every model is dumped and rendered (tgs, lottie, png, svg), crafts after the crafted models are rendered. So anything in the feed is already available from the api and the cdn.

Every event has id, type, gift, giftId and at, plus its own fields. For example, model.redrawn has the new and previous documentId and the new customEmojiId. The full list is in /llm and /openapi.json.
❤3