Buy a ranked ticket
const url = 'https://foxleague.ai/api/shop/ranked-ticket';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"tx_hash":"example","wallet_address":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://foxleague.ai/api/shop/ranked-ticket \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "tx_hash": "example", "wallet_address": "example" }'Records a ranked ticket after you paid for it with shopPay on the game contract, in FOXSY. Tickets are sold only once the competition levels are live (live in the status): pay only after a ranked start answered ranked_ticket_required. The payment must equal the ticket price (price_foxsy of the status) exactly; one payment buys exactly one ticket. A payment the contract refused (a gateway success whose result carries a return message) buys nothing. A short or wrong amount is refunded whole. The answer is the status with the tickets you now hold.
Who: a signed-in player with a team; wallet_address must be the session wallet and the payment must come from it.
Rate limit: at most 10 confirms per session wallet in any 60 seconds by default, counted together with the other paid confirms (POST /api/shop/confirm, POST /api/shop/waive-cooldown, POST /api/shop/medicine); one more is answered HTTP 429 before the payment is read.
Refusals:
Too many purchase confirmations: at most <n> per wallet every <s> seconds. Your payment is kept: confirm the same transaction again in <wait> <unit>.(tx_pending, HTTP 429 with aRetry-Afterheader): this session wallet sent more confirms than its budget allows (10 within 60 seconds by default). The payment was not read: confirm the same hash again after the wait.Wallet mismatch: sign with the correct wallet:wallet_addressis not the session wallet.Ranked games are free until the competition levels start on <time>: no ticket is needed yet.: the competition levels are not live yet, so no ticket is sold (<time>reads like2026-11-09 14:00 UTC). The chain is not read and nothing is recorded: the payment is refunded by the unconfirmed-payment net.Ranked games are free: no ticket is needed yet.: the same while no switch time is set.Not registered: the wallet has no account yet. The payment is kept: confirm again after the registration.Chain is temporarily unavailable. Please retry shortly.(tx_pending): the server cannot read the chain right now.Could not verify transaction yet. Please confirm again in a moment.(tx_pending): the transaction is not final yet.Transaction already processed: this transaction already bought a ticket or another product.This payment was already refunded and cannot be used for a purchase.: this transaction was refunded.Transaction paid <paid> but a ranked ticket costs <price> FOXSY.<refund note>: the amount is not the price; the payment is refunded whole.<paid>reads like150 FOXSY.Failed to record purchase. Your payment is kept: confirm again in a moment.(tx_pending): the ticket could not be written; confirm the same transaction again.
Authorizations
Section titled “Authorizations ”Request Body required
Section titled “Request Body required ”A paid ranked ticket to record.
object
The hash of your shopPay payment of the ticket price (64 hexadecimal characters).
Your wallet; it must be the session wallet and the payer.
Example generated
{ "tx_hash": "example", "wallet_address": "example"}Responses
Section titled “ Responses ”Success or a refusal: read success (the refusals are in the description).
object
A machine-readable reason next to error, set only where the caller must act differently. tx_pending: the payment was not refused but could not be verified yet; keep the transaction hash and confirm again with the same hash, never pay twice.
The answer. Present when success is true.
object
Whether ranked costs a ticket now: the competition levels switch has passed.
When the competition levels govern (RFC 3339, UTC); null while the switch is off.
What one ranked game costs its starter, in whole FOXSY.
The ranked tickets you hold: each pays for one ranked game against a real opponent.
Why the request was refused, in plain words. Present when success is false.
true when the request did what it asked. false is a refusal: read error.
Example
{ "data": { "live": true, "live_from": "2026-11-09T14:00:00Z", "price_foxsy": 100, "tickets": 2 }, "success": true}No valid session. The body is plain text: Missing Authorization header, Invalid Authorization format, Invalid session token or Session expired or invalid. Sign in again.
Example
Session expired or invalidThe body does not match the request schema, for example a tx_hash that is not 64 hexadecimal characters. The body is plain text.
Too many confirms from this session wallet (10 within 60 seconds by default). The answer carries Retry-After and the usual JSON refusal with code: "tx_pending": the payment was not read, so confirm the same hash again after the wait.
object
A machine-readable reason next to error, set only where the caller must act differently. tx_pending: the payment was not refused but could not be verified yet; keep the transaction hash and confirm again with the same hash, never pay twice.
The answer. Present when success is true.
object
Whether ranked costs a ticket now: the competition levels switch has passed.
When the competition levels govern (RFC 3339, UTC); null while the switch is off.
What one ranked game costs its starter, in whole FOXSY.
The ranked tickets you hold: each pays for one ranked game against a real opponent.
Why the request was refused, in plain words. Present when success is false.
true when the request did what it asked. false is a refusal: read error.
Example generated
{ "code": "example", "data": { "live": true, "live_from": "example", "price_foxsy": 1, "tickets": 1 }, "error": "example", "success": true}