Since November 2025, new limited Telegram gifts are released through auctions instead of a fixed-price sale. Bids are paid in Stars, carry over between rounds and are refunded when the auction ends. If you build a client, a gift tracker or a bot that deals with Stars, this changes what you show users and when their Stars come back. This post walks through the auction docs and the related client configuration values.
Spotting an auction gift
An auctioned gift is a starGift with the auction flag set, plus auction_slug, gifts_per_round and auction_start_date. The docs are strict about it: such a gift "is auction-only: it must not be bought through the normal gift sending flow". The slug builds a t.me/auction/<slug> deep link.
Reading the state
-
payments.getStarGiftAuctionState(auction, version)returns the gift, the auction state and the current user's state, and subscribes the client toupdateStarGiftAuctionStatefortimeoutseconds. Call it again aftertimeoutto keep receiving updates. -
payments.getStarGiftActiveAuctions(hash)returns every unfinished auction the user has bid on, including ones where the bid was returned. Clients use it at startup to show an auction badge. - Apply a
starGiftAuctionStateonly if itsversionis bigger than the cached one: the server "may sometimes return slightly outdated cached versions". AstarGiftAuctionStateFinishedhas no version and replaces any cached state.
Rounds
The auction has total_rounds rounds. Each round gives gifts_per_round gifts to the top bidders of that round, so the total supply is gifts_per_round * total_rounds. rounds describes them compactly: each StarGiftAuctionRound covers rounds from its num up to the next entry's num - 1. An extendable round (starGiftAuctionRoundExtendable) has extend_top and extend_window: a change in the top extend_top positions prolongs the round by extend_window seconds, so a late bid near the top extends the round instead of closing it.
gifts_left is the live count of gifts still to distribute. It overrides starGift.availability_remains, which lags behind because updates do not refresh it.
Bids
A bid is a normal Stars payment: payments.getPaymentForm with inputInvoiceStarGiftAuctionBid (peer, gift_id, bid_amount, optional message and hide_name; update_bid to raise an existing bid). Things that matter for UX:
- A bid "cannot be retracted". The only outcomes are a win, a higher bid, or a refund when the user loses everything and the auction finishes.
- A bid outside the top
Nof a round carries over to the next round automatically. -
starGiftAuctionUserState.min_bid_amount, when present, overrides the auction-widemin_bid_amountfor this user. -
returnedmeans the bid fell so far behind that it can never win, even if nobody bids again. It was removed and refunded; to take part again the user has to place a new bid. - Bids appear in the Stars transaction history with the
stargift_auction_bidflag.
Estimating the user's position
bid_levels holds exact positions for the first 100 places and coarser checkpoints after that (100, 200 … 1,000, 2,000 … gifts_left). Equal amounts rank by time: the earlier bid is higher. The documented algorithm, as code:
def auction_position(state, user_state, my_id):
if my_id in state.top_bidders:
return state.top_bidders.index(my_id) + 1
for level in state.bid_levels: # ascending by position
if (level.amount == user_state.bid_amount and level.date >= user_state.bid_date) \
or level.amount < user_state.bid_amount:
return level.pos
return state.bid_levels[-1].pos + 1
def expected_gift_number(state, position):
return state.last_gift_num + position
Positions from coarse checkpoints are approximate, so round the displayed number accordingly.
Winning, and what you cannot do afterwards
Won gifts arrive as messageActionStarGift with auction_acquired set; gift_num is the collectible number. payments.getStarGiftAuctionAcquiredGifts lists everything the user won, with bid amount, round and position.
Two limits to surface in the UI:
- "Gifts acquired through collectible gift auction cannot be converted back into Telegram Stars."
- After the auction,
starGiftAuctionStateFinishedgivesaverage_price, and optionallylisted_count(on resale in Telegram, fetch withpayments.getResaleStarGifts) andfragment_listed_countwithfragment_listed_url.
Resale economics from the client config
If a user resells the gift, the seller receives price * permille / 1000. The documented config example has:
| Key | Value | Meaning |
|---|---|---|
stars_stargift_resale_commission_permille |
800 | seller gets 80% of a price in Stars |
ton_stargift_resale_commission_permille |
900 | seller gets 90% of a price in GRAM (nanograms) |
stars_stargift_resale_amount_min |
125 | minimum resale price in Stars |
stars_stargift_resale_amount_max |
100000 | maximum resale price in Stars |
Read these from help.getAppConfig at runtime instead of hardcoding them: they are configuration, not protocol constants.
What this means for Stars flows
Auctions move Stars in bursts. Users top up before a release, Stars stay locked while bids are in play, and losing bids land back on balances in one wave when the auction ends. Resales paid in Stars add more. If your bot accepts Stars, expect payment spikes after big auctions, and remember that Stars paid to a bot follow the usual availability rules in the Bot Platform Developer Terms.
Checklist
- [ ] treat
starGift.auctiongifts as bid-only, never send them through the normal gift flow - [ ] apply auction states by
version; applystarGiftAuctionStateFinishedunconditionally - [ ] show the bid as locked until a win, a refund or
returned - [ ] estimate position from
bid_levelsand label approximate positions - [ ] tell users that auction gifts cannot be converted back into Stars
- [ ] read resale commission and limits from the app config
Disclosure: we build StarGate, a Telegram bot and web app that swaps Stars for GRAM, USDT, ETH and BTC. This post was drafted by an AI assistant from the Telegram documentation linked above, and every quote was checked against those pages.
Top comments (0)