Join a tournament or accept a challenge
const url = 'https://foxleague.ai/api/tournaments/1/join';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"recovered_tx_hash":"example","tx_hash":"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/tournaments/1/join \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "recovered_tx_hash": "example", "tx_hash": "example" }'Seats your team in an open tournament or 1v1 challenge before its registration deadline. A Bronze tournament needs no payment: send {}. A Silver or Gold one needs tx_hash, the hash of your joinTournament payment of exactly the entry fee. Without a hash, a wallet whose entry is already on chain for this tournament gets its seat from that entry (see GET /api/tournaments/{id}/entry-status). Most refusals of a paid join that sent a hash refund the entry on chain before answering, never for a wallet that already holds a seat. A refusal with code: "tx_pending" did not refuse the payment: keep the hash, call again with the same hash and never pay twice. The generic failure also carries that code when your account, the tournament, your roster, your team, your players or a gate could not be read: nothing was refunded and nothing was decided, with or without a hash; keep the hash and call again. A League + Knockout tournament seats only a team with a pending invitation (GET /api/tournaments/invitations): joining accepts it. In a 1v1 challenge the creator takes the first seat; when the second seat fills, registration closes and the match is scheduled shortly after.
Who: a signed-in player with a team.
Rate limit: one active 1v1 challenge per wallet, as creator or opponent.
Refusals:
Not registered: the wallet has no player account.Tournament not found: no tournament has this id.Tournament is not open for registration (status: <status>): the tournament does not take joins.This tournament has no entry fee on a paid tier and cannot take entries.This 1v1 challenge is locked to a specific opponent. You cannot join it.: you are neither its creator nor its target.Could not verify the tournament right now. Please try again.: carriescode: "tx_pending".You created this tournament as organizer-only, so you're set up to run it without playing. Create it without 'Organizer only' to take part yourself.This tournament is private. Only invited teams can join.: you are not invited.This League + Knockout tournament is by invitation only: the invitations go to the top of the leaderboard at its snapshot.: you have no invitation.Your invitation to this tournament has expired: its seat went to the next wave.You declined this invitation, so it is closed.You left this tournament, so your invitation is closed.Your team already has a seat or an invitation in <title>, another League + Knockout tournament. A team takes part in one League + Knockout tournament at a time: this one opens to you once <title> is over.: a League + Knockout invitation while your team has a seat or a pending invitation in another one that is neither completed nor cancelled; a payment already sent is refunded.Your team is still in <title>, a League + Knockout tournament that has started. You can join or create another tournament once your team is out or <title> ends. 1v1 challenges and ranked matches stay open to you.: any tournament other than a 1v1 challenge or a developer tournament.Could not verify your developer binary right now. Please try again.: carriescode: "tx_pending".This is a Developer-mode tournament. Upload and verify a team binary in Developers Hub first, then you can join.Another team in this tournament already uses the binary name "<name>". Rename your binary in Developers Hub to a unique name, then join.Creator must join first: slot 1 is reserved: 1v1 challenge whose creator has not taken the first seat yet.Registration deadline has passed.You need at least 18 unlisted players to enter a match. You currently have <have> (<short> short). Cancel <short> <listing|listings> on the Marketplace or buy <short> more <NFT|NFTs> to play again.: while the 18-player rule is in force, your wallet holds fewer than 18 players that are not listed for sale.No team found. Set up your team first.: you have no team.Lineup must have 11 players: your saved lineup does not hold eleven starters.Team must have exactly 7 substitutes to join a tournament (you have <count>). Open Tactics and save again. The backend will auto-fill the bench from your reserves.: your bench does not hold seven players.Some players in your lineup are no longer owned by you or are listed for sale. Click Sync to refresh your squad, then update your team before joining.: one of your eighteen players left your wallet or is on sale.Some players not found. Expected <expected>, got <found>: some of your players are not known to the game yet.Invalid lineup dataorInvalid substitutes data: your saved lineup or bench cannot be read; save your tactics again.No validated developer team found. Upload and validate a binary in Developers Hub first.: developer tournament without an active verified developer team of yours.Your squad isn't rested enough to play: fewer than 11 players are match-fit (condition too low or in transfer cooldown). Recover their condition in the Shop, then try again.: 1v1 challenge only.Couldn't verify your squad's match fitness right now. Please try again in a moment.: 1v1 challenge only; carriescode: "tx_pending"(nothing was refunded, with or without a hash).<name> was recently transferred (cooldown <h>h <m>m remaining). Tournaments cannot be joined with a recently-rented NFT.: one of your eighteen players arrived by a wallet transfer too recently.You already have an active 1v1. Finish it or cancel it first.: 1v1 challenge while you already created or joined another open or running one.You have a tournament match within the hour. Finish it first.: 1v1 challenge from an hour before a tournament or challenge match of yours until its result is out. The same holds from an hour before your group’s last kickoff until the group’s results are out and from an hour before your Swiss round match until all the round’s results are out.Could not verify your join state. Please try again shortly: carriescode: "tx_pending".You are already in this tournament: you already hold a seat here. A wallet with a seat hears this first, whatever the tournament’s status (active,completedorcancelledincluded), with or without a hash: nothing is refunded and nothing is read on chain.Tournament is full.Tournament is not open for registration (status: closed): the tournament left registration between this call’s checks and its seat; a paid entry is refunded.Chain is temporarily unavailable. Please retry shortly.: paid tournament; carriescode: "tx_pending".Entry fee transaction hash required for Silver/Gold tournaments: paid tournament, notx_hashand no entry of yours on chain.Entry fee verification failed. Try again later: the payment or your entry on chain could not be read; carriescode: "tx_pending".Entry fee payment is less than required: the payment or your entry on chain is below the fee; it is refunded.Transaction <status> on chain: cannot confirm tournament entry: the payment did not succeed.Your payment isn't confirmed on chain yet, but it may still settle. Please retry the tournament entry in a moment.: retry with the same hash; never pay twice.Transaction was rejected on chain (<message>) and refunded: tournament entry not confirmedTransaction sender does not match your walletTransaction was not sent to the tournament entry contractTransaction is not a tournament entry call: the transaction is not ajoinTournamentcall.This payment does not match the tournament's entry fee exactly. It stays refundable; please contact support.This payment was for a different tournament and can't be used to join this one.This entry payment was already used to join. If you left the tournament, pay again to rejoin.Could not verify the payment state right now. Please retry in a moment.: carriescode: "tx_pending".Your entry payment is confirmed. We're finalizing your seat and this page updates automatically. Do NOT pay again.: your entry has not settled on chain yet; call the route again in a moment without a hash.This entry payment was refunded (you left this tournament). Pay again to rejoin.Failed to join tournament. Please try again shortly: carriescode: "tx_pending".We couldn't confirm your entry escrow is backing your seat right now. Please retry in a moment. If it was refunded (e.g. you left this tournament), your FOXSY is already back in your wallet.: carriescode: "tx_pending".Entry fee verification failed. Please try again shortly: carriescode: "tx_pending".Failed to join the tournament. Your entry is kept: press Join again in a moment.: carriescode: "tx_pending".This entry payment was already used to join. If you left, pay again to rejoin.: the same payment took a seat at the same moment.Could not finalize your seat right now. Please retry in a moment.: carriescode: "tx_pending".
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”The tournament id.
Request Body required
Section titled “Request Body required ”The payment proof of a join; send {} for a free tournament.
object
Optional, only with no tx_hash: the hash of the joinTournament payment you hold when you take your seat from an entry already on chain, 64 hexadecimal characters. It is not a payment claim. The seat is proven by the entry on chain; this hash is recorded with the seat only after one read of that transaction shows your successful join of this tournament. A value that is not a hash, a hash that is not yours or one already recorded is ignored: the seat is never refused over this field.
Hash of your joinTournament payment, 64 hexadecimal characters. Leave it out (or send null or an empty string) for a free tournament or to take your seat from an entry already on chain.
Example generated
{ "recovered_tx_hash": "example", "tx_hash": "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
Present when some starters may run out of condition during the tournament: Warning: <n> starter(s) may reach 0 condition during this tournament (<m> estimated matches). Consider using condition recovery items. Absent otherwise.
Your seat id: the id of your row in the tournament’s participants.
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": { "participant_id": 2258 }, "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 invalid