Telegram Stars API — MyStars Fulfilment API documentation
Changelog
Every change to the public API, newest first.
- v1.9.0feature
Payment window extended to 1 hour
An order now stays open for payment for 1 hour instead of 15 minutes. The order's expires_at field is unchanged in shape and remains the single source of truth for the deadline — it simply lands further out, giving payers more time. No request or response field changed; if you read expires_at (rather than assuming 15 minutes) nothing in your integration needs to change.
- v1.8.2feature
Order create response echoes what was ordered
POST /v1/orders now returns type plus quantity (for Stars) or months (for Premium) — the field that doesn't apply is null — so the created order is self-describing, just like GET /v1/pricing and the order view. You no longer have to correlate the response back to your request. Purely additive; existing fields are unchanged.
- v1.8.1fix
Clearer docs: request-flow diagram + recipient-check guidance
The reference now leads with the recommended call order (pricing → recipient check → order create) and a request-flow diagram in Quick start. POST /v1/recipients/check explains why type is required and warns that a recipient who already has an active Premium subscription can't be gifted Premium — Telegram blocks it (eligible:false, reason already_subscribed; the order would 422). Docs only — no contract change.
- v1.8.0feature
USDT payments show a processing-fee breakdown
For usdt_ton, GET /v1/pricing and the order-create payment block now include a fee object — subtotal, processing_fee (the 1% swap + 0.5 GRAM/TON gas), total and a description — so you can see exactly what the swap costs. The fee was ALWAYS included in amount; this only itemises it (fee.total equals amount, never adds to it). TON quotes return fee: null. Purely additive.
- v1.7.1feature
Pricing response echoes what it priced
GET /v1/pricing now returns type plus quantity (for Stars) or months (for Premium) — the field that doesn't apply is null — so the amount is self-describing and you no longer have to correlate the quote back to your request. Purely additive; existing fields are unchanged.
- v1.7.0feature
New: list available products
A new GET /v1/products endpoint returns the product catalog — the two product types (stars, premium) and the buyable shape of each (stars: a continuous quantity range 50–1000000; premium: the fixed tiers 3/6/12 months). It's price-free metadata so you can build your own catalog/UI without guessing the bounds; keep using GET /v1/pricing for the price.
- v1.6.1fix
Reversal terminology standardised
The docs now use 'reversal' consistently to match the reversed order status and the reversal_tx field — the section is now 'Reversals & delivery' and adds a 'When a reversal happens' breakdown of the exact cases. No behaviour change: when and how your funds are returned is unchanged.
- v1.6.0feature
Unmatched payments are auto-refunded
A payment that arrives with no order reference (a missing or unrecognised memo) is now returned to the sender minus the network fee. If it can be attributed unambiguously to one of your pending orders, that order ends failed with failure_reason no_memo / wrong_memo and the refund reference in reversal_tx.
- v1.5.0feature
Rate limits documented; probe cap raised to 30/min
The overview now documents the per-minute request budget, the RateLimit-* / Retry-After headers, the daily order cap and the per-recipient guard. The tighter pricing & recipient-check probe cap was raised from 10 to 30 requests/min.
- v1.4.0feature
Pricing response adds quote freshness + USDT/TON rate
GET /v1/pricing now returns quoted_at and valid_until (a re-quote hint) plus usdt_per_ton (the current public USDT/TON rate for your own GRAM↔USDT conversion).
- v1.3.0feature
Terminal failed and expired order-status webhooks now fire
If you set a callback_url, you now also receive the terminal failed and expired webhook events — previously only delivered and reversed were delivered.
- v1.2.0breaking
Pricing response returns amount + currency only
GET /v1/pricing now returns just the final amount and currency. The previous breakdown object has been removed — amount is already the full, all-in total to pay, so no change is needed unless you read breakdown fields.
- v1.1.0feature
Pay in USDT (TON), plus a price breakdown
Orders and quotes now accept payment_currency: usdt_ton alongside ton (GRAM). The pricing response gained a breakdown object (Fragment cost, markup, gas, and DEX fee + swap gas for USDT).
- v1.0.0breaking
recipient is now an object, not a bare string
Create-order and recipient-check requests take recipient: { username } instead of a top-level username string. Update your request bodies before this version — the old shape is rejected with 400 bad_request.