List tournaments and 1v1 challenges
const url = 'https://foxleague.ai/api/tournaments';const options = {method: 'GET'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url https://foxleague.ai/api/tournamentsLists tournaments and 1v1 challenges: featured ones first, then by kickoff, newest first, unless sort or sections asks for another order. The answer is one page of up to 500 rows. Every filter and the order are applied before the page is cut, so a page of 20 rows is the first 20 of the filtered list. The X-Total-Count response header holds how many match the filters in all; ask for the next page with offset set to the number of rows already read until you hold that many. Use kind to list tournaments and challenges separately. Use public_only to leave out what a stranger cannot join. Use completed_since to list only those that completed at or after an instant: a tournament completes after the broadcast of its last match has ended, at its completed_at. A 1v1 row carries the team names and badges of its creator and opponent; a completed 1v1 row carries its score once its match’s broadcast ends.
With sections, the X-Section-Counts response header holds how many rows of the filtered list each section has, in display order, for example open=3,active=1,completed=730. Every answer carries the header X-List-Contract: 2: a server without it ignored hide_cancelled, developer_mode, involving, wallet, search, sections and sort.
Who: anyone. With a session, the creator and the target of a targeted 1v1 challenge also read its target_user_id. The target reads targeted_to_you: true. involving answers for the player named by wallet, else for the signed-in player; with neither it answers no rows.
Refusals:
Unknown tournament status: use open, pending_sc, active, completed, cancelled or awaiting_payment.:statusis none of these six values (HTTP 200).Invalid sort. Use one of: featured, newest, pool_desc, pool_asc: HTTP 400.Invalid sections. Use one of: status, phase, featured: HTTP 400.Invalid involving. Use one of: target, target_or_creator, participant_or_creator, mine: HTTP 400.Invalid <parameter>: a NUL byte is not a character.: HTTP 400;<parameter>is the text parameter that held the byte.
Authorizations
Section titled “Authorizations ”- None
- session
Parameters
Section titled “ Parameters ”Query Parameters
Section titled “Query Parameters ”Only tournaments with this status: open, pending_sc, active, completed, cancelled or awaiting_payment. awaiting_payment: a challenge or tournament you authorized with POST /api/tournaments/challenges/authorize and have not paid yet; only its creator ever reads it. Any other value is refused.
Only tournaments of this format: knockout, groups_knockout, round_robin, swiss or league_knockout.
Only tournaments of this tier: bronze, silver or gold.
standard lists tournaments of more than two teams; challenge lists 1v1 challenges. Without it both are listed together.
Only tournaments that completed at or after this instant, as RFC 3339 with Z or an offset (for example 2026-10-08T00:00:00Z). A tournament that was cancelled never completed. Any other value is refused with HTTP 400.
Rows per page, 1 to 500. Default 500.
Rows to skip. Default 0.
true leaves cancelled tournaments out.
true lists only developer tournaments; false lists only the others. Without it both are listed.
Only rows a player is part of: the player named by wallet, else the signed-in one. target: 1v1 challenges addressed to them. target_or_creator: addressed to them or created by them. participant_or_creator: tournaments they play in or created. mine: created by them, joined by them or addressed to them (the 1v1 lobby’s own set). Without a wallet or a session no row matches.
The player involving is about, by wallet address. What is public about them answers to anyone: the tournaments they created or play in. Who a challenge is addressed to is not public: with wallet, target and the target half of target_or_creator answer only under that wallet’s own session; under another session or none they match nothing. An unknown wallet matches nothing.
Lists the rows section after section and counts each section in X-Section-Counts. status: open, active, completed, cancelled, then every other status. phase: open (neither running nor completed), active (running), completed. featured: featured (whatever its status), open (open or being created), running, completed, other (cancelled). sort then orders the rows inside each section.
The order of the rows. featured (the default): featured first, then latest kickoff first. newest: newest created first. pool_desc: largest prize pool (entry fee times seats) first. pool_asc: smallest prize pool first.
Only tournaments whose title contains this text (upper and lower case are the same) or the one whose id is this number, written with or without a leading hash sign.
true lists only what any team may join: it leaves out a tournament with an invite list and a 1v1 challenge addressed to one team. Champions FoxLeague (league_knockout) always shows. So do the ones the signed-in player created, is invited to, plays in or is challenged in; for a player named by wallet without their session, the ones they created or play in. X-Total-Count and X-Section-Counts count the filtered list. Absent or false: every tournament is listed.
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.
A tournament or 1v1 challenge.
object
Completed 1v1 challenge rows decided on penalties: shootout goals of the away side. Absent otherwise.
Completed 1v1 challenge rows of the tournament lists: goals of the away side. Absent otherwise.
End of that reserved window (RFC 3339): one hour after the tournament’s booked play time, about 3 minutes per match without the time between games; null when there is none. This is not when the tournament ends: it can keep playing after its window for hours or days.
Start of the time window a standard tournament reserves on the schedule, one hour before kickoff (RFC 3339). No other tournament may reserve an overlapping window. null for 1v1 challenges and developer tournaments.
When the tournament was cancelled (RFC 3339); null when it was not.
1v1 challenge: the minutes it was opened for. null for a standard tournament.
When the tournament completed (RFC 3339); null before.
When the tournament was created (RFC 3339).
1v1 challenge rows of the tournament lists: the creator’s team badge. Absent otherwise.
1v1 challenge rows still to be played (not completed nor cancelled, not a developer one): the creator’s team OVR, one decimal, its best XI OVR (the average OVR of the strongest XI it can field from the cards it owns now (for every formation in Tactics the best card of each position for its slots, each card in its own position, the highest average kept; cards listed for sale count)). Absent otherwise and when no card it owns fits a slot.
The formation the creator’s best XI is built in, such as 4-3-3. Absent with creator_ovr.
1v1 challenge rows of the tournament lists: the creator’s team name. Absent otherwise.
User id of the creator (the organizer).
Registration closes at this time (RFC 3339).
Completed 1v1 challenge rows of the tournament lists: regular, extra_time or penalties. Absent otherwise.
Text written by the creator; null when none.
true when only teams with a verified developer binary may join.
Completed 1v1 challenge rows of the tournament lists: hash of the prize payout transaction. Absent otherwise.
Entry fee in whole FOXSY; 0 for a free tournament (every Bronze before the competition levels go live, a developer one always).
true for a tournament the game features: it is listed first and enters the hall of fame when it completes.
knockout, groups_knockout, round_robin, swiss or league_knockout (Champions FoxLeague: 36 teams in one league table drawn from four pots, then two-legged knockout ties up to a single-match final).
true when a match for third place is played. A Champions FoxLeague tournament always plays one, before its final.
true for a round robin where every pair of teams meets twice.
Completed 1v1 challenge rows decided on penalties: shootout goals of the home side. Absent otherwise.
Completed 1v1 challenge rows of the tournament lists: goals of the home side. Absent otherwise.
Completed 1v1 challenge rows of GET /api/tournaments: user id of the home side, to match the score to the teams (the creator is not always at home). Absent otherwise.
The tournament id.
true when only invited teams may join.
Seats. 2 for a 1v1 challenge.
Teams needed to start; with fewer at the deadline the tournament is cancelled.
1v1 challenge rows of the tournament lists: the opponent’s team badge once an opponent holds the second seat. Absent otherwise.
The opponent’s team OVR, read like creator_ovr, once an opponent holds the second seat. Absent otherwise.
The formation the opponent’s best XI is built in. Absent with opponent_ovr.
1v1 challenge rows of the tournament lists: the opponent’s team name once an opponent holds the second seat. Absent otherwise.
Tournament detail only: true when the creator runs the tournament without a seat. Absent elsewhere.
The highest best XI OVR a team may have to join, a whole number from 1 to 100. Absent when there is none. While registration is open its creator or an admin can raise it or remove it; it never drops.
The lowest best XI OVR a team may have to join, a whole number from 1 to 100. Absent when there is none. The best XI OVR is the average OVR of the strongest XI a manager can field from the cards they own; it is checked once, when a team joins. While registration is open its creator or an admin can lower it or remove it (POST /api/tournaments/{id}/ovr-range); it never rises.
Seats taken. Filled by GET /api/tournaments; null in other answers.
Minutes between one match’s kickoff and the next.
User id of the runner-up, set when the tournament completes; null before.
Id of the tournament on chain (equal to id) for a paid tournament once it is created there; null for a free tournament.
When registration closed and the draw was made (RFC 3339); null before.
Kickoff of the first match (RFC 3339).
open: registration is open. pending_sc: a paid tournament is being created on chain and cannot be joined yet. active: registration closed and the tournament is under way. completed: finished, podium set. cancelled: too few teams at the deadline or cancelled by its creator. awaiting_payment: a challenge or tournament its creator authorized with POST /api/tournaments/challenges/authorize and has not paid yet; only its creator is ever answered it.
Targeted 1v1 challenge: user id of the only opponent who may accept. Given to the creator and the target only; null for everyone else and for any other tournament.
true for a 1v1 challenge locked to one opponent. Absent otherwise.
true when you are the opponent a targeted 1v1 challenge is locked to. Absent otherwise.
User id of the third-placed team, set when the tournament completes; null before and when no third place is decided.
bronze, silver or gold. A Bronze with an entry fee (possible once the competition levels are live) is paid like Silver; one without is free.
Name of the tournament.
User id of the winner, set when the tournament completes; null before.
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": [ { "blocking_window_end": "2026-10-02T19:24:00Z", "blocking_window_start": "2026-10-02T17:00:00Z", "cancelled_at": null, "challenge_deadline_minutes": null, "completed_at": null, "created_at": "2026-09-30T09:12:44Z", "creator_user_id": 57, "deadline": "2026-10-02T17:00:00Z", "description": "Eight teams, straight knockout.", "developer_mode": false, "entry_fee_foxsy": 1000, "featured": false, "format": "knockout", "has_third_place_match": true, "home_and_away": false, "id": 412, "is_private": false, "max_teams": 8, "min_teams": 8, "participant_count": 3, "round_interval_minutes": 30, "runner_up_user_id": null, "sc_tournament_id": 412, "started_at": null, "starts_at": "2026-10-02T18:00:00Z", "status": "open", "target_user_id": null, "third_place_user_id": null, "tier": "silver", "title": "Friday Night Cup", "winner_user_id": null }, { "blocking_window_end": null, "blocking_window_start": null, "cancelled_at": null, "challenge_deadline_minutes": 60, "completed_at": null, "created_at": "2026-10-01T10:40:00Z", "creator_badge": "ipfs://bafkrei7qa5efe6qeqpno57ye6scmejvqtia6d7rgn7ss555hmtf", "creator_ovr": 48.3, "creator_ovr_formation": "4-4-2", "creator_team_name": "Copper Valley", "creator_user_id": 88, "deadline": "2026-10-01T11:40:00Z", "description": null, "developer_mode": false, "entry_fee_foxsy": 5000, "featured": false, "format": "knockout", "has_third_place_match": false, "home_and_away": false, "id": 415, "is_private": false, "max_teams": 2, "min_teams": 2, "participant_count": 1, "round_interval_minutes": 30, "runner_up_user_id": null, "sc_tournament_id": 415, "started_at": null, "starts_at": "2026-10-01T11:45:00Z", "status": "open", "target_user_id": null, "targeted": true, "third_place_user_id": null, "tier": "gold", "title": "Come and get it", "winner_user_id": null } ], "success": true}A sort, sections or involving outside its values and a NUL byte in a text parameter answer a JSON body with success: false and the reason in error. A completed_since that is not an RFC 3339 instant, a hide_cancelled or developer_mode that is not a boolean and a limit or offset that is not a number answer plain text.
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