Получить ключGet a key →

Продавайте наши товары у себяSell our products on your side

FoxyStars API - для тех, кто хочет перепродавать Telegram Stars, Premium и TON на своём сайте, в своём боте или приложении. Заказы оплачиваются с вашего баланса в @FoxyStarsShopBot по тем же ценам, что в боте, а наценку для своих клиентов вы ставите сами.

FoxyStars API is for resellers who want to sell Telegram Stars, Premium and TON on their website, bot or app. Orders are paid from your balance in @FoxyStarsShopBot at the same prices as in the bot, and you set your own markup for your customers.

Базовый адресBase URL: https://api.foxystarsshop.com/v1 ФорматFormat: JSON ВалютаCurrency: RUB

Получить ключGet a key

  1. Откройте @FoxyStarsShopBot и пополните баланс - с него оплачиваются заказы через API.Open @FoxyStarsShopBot and top up your balance - API orders are paid from it.
  2. Перейдите в Профиль → API и нажмите «Получить ключ».Go to Profile → API and tap “Get key”.
  3. Сохраните ключ вида fs_live_… - он показывается один раз. Потеряли - нажмите «Перевыпустить ключ»: старый перестанет работать сразу.Save the key fs_live_… - it is shown only once. Lost it? Tap “Reissue key”: the old one stops working immediately.

АвторизацияAuthentication

Передавайте ключ в заголовке каждого запроса:

Send the key in a header of every request:

Authorization: Bearer fs_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Можно и заголовком X-API-Key: fs_live_…. Без ключа или с неверным ключом - ответ 401 unauthorized.The X-API-Key: fs_live_… header works too. No key or a wrong key returns 401 unauthorized.

Быстрый стартQuick start

Четыре запроса - и первый заказ готов:

Four requests to your first order:

bash
# 1. балансbalance
curl https://api.foxystarsshop.com/v1/balance -H "Authorization: Bearer $KEY"

# 2. цена 100 звёздprice for 100 stars
curl "https://api.foxystarsshop.com/v1/price?product=stars&quantity=100" -H "Authorization: Bearer $KEY"

# 3. заказorder
curl -X POST https://api.foxystarsshop.com/v1/orders -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"custom_id":"order-1001","product":"stars","quantity":100,"recipient":"@durov"}'

# 4. статус заказа (опрашивайте раз в 3-5 секунд)order status (poll every 3-5 seconds)
curl https://api.foxystarsshop.com/v1/orders/123 -H "Authorization: Bearer $KEY"

Формат ответаResponse format

Успех - "ok": true и данные в data. Ошибка - "ok": false и объект error с машинным кодом и понятным описанием.

Success is "ok": true with the payload in data. An error is "ok": false with an error object holding a machine code and a readable message.

json
{ "ok": true,  "data": { "balance": "1250.00", "currency": "RUB" } }

{ "ok": false, "error": { "code": "insufficient_balance", "message": "not enough balance, top it up in the bot", "price": "146.00" } }
Все суммы - строки в рублях с копейками ("146.00"): так не теряется точность. Время - UTC в формате ISO 8601.All amounts are strings in rubles with kopecks ("146.00") so no precision is lost. Times are UTC in ISO 8601.

Заказы и статусыOrders & statuses

Заказ выполняется в фоне: POST /orders сразу отвечает 202 со статусом pending, дальше вы опрашиваете GET /orders/{id}. Обычно заказ выполняется за 10-60 секунд.

Orders run in the background: POST /orders replies 202 with status pending right away, then you poll GET /orders/{id}. An order usually completes in 10-60 seconds.

СтатусStatusЧто значитMeaningДеньгиMoney
pendingПринят, ждёт выполненияAccepted, waitingещё не списаныnot charged yet
processingОтправляем получателюBeing deliveredсписаныcharged
completedВыполнен, товар у получателя. receipt - номер заказа, как в ботеDone, delivered. receipt is the order number, same as in the botсписаныcharged
failedНе выполнен, причина в errorNot done, reason in errorrefunded: true - списывали и вернули на баланс; false - не списывалиrefunded: true - charged and returned to balance; false - never charged
Деньги никогда не «зависают»: если заказ не выполнился по любой причине, включая перезапуск нашего сервера, сумма возвращается на ваш баланс автоматически.Money never gets stuck: if an order fails for any reason, including our server restarting, the amount returns to your balance automatically.

custom_id и повторыcustom_id & retries

custom_id - ваш уникальный номер заказа (1-64 символа, например номер заказа на вашем сайте). Он защищает от двойной оплаты:

custom_id is your unique order id (1-64 characters, e.g. the order number on your website). It protects from double charges:

• Повтор запроса с тем же custom_id и теми же данными вернёт уже созданный заказ с пометкой "idempotent_replay": true - второй раз ничего не спишется.
• Тот же custom_id с другими данными - ошибка 409 custom_id_conflict.
• Оборвалась связь, пришёл таймаут или 5xx? Повторите запрос с тем же custom_id - это безопасно.
• Заказ со статусом failed окончательный: чтобы попробовать снова, создайте заказ с новым custom_id.

• Repeating a request with the same custom_id and the same data returns the existing order with "idempotent_replay": true - nothing is charged twice.
• The same custom_id with different data is a 409 custom_id_conflict.
• Connection dropped, timeout or 5xx? Retry with the same custom_id - it is safe.
• An order with status failed is final: to try again, create an order with a new custom_id.

Необязательный max_price - потолок цены: если цена успела вырасти выше него, заказ не создаётся (409 price_changed, в ответе текущая цена).

Optional max_price is a price ceiling: if the price has risen above it, no order is created (409 price_changed, the current price is in the reply).

ТоварыProducts

productТоварProductquantityrecipient
starsTelegram Starsзвёзд, от 50 до 25 000stars, 50 to 25,000@username в TelegramTelegram @username
premiumTelegram Premiumмесяцев: 3, 6 или 12months: 3, 6 or 12@username в TelegramTelegram @username
tonПополнение TONTON top-upTON, от 1 до 10 000TON, 1 to 10,000@username в TelegramTelegram @username

Получателя можно указать как @durov, durov или t.me/durov. Цены совпадают с ценами бота и меняются вместе с курсом - берите актуальную через GET /price. Другие товары бота появятся в API следующими обновлениями.The recipient can be @durov, durov or t.me/durov. Prices match the bot and follow the exchange rate - get the current one via GET /price. More of the bot's products will come to the API in later updates.

ЛимитыLimits

ЛимитLimitЗначениеValueПри превышенииWhen exceeded
Запросов на ключRequests per key60 в минуту60 per minute429 rate_limited + Retry-After
Незавершённых заказовActive orders5 одновременно5 at a time429 too_many_active_orders
Размер запросаRequest size16 KB413 too_large

ОшибкиErrors

HTTPcodeЧто делатьWhat to do
400bad_requestТело - не JSON-объектBody is not a JSON object
401unauthorizedНет ключа или он неверный/отключёнMissing, wrong or disabled key
402insufficient_balanceПополните баланс в боте (в ответе - нужная сумма)Top up in the bot (the reply includes the price)
403forbiddenДоступ закрыт - напишите в поддержку ботаAccess denied - contact the bot's support
404not_foundНет такого заказа или методаNo such order or endpoint
409custom_id_conflictcustom_id уже занят другим заказомcustom_id is already used by another order
409price_changedЦена выше вашего max_pricePrice is above your max_price
422validation_errorНеверный параметр - подробности в messageInvalid parameter - see message
422invalid_recipientТакого пользователя Telegram нетNo such Telegram user
422recipient_rejectedПолучателю нельзя это купить (например, Premium уже есть)This can't be bought for the recipient (e.g. already has Premium)
429rate_limitedПодождите Retry-After секундWait Retry-After seconds
429too_many_active_ordersДождитесь завершения текущих заказовWait for active orders to finish
503out_of_stockТовар временно закончился - повторите позжеTemporarily out of stock - retry later
503upstream_unavailableПоставщик не ответил - повторите с тем же custom_idSupplier didn't respond - retry with the same custom_id
500internal_errorПовторите позже с тем же custom_idRetry later with the same custom_id

Если заказ уже создан, но не выполнился, причина будет в поле error самого заказа: price_changed, out_of_stock, insufficient_balance, supplier_error, upstream_unavailable, interrupted.

If an order was created but not completed, the reason is in the order's own error field: price_changed, out_of_stock, insufficient_balance, supplier_error, upstream_unavailable, interrupted.

МетодыEndpoints

GET/v1/balance

Баланс вашего аккаунта в боте.

Your account balance in the bot.

200
{ "ok": true, "data": { "balance": "1250.00", "currency": "RUB" } }

GET/v1/products

Список товаров и допустимое количество.

Products and allowed quantities.

200
{ "ok": true, "data": [
  { "product": "stars", "title": "Telegram Stars", "recipient": "Telegram username",
    "quantity": { "min": 50, "max": 25000, "unit": "stars" } },
  { "product": "premium", "title": "Telegram Premium", "recipient": "Telegram username",
    "quantity": { "choices": [3, 6, 12], "unit": "months" } },
  { "product": "ton", "title": "TON top-up", "recipient": "Telegram username",
    "quantity": { "min": 1, "max": 10000, "unit": "TON" } }
] }

GET/v1/price?product=stars&quantity=100

Текущая цена. Параметры: product, quantity.

Current price. Parameters: product, quantity.

200
{ "ok": true, "data": { "product": "stars", "quantity": 100, "unit_price": "1.46", "price": "146.00", "currency": "RUB" } }

POST/v1/orders

Создать заказ. Получатель и цена проверяются сразу - до списания денег.

Create an order. The recipient and price are checked right away - before any money is charged.

ПолеFieldТипTypeОписаниеDescription
custom_idstringобязательноrequiredВаш уникальный номер заказа, 1-64 символаYour unique order id, 1-64 characters
productstringобязательноrequiredstars · premium · ton
quantityintegerобязательноrequiredКоличество (см. «Товары»)Quantity (see Products)
recipientstringобязательноrequired@username получателяRecipient @username
max_pricestringнетoptionalПотолок цены в рубляхPrice ceiling in RUB
request
{ "custom_id": "order-1001", "product": "stars", "quantity": 100, "recipient": "@durov", "max_price": "150.00" }
202
{ "ok": true, "data": {
  "order_id": 123, "custom_id": "order-1001", "product": "stars", "quantity": 100,
  "recipient": "durov", "price": "146.00", "currency": "RUB", "status": "pending",
  "refunded": false, "error": null, "receipt": null,
  "created_at": "2026-09-29T10:00:00Z", "updated_at": "2026-09-29T10:00:00Z" } }

Повтор с тем же custom_id отвечает 200 и "idempotent_replay": true.A retry with the same custom_id replies 200 and "idempotent_replay": true.

GET/v1/orders/{order_id}

Заказ по номеру. Ответ - тот же объект заказа, что выше; готовый заказ выглядит так:

An order by its id. Returns the same order object; a finished order looks like this:

200
{ "ok": true, "data": { "order_id": 123, "status": "completed", "refunded": false, "error": null, "receipt": "37004512", ... } }

GET/v1/orders

Ваши заказы, новые первыми. Параметры: limit (1-100, по умолчанию 20), offset. С параметром custom_id вернёт один заказ по вашему номеру.

Your orders, newest first. Parameters: limit (1-100, default 20), offset. With custom_id it returns a single order by your id.

bash
curl "https://api.foxystarsshop.com/v1/orders?custom_id=order-1001" -H "Authorization: Bearer $KEY"

Примеры кодаCode examples

Заказ с ожиданием результата:

Create an order and wait for the result:

import time, uuid, requests

API = "https://api.foxystarsshop.com/v1"
H = {"Authorization": "Bearer fs_live_..."}

order = requests.post(f"{API}/orders", headers=H, timeout=60, json={
    "custom_id": str(uuid.uuid4()),   # your order number
    "product": "stars", "quantity": 100, "recipient": "@durov",
}).json()
if not order["ok"]:
    raise SystemExit(order["error"])

oid = order["data"]["order_id"]
while True:
    o = requests.get(f"{API}/orders/{oid}", headers=H, timeout=30).json()["data"]
    if o["status"] in ("completed", "failed"):
        break
    time.sleep(4)
print(o["status"], o["error"])

БезопасностьSecurity

Ключ даёт право тратить ваш баланс. Храните его только на своём сервере: не вставляйте в код сайта, который видит браузер, в мобильное приложение или в открытый репозиторий. Если ключ мог утечь - сразу перевыпустите его в боте.The key can spend your balance. Keep it on your server only: never put it in browser-side website code, a mobile app or a public repository. If it may have leaked, reissue it in the bot right away.

Все запросы - только по HTTPS. Вы покупаете у нас по ценам бота и сами назначаете цену своим клиентам.

All requests go over HTTPS only. You buy from us at the bot's prices and set your own prices for your customers.