Skip to content

Create a tournament or 1v1 challenge

POST
/api/tournaments/create
curl --request POST \
--url https://foxleague.ai/api/tournaments/create \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "challenge_deadline_minutes": 1, "deadline": "2026-04-15T12:00:00Z", "description": "example", "developer_mode": true, "entry_fee_foxsy": 1, "format": "example", "has_third_place_match": true, "home_and_away": true, "max_teams": 1, "min_teams": 1, "organizer_only": true, "round_interval_minutes": 1, "snapshot_at": "2026-04-15T12:00:00Z", "sponsor_prize_foxsy": 1, "starts_at": "2026-04-15T12:00:00Z", "target_user_id": 1, "tier": "example", "title": "example", "whitelist_user_ids": [ 1 ] }'

Creates a standard tournament or, with max_teams: 2, a 1v1 challenge. In a free tournament you get the first seat at once, unless organizer_only is set. A paid Silver or Gold tournament is first created on chain; you then pay the entry fee and join with POST /api/tournaments/{id}/join like any player. The answer is the tournament as first written: a paid one reads status: "pending_sc" and sc_tournament_id: null here, so read it again before joining. A standard tournament that is not a developer one reserves a time window on the schedule and is refused when that window overlaps another tournament’s. A League + Knockout tournament (an admin only) takes a snapshot_at and is always organized: its seats go to the teams it invites from the leaderboard frozen at that date, in three waves. A paid one is created on chain open to invited wallets only.

Who: a signed-in player.

Rate limit: one active 1v1 challenge per wallet (as creator or opponent), one active tournament you created to play in and one active tournament you organize.

Refusals:

  • Not registered: the wallet has no player account.
  • Invalid format '<format>'. Valid: knockout, groups_knockout, round_robin, swiss, league_knockout: unknown format.
  • League + Knockout tournaments are created by an admin only.: league_knockout from a player.
  • League + Knockout is switched off. An admin turns on tournament.league_knockout_enabled first.: league_knockout while the admin has not switched the format on.
  • A League + Knockout tournament needs a snapshot date (snapshot_at): the leaderboard is frozen then and the invitations go out.: league_knockout without snapshot_at.
  • The snapshot date must be in the future.
  • The snapshot date must be at least <window> before the registration deadline.: the window is an admin setting, 4 days by default.
  • snapshot_at is only for League + Knockout tournaments.: snapshot_at for another format.
  • A League + Knockout tournament invites from the leaderboard: it takes no invite list.: league_knockout with a non-empty whitelist_user_ids.
  • A League + Knockout tournament is played by the NFT teams the leaderboard ranks: it cannot be a developer tournament.: league_knockout with developer_mode: true.
  • 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.: a tournament you would play in (not organizer-only, not a developer tournament, not a 1v1 challenge).
  • A prize from FoxLeague is only for League + Knockout tournaments.: sponsor_prize_foxsy for another format.
  • A prize from FoxLeague needs a Silver or Gold League + Knockout tournament: the contract holds the prize.: a prize on a Bronze one.
  • The prize from FoxLeague must be at least 1 FOXSY.
  • This wallet is not an approved sponsor: the owner approves it once on the contract. Create the tournament without a prize or ask the owner to approve this wallet.: a prize from a wallet the owner has not approved on the contract.
  • Could not check on the contract whether this wallet may give a prize. Please retry or create the tournament without a prize.: the contract could not be read; nothing was created.
  • Invalid tier '<tier>'. Valid: bronze, silver, gold: unknown tier.
  • Invalid max_teams <max_teams> for format '<format>'. Allowed: <sizes>: a size the format does not allow; <sizes> lists the allowed ones, for example 2, 4, 8, 16, 32.
  • min_teams must be >= <minimum> for format '<format>': min_teams below the format’s minimum.
  • min_teams cannot exceed max_teams.
  • Knockout tournaments start only when the bracket is full. Set min and max teams equal (<max_teams>) so every team has an opponent (no byes).: a knockout with min_teams different from max_teams.
  • Groups + KO starts only at a full bracket. Set min and max teams equal (<max_teams>) so the advancing knockout round is a clean power of two (no byes).: the same rule for groups_knockout.
  • 1v1 challenges are Silver or Gold; Bronze is for developer challenges only: a Bronze 1v1 challenge without developer_mode.
  • challenge_deadline_minutes must be one of 30, 60, 120, 240, got <minutes>.
  • You cannot challenge yourself. Choose a different opponent: target_user_id is your own id.
  • Targeted opponent not found. They need to register on the platform first: no player has this target_user_id.
  • Developer challenges can only be created by a verified, active developer team. Upload and validate a binary in Developers Hub first: developer 1v1 challenge without an active verified developer team of yours.
  • That opponent doesn't have a verified, active developer team, so they can't accept a developer challenge: developer 1v1 challenge whose target has no such team.
  • You already have an active 1v1. Finish it or cancel it first.: you already created or joined an open or running 1v1 challenge.
  • 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.
  • Deadline must be in the future.
  • Tournament must start at least 1 hour from now.
  • starts_at must be after the registration deadline: starts_at is not more than five minutes after deadline.
  • Time slot conflicts with tournament #<id> '<title>'. Choose a different time.: the reserved window overlaps another tournament’s.
  • You already have an active tournament you are organizing. Complete or cancel it before creating another.: organizer_only while you already organize an active tournament.
  • You already have an active tournament you are playing in. Complete or cancel it before creating another.: you already created an active standard tournament to play in.
  • Bronze tournaments cannot have an entry fee.
  • Entry fee cannot be negative.
  • Silver: <min>-<max> FOXSY: a Silver fee outside the Silver range, 0 included.
  • Gold: >=<min> FOXSY: a Gold fee below the Gold minimum, 0 included.
  • Round interval must be 30-1440 minutes: round_interval_minutes above 1440.
  • Title must be 1-100 characters: blank or too long title.
  • Description must be under 1000 characters.
  • Tournament cannot start more than 90 days from now.
  • One or more invited teams were not found. They need to register first.: an id in whitelist_user_ids is not a player.
  • The invite list has more teams (<count>) than the tournament holds (<max_teams>).: whitelist_user_ids holds more teams than max_teams.
  • A private tournament can only be filled by the teams you invite plus yourself. You invited <count>, so at most <capacity> can join, which is below the minimum of <min_teams>. Invite more teams or lower the minimum.: too few invitations for min_teams (without plus yourself when you organize only).
  • Could not create the tournament right now. Please retry.: the tournament could not be stored; nothing was created.
  • Paid tournaments are not available right now. Please try again later.: a Silver or Gold tournament while paid tournaments cannot be created.
  • Chain is temporarily unavailable. Please retry shortly.: paid tournament while the chain cannot be reached; nothing was created.
  • The tournament could not be created on chain, so it was cancelled. Please try again.
  • On-chain tournament creation could not be confirmed yet. The network may not be producing blocks; the tournament stays pending until its creation can be confirmed. Please check the tournament list before retrying.: the tournament stays pending_sc until its creation on chain is confirmed.
  • Developer tournaments require a validated developer team to enter. Create it as organizer-only to run it without playing. Otherwise validate a binary in Developers Hub first.: free developer tournament, you play in it and you have no verified developer binary.
  • 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.
  • Tournament creation failed. Could not snapshot your team: <reason>: free tournament where your squad cannot take its seat; <reason> is one of the squad refusals of POST /api/tournaments/{id}/join. Nothing was created.
  • Tournament creation failed: your team could not be added to it. Please try again.: nothing was created.
Media type application/json

The settings of a new tournament or 1v1 challenge.

object
challenge_deadline_minutes

1v1 challenge only: minutes the challenge stays open, 30, 60, 120 or 240 (default 60). Kickoff is five minutes after it closes; when an opponent accepts, registration closes at once and the match is scheduled shortly after.

integer | null format: int32
deadline
required

Registration closes at this time (RFC 3339); it must be in the future. Required but ignored for a 1v1 challenge.

string format: date-time
description

Optional text, at most 1000 characters.

string | null
developer_mode

Only teams with a verified developer binary may join. Available on every format except League + Knockout.

boolean | null
entry_fee_foxsy

Entry fee in whole FOXSY. 0 or absent for Bronze. Silver and Gold need a fee inside the tier’s range; the refusal names the range.

integer | null format: int64
format
required

knockout, groups_knockout, round_robin, swiss or league_knockout (League + Knockout: created by an admin only, while the admin has switched the format on). A 1v1 challenge is knockout.

string
has_third_place_match

Adds a match for third place between the losing semifinalists. Default false.

boolean | null
home_and_away

round_robin only: every pair of teams meets twice. Ignored for other formats.

boolean | null
max_teams
required

Seats. knockout: 2, 4, 8, 16 or 32 (2 makes a 1v1 challenge). groups_knockout: 8, 16, 32 or 64. round_robin: 3 to 20. swiss: 3 to 32. league_knockout: 36.

integer format: int32
min_teams
required

Teams needed to start; with fewer at the deadline the tournament is cancelled. At least 2 for knockout, 8 for groups_knockout, 36 for league_knockout and 3 for round_robin and swiss; at most max_teams. Equal to max_teams for knockout, groups_knockout and league_knockout.

integer format: int32
organizer_only

Standard tournament only: you run the tournament without a seat and cannot join it later.

boolean | null
round_interval_minutes

Minutes between one match’s kickoff and the next: the tournament plays its matches one after another. Default 30; a lower value counts as 30; at most 1440.

integer | null format: int32
snapshot_at

League + Knockout only (required there): when the leaderboard is frozen and the first invitation wave goes out. In the future and at least 4 days (an admin setting) before deadline. Refused for every other format.

string | null format: date-time
sponsor_prize_foxsy

League + Knockout only, optional: a prize from FoxLeague in whole FOXSY, at least 1, split equally among the 8 quarter-finalists by the tournaments contract. Only on a Silver or Gold tournament and only when your wallet is an approved sponsor on the contract. Your wallet deposits it after the create, before the snapshot.

integer | null format: int64
starts_at
required

Kickoff of the first match (RFC 3339): more than one hour from now, more than five minutes after deadline and at most 90 days ahead. Required but ignored for a 1v1 challenge.

string format: date-time
target_user_id

1v1 challenge only: the user id of the only opponent who may accept. Not your own id.

integer | null format: int32
tier
required

bronze (free), silver or gold (paid in FOXSY). A 1v1 challenge is Silver or Gold; Bronze only for a developer challenge.

string
title
required

Name of the tournament, 1 to 100 characters, not blank.

string
whitelist_user_ids

Standard tournament only, never League + Knockout (its invitations come from the leaderboard): user ids of the teams you invite. A non-empty list makes the tournament private. Your own id and repeated ids are dropped; at most max_teams ids.

Array<integer> | null
Example generated
{
"challenge_deadline_minutes": 1,
"deadline": "2026-04-15T12:00:00Z",
"description": "example",
"developer_mode": true,
"entry_fee_foxsy": 1,
"format": "example",
"has_third_place_match": true,
"home_and_away": true,
"max_teams": 1,
"min_teams": 1,
"organizer_only": true,
"round_interval_minutes": 1,
"snapshot_at": "2026-04-15T12:00:00Z",
"sponsor_prize_foxsy": 1,
"starts_at": "2026-04-15T12:00:00Z",
"target_user_id": 1,
"tier": "example",
"title": "example",
"whitelist_user_ids": [
1
]
}

Success or a refusal: read success (the refusals are in the description).

Media type application/json
object
code

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.

string | null
data

The answer. Present when success is true.

object
away_penalty

Completed 1v1 challenge rows decided on penalties: shootout goals of the away side. Absent otherwise.

integer | null format: int32
away_score

Completed 1v1 challenge rows of the tournament lists: goals of the away side. Absent otherwise.

integer | null format: int32
blocking_window_end

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.

string | null format: date-time
blocking_window_start

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.

string | null format: date-time
cancelled_at

When the tournament was cancelled (RFC 3339); null when it was not.

string | null format: date-time
challenge_deadline_minutes

1v1 challenge: the minutes it was opened for. null for a standard tournament.

integer | null format: int32
completed_at

When the tournament completed (RFC 3339); null before.

string | null format: date-time
created_at
required

When the tournament was created (RFC 3339).

string format: date-time
creator_badge

1v1 challenge rows of the tournament lists: the creator’s team badge. Absent otherwise.

string | null
creator_team_name

1v1 challenge rows of the tournament lists: the creator’s team name. Absent otherwise.

string | null
creator_user_id
required

User id of the creator (the organizer).

integer format: int32
deadline
required

Registration closes at this time (RFC 3339).

string format: date-time
decided_by

Completed 1v1 challenge rows of the tournament lists: regular, extra_time or penalties. Absent otherwise.

string | null
description

Text written by the creator; null when none.

string | null
developer_mode

true when only teams with a verified developer binary may join.

boolean | null
distribute_tx_hash

Completed 1v1 challenge rows of the tournament lists: hash of the prize payout transaction. Absent otherwise.

string | null
entry_fee_foxsy
required

Entry fee in whole FOXSY; 0 for Bronze.

integer format: int64
featured
required

true for a tournament the game features: it is listed first and enters the hall of fame when it completes.

boolean
format
required

knockout, groups_knockout, round_robin, swiss or league_knockout (League + Knockout: 36 teams in one league table drawn from four pots).

string
has_third_place_match
required

true when a match for third place is played.

boolean
home_and_away

true for a round robin where every pair of teams meets twice.

boolean | null
home_penalty

Completed 1v1 challenge rows decided on penalties: shootout goals of the home side. Absent otherwise.

integer | null format: int32
home_score

Completed 1v1 challenge rows of the tournament lists: goals of the home side. Absent otherwise.

integer | null format: int32
home_user_id

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.

integer | null format: int32
id
required

The tournament id.

integer format: int64
is_private

true when only invited teams may join.

boolean
max_teams
required

Seats. 2 for a 1v1 challenge.

integer format: int32
min_teams
required

Teams needed to start; with fewer at the deadline the tournament is cancelled.

integer format: int32
opponent_badge

1v1 challenge rows of the tournament lists: the opponent’s team badge once an opponent holds the second seat. Absent otherwise.

string | null
opponent_team_name

1v1 challenge rows of the tournament lists: the opponent’s team name once an opponent holds the second seat. Absent otherwise.

string | null
organizer_only

Tournament detail only: true when the creator runs the tournament without a seat. Absent elsewhere.

boolean | null
participant_count

Seats taken. Filled by GET /api/tournaments; null in other answers.

integer | null format: int64
round_interval_minutes
required

Minutes between one match’s kickoff and the next.

integer format: int32
runner_up_user_id

User id of the runner-up, set when the tournament completes; null before.

integer | null format: int32
sc_tournament_id

Id of the tournament on chain (equal to id) for a paid tournament once it is created there; null for a free tournament.

integer | null format: int64
started_at

When registration closed and the draw was made (RFC 3339); null before.

string | null format: date-time
starts_at
required

Kickoff of the first match (RFC 3339).

string format: date-time
status
required

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.

string
target_user_id

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.

integer | null format: int32
targeted

true for a 1v1 challenge locked to one opponent. Absent otherwise.

boolean
targeted_to_you

true when you are the opponent a targeted 1v1 challenge is locked to. Absent otherwise.

boolean
third_place_user_id

User id of the third-placed team, set when the tournament completes; null before and when no third place is decided.

integer | null format: int32
tier
required

bronze (free), silver or gold (paid in FOXSY).

string
title
required

Name of the tournament.

string
winner_user_id

User id of the winner, set when the tournament completes; null before.

integer | null format: int32
error

Why the request was refused, in plain words. Present when success is false.

string | null
success
required

true when the request did what it asked. false is a refusal: read error.

boolean
Example
{
"data": {
"blocking_window_end": "2026-10-04T19:24:00Z",
"blocking_window_start": "2026-10-04T17:00:00Z",
"cancelled_at": null,
"challenge_deadline_minutes": null,
"completed_at": null,
"created_at": "2026-10-01T09:12:44.518204Z",
"creator_user_id": 57,
"deadline": "2026-10-04T17: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": 419,
"is_private": false,
"max_teams": 8,
"min_teams": 8,
"participant_count": null,
"round_interval_minutes": 30,
"runner_up_user_id": null,
"sc_tournament_id": null,
"started_at": null,
"starts_at": "2026-10-04T18:00:00Z",
"status": "pending_sc",
"target_user_id": null,
"third_place_user_id": null,
"tier": "silver",
"title": "Sunday Silver Cup",
"winner_user_id": null
},
"success": true
}

The request body is not valid JSON.

Media type application/json
object
code

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.

string | null
data

The answer. Present when success is true.

object
away_penalty

Completed 1v1 challenge rows decided on penalties: shootout goals of the away side. Absent otherwise.

integer | null format: int32
away_score

Completed 1v1 challenge rows of the tournament lists: goals of the away side. Absent otherwise.

integer | null format: int32
blocking_window_end

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.

string | null format: date-time
blocking_window_start

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.

string | null format: date-time
cancelled_at

When the tournament was cancelled (RFC 3339); null when it was not.

string | null format: date-time
challenge_deadline_minutes

1v1 challenge: the minutes it was opened for. null for a standard tournament.

integer | null format: int32
completed_at

When the tournament completed (RFC 3339); null before.

string | null format: date-time
created_at
required

When the tournament was created (RFC 3339).

string format: date-time
creator_badge

1v1 challenge rows of the tournament lists: the creator’s team badge. Absent otherwise.

string | null
creator_team_name

1v1 challenge rows of the tournament lists: the creator’s team name. Absent otherwise.

string | null
creator_user_id
required

User id of the creator (the organizer).

integer format: int32
deadline
required

Registration closes at this time (RFC 3339).

string format: date-time
decided_by

Completed 1v1 challenge rows of the tournament lists: regular, extra_time or penalties. Absent otherwise.

string | null
description

Text written by the creator; null when none.

string | null
developer_mode

true when only teams with a verified developer binary may join.

boolean | null
distribute_tx_hash

Completed 1v1 challenge rows of the tournament lists: hash of the prize payout transaction. Absent otherwise.

string | null
entry_fee_foxsy
required

Entry fee in whole FOXSY; 0 for Bronze.

integer format: int64
featured
required

true for a tournament the game features: it is listed first and enters the hall of fame when it completes.

boolean
format
required

knockout, groups_knockout, round_robin, swiss or league_knockout (League + Knockout: 36 teams in one league table drawn from four pots).

string
has_third_place_match
required

true when a match for third place is played.

boolean
home_and_away

true for a round robin where every pair of teams meets twice.

boolean | null
home_penalty

Completed 1v1 challenge rows decided on penalties: shootout goals of the home side. Absent otherwise.

integer | null format: int32
home_score

Completed 1v1 challenge rows of the tournament lists: goals of the home side. Absent otherwise.

integer | null format: int32
home_user_id

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.

integer | null format: int32
id
required

The tournament id.

integer format: int64
is_private

true when only invited teams may join.

boolean
max_teams
required

Seats. 2 for a 1v1 challenge.

integer format: int32
min_teams
required

Teams needed to start; with fewer at the deadline the tournament is cancelled.

integer format: int32
opponent_badge

1v1 challenge rows of the tournament lists: the opponent’s team badge once an opponent holds the second seat. Absent otherwise.

string | null
opponent_team_name

1v1 challenge rows of the tournament lists: the opponent’s team name once an opponent holds the second seat. Absent otherwise.

string | null
organizer_only

Tournament detail only: true when the creator runs the tournament without a seat. Absent elsewhere.

boolean | null
participant_count

Seats taken. Filled by GET /api/tournaments; null in other answers.

integer | null format: int64
round_interval_minutes
required

Minutes between one match’s kickoff and the next.

integer format: int32
runner_up_user_id

User id of the runner-up, set when the tournament completes; null before.

integer | null format: int32
sc_tournament_id

Id of the tournament on chain (equal to id) for a paid tournament once it is created there; null for a free tournament.

integer | null format: int64
started_at

When registration closed and the draw was made (RFC 3339); null before.

string | null format: date-time
starts_at
required

Kickoff of the first match (RFC 3339).

string format: date-time
status
required

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.

string
target_user_id

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.

integer | null format: int32
targeted

true for a 1v1 challenge locked to one opponent. Absent otherwise.

boolean
targeted_to_you

true when you are the opponent a targeted 1v1 challenge is locked to. Absent otherwise.

boolean
third_place_user_id

User id of the third-placed team, set when the tournament completes; null before and when no third place is decided.

integer | null format: int32
tier
required

bronze (free), silver or gold (paid in FOXSY).

string
title
required

Name of the tournament.

string
winner_user_id

User id of the winner, set when the tournament completes; null before.

integer | null format: int32
error

Why the request was refused, in plain words. Present when success is false.

string | null
success
required

true when the request did what it asked. false is a refusal: read error.

boolean
Example generated
{
"code": "example",
"data": {
"away_penalty": 1,
"away_score": 1,
"blocking_window_end": "2026-04-15T12:00:00Z",
"blocking_window_start": "2026-04-15T12:00:00Z",
"cancelled_at": "2026-04-15T12:00:00Z",
"challenge_deadline_minutes": 1,
"completed_at": "2026-04-15T12:00:00Z",
"created_at": "2026-04-15T12:00:00Z",
"creator_badge": "example",
"creator_team_name": "example",
"creator_user_id": 1,
"deadline": "2026-04-15T12:00:00Z",
"decided_by": "example",
"description": "example",
"developer_mode": true,
"distribute_tx_hash": "example",
"entry_fee_foxsy": 1,
"featured": true,
"format": "example",
"has_third_place_match": true,
"home_and_away": true,
"home_penalty": 1,
"home_score": 1,
"home_user_id": 1,
"id": 1,
"is_private": true,
"max_teams": 1,
"min_teams": 1,
"opponent_badge": "example",
"opponent_team_name": "example",
"organizer_only": true,
"participant_count": 1,
"round_interval_minutes": 1,
"runner_up_user_id": 1,
"sc_tournament_id": 1,
"started_at": "2026-04-15T12:00:00Z",
"starts_at": "2026-04-15T12:00:00Z",
"status": "example",
"target_user_id": 1,
"targeted": true,
"targeted_to_you": true,
"third_place_user_id": 1,
"tier": "example",
"title": "example",
"winner_user_id": 1
},
"error": "example",
"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.

Media type text/plain
string
Example
Session expired or invalid