Tournaments REST API

Overview

The Tournaments REST API enables server-side management of pool tournaments, including creation, modification, score tracking, and completion operations.

Prerequisites

  • API key configured per API Setup

  • Understanding of tournament types and payout structures

Base URL

Sandbox: https://api.sandbox.lucrasports.com
Production: https://api.lucrasports.com

Authentication

All requests require authentication via the X-Lucra-Api-Key header. See API Setup for details.

Tournament Concepts

Type: CASH_FIXED

The total prize pool is defined upfront and has no relation to the amount collected from buy-ins. This means:

  • The reward amounts are fixed regardless of how many participants join

  • The tenant bears the financial risk - if insufficient participants join, the tenant may pay out more in prizes than collected in entry fees

  • Prize values in paymentStructure represent absolute monetary amounts

  • Example: A tournament with $1,000 in total prizes will pay exactly $1,000 to winners, even if only $500 was collected from entry fees

Type: CASH_PERCENTAGE

The prize pool is calculated from the total amount collected from entry fees, distributed according to percentage allocations. Key characteristics:

  • Reward tiers are defined as percentages rather than fixed amounts

  • The value in paymentStructure represents a percentage (e.g., 60 for 60%)

  • The sum of all percentage values must equal exactly 100

  • The actual payout amounts are calculated after fees are deducted from the collected pool

Example: With a 60%/30%/10% split:

  • If $1,000 is collected and there's a 10% platform fee ($100), the net pool is $900

  • 1st place receives: 60% of $900 = $540

  • 2nd place receives: 30% of $900 = $270

  • 3rd place receives: 10% of $900 = $90

Payout Calculation:

Replayable Tournaments

Replayable tournaments allow participants to join the same tournament multiple times, submitting new scores in an attempt to improve their standing. Each time a user rejoins, they pay the buy-in amount again (if applicable) and start a new attempt.

Key Attributes:

Attribute
Type
Default
Description

maxAttempts

number

1

Maximum number of times a user can join/rebuy into the tournament

attemptFinished

boolean

false

When submitting scores, marks the attempt as completed (prevents further score updates)

omitAttemptCompletedCheck

boolean

false

If true, allows rebuys even when the current attempt is not finished

How It Works:

  1. Initial Entry: Users join the tournament by paying the buy-in amount (their first attempt).

  2. Submitting Scores: While an attempt is active, users can submit and update their scores. Set attemptFinished: true when submitting a score to mark the attempt as complete and lock it from further updates.

  3. Rebuying: Users can rejoin the tournament (rebuy) to start a new attempt if:

    • They haven't reached maxAttempts

    • Their current attempt is finished (when omitAttemptCompletedCheck: false)

    • OR at any time (when omitAttemptCompletedCheck: true)

  4. Buy-in Collection: Each rebuy charges the full buyInAmount again, increasing the total pool.

  5. Leaderboard: The user's best score across all attempts determines their final position. Only their best attempt counts toward rankings and rewards.

Common Configurations:

Use Case

maxAttempts

omitAttemptCompletedCheck

Behavior

Single attempt only

1

false

Standard tournament - no rebuys allowed

Multiple attempts, finish first

3

false

Users must complete each attempt before starting a new one

Multiple attempts, flexible

3

true

Users can abandon and restart attempts without finishing

Example Workflow:

Checking Rebuy Eligibility:

Use the canSubmitNewScore field in the user leaderboard response to determine if a user can submit additional scores or needs to rebuy:

  • canSubmitNewScore: true - User can update their current attempt

  • canSubmitNewScore: false - User's attempt is finished; they must rebuy to submit new scores

Position and Ranking

Understanding how positions work is critical for tournament completion and reward distribution. There are two position fields that serve different purposes:

Position Fields:

Field
Type
Description

position

number

Automatically calculated rank based on scores (1st, 2nd, 3rd, etc.)

positionOverride

number

Optional manual position that overrides the automatic ranking for reward distribution

How Positions Are Calculated:

  1. Automatic Position (position):

    • Calculated based on scores according to the scoringType

    • For HIGHEST_SCORE: Higher scores = better position

    • For LOWEST_SCORE: Lower scores = better position

    • Uses sequential numbering: 1, 2, 3, 4, 5...

    • Always unique - no two users have the same position

    • Updated automatically whenever scores change

  2. Position Override (positionOverride):

    • Automatically calculated using rank-based logic that handles ties: 1, 2, 2, 4, 5...

    • Can also be manually set during tournament completion for custom adjustments

    • Returns null when it equals position (no override needed)

    • Returns the actual value when it differs from position (ties or manual adjustments)

    • Takes precedence over automatic position for reward allocation

    • Used to handle tied scores and special cases

Position in Reward Structure:

In the rewardStructure array, position fields define prize tiers and their recipients:

Position in User Leaderboard:

In the users array, position fields show each participant's ranking:

When to Use Position Override:

Use positionOverride when completing tournaments to handle these scenarios:

Scenario
Example

Handling Ties

Two users with identical scores both receive 1st place rewards

Manual Adjustments

Disqualification or rule violations require position changes

External Factors

Video review or judge decisions modify automatic rankings

Custom Reward Rules

Business logic requires different reward allocation than score-based ranking

Example - Handling a Tie:

Two users achieve the same score and should both receive 1st place rewards:

Automatic Tournament Completion:

When using auto-complete (completing without specifying winners), the system:

  1. Sorts users by score according to scoringType

  2. Calculates position using sequential numbering (1, 2, 3, 4, 5...)

  3. Calculates an override position that handles ties (1, 2, 2, 4, 5...)

  4. Sets positionOverride to non-null only when it differs from position (i.e., when there are tied scores)

  5. Distributes rewards based on the final positions

Best Practices:

  • Read-only during active tournament: Position values are calculated automatically; you cannot set them via score updates

  • Set during completion: Use positionOverride in the complete endpoint to manually adjust final positions

  • Null means no override: If positionOverride is null, the automatic position is used for rewards

  • Display positions: Always use positionOverride ?? position to show the user's final ranking

  • Validate overrides: Ensure position overrides align with your prize distribution logic

Endpoints

Create Tournament

Create a new pool tournament.

Request Body:

Field Descriptions:

Field
Type
Required
Description

title

string

Yes

Tournament name

description

string

No

Tournament description

type

string

Yes

CASH_FIXED or CASH_PERCENTAGE

buyInAmount

number

Yes

Entry fee per participant

paymentStructure

array

Yes

Prize distribution by position

maxParticipants

number

No

Maximum participants

minPayoutAmount

number

No

Minimum guaranteed prize pool

fee

number

No

Platform fee percentage (default: 0)

scoringType

string

No

HIGHEST_SCORE or LOWEST_SCORE (default: HIGHEST_SCORE)

gameId

string

No

External game identifier

locationIds

array

No

Array of location UUIDs

startsAt

string

No

ISO 8601 start timestamp

expiresAt

string

No

ISO 8601 expiration timestamp

isPublic

boolean

No

Whether tournament is publicly visible

visibilityLevel

string

No

Visibility level: PUBLIC, PRIVATE_HIDDEN, or PRIVATE_VIEWABLE

privateCode

string

No

Access code for joining a private tournament

omitAttemptCompletedCheck

boolean

No

If true, allows users to replay without finishing the previous attempt (see Replayable Tournaments)

overrideImageUrl

string

No

Custom image URL for tournament banner

maxAttempts

number

No

Maximum number of attempts allowed per user (see Replayable Tournaments)

metadataString

string

No

JSON string for custom metadata (alternative: use metadata object)

Response:

Returns created tournament object with generated matchupId.

Get Tournament

Retrieve tournament details including participants and standings. This endpoint requires Lucra users and matchups ID tracking. If you want to search matchups using metadata matching see Tournament Metadata Matching section.

Path Parameters:

  • matchupId (string, required) - UUID of the tournament

Response:

Matchup Response Field Descriptions:

Field
Type
Description

id

string

UUID of the tournament

status

string

Tournament status (OPEN, CONFIRMED, CLOSED, etc.)

type

string

CASH_FIXED or CASH_PERCENTAGE

tenantId

string

UUID of the tenant who owns the tournament

createdAt

string

ISO 8601 timestamp when tournament was created

expiresAt

string

ISO 8601 expiration timestamp

startsAt

string

ISO 8601 start timestamp

isPublic

boolean

Whether tournament is publicly visible

visibilityLevel

string

Visibility level setting

gameId

string

External game identifier

title

string

Tournament name

description

string

Tournament description

metadataString

string

JSON string for custom metadata

metadata

object

Parsed metadata object

locationIds

array

Array of location UUIDs

fee

number

Platform fee percentage

buyInAmount

number

Entry fee per participant

numberOfParticipants

number

Current number of participants

maxParticipants

number

Maximum participants allowed

maxAttempts

number

Maximum attempts per user

totalPoolAmount

number

Total collected pool amount

poolTotalAmount

number

Total pool amount (same as totalPoolAmount)

poolNetAmount

number

Net pool amount after fees

poolFeeAmount

number

Total fees collected

scoringType

string

HIGHEST_SCORE or LOWEST_SCORE

privateCode

string

Private access code (if private tournament)

overrideImageUrl

string

Custom tournament banner image URL

rewardStructure

array

Prize distribution structure with winners

users

array

Leaderboard with all participants

Reward Structure Field Descriptions:

Field
Type
Description

position

number

Prize tier position as defined in payment structure (see Position and Ranking)

positionOverride

number

Manual position override for reward assignment (see Position and Ranking)

value

number

Prize value for this position

userId

string

UUID of user in this position (if settled)

userName

string

Username of winner (if settled)

userMetadata

object

User metadata

tierNetAmount

number

Net prize amount after fees

tierFeeAmount

number

Fee amount for this tier

tierTotalAmount

number

Total prize amount for this tier

User Leaderboard Field Descriptions:

Field
Type
Description

userId

string

UUID of the user

userName

string

Username

userMetadata

object

User metadata

userAvatarUrl

string

URL to user's avatar image

position

number

Calculated absolute leaderboard position based on score (see Position and Ranking)

positionOverride

number

Final position used for rewards (see Position and Ranking)

score

number

User's score

metadataString

string

JSON string for score-specific metadata

rewardTotalAmount

number

Total reward amount user will receive

rewardNetAmount

number

Net reward amount after fees

rewardFeeAmount

number

Fee amount deducted from reward

canSubmitNewScore

boolean

Whether user can submit additional score (see Replayable Tournaments)

Update Tournament

Modify tournament properties before or during the event.

Path Parameters:

  • matchupId (string, required) - UUID of the tournament

Request Body:

Modifiable Fields:

Field
Type
Description

title

string

Tournament name

description

string

Tournament description

type

string

CASH_FIXED or CASH_PERCENTAGE

buyInAmount

number

Entry fee per participant

paymentStructure

array

Prize distribution by position

maxParticipants

number

Maximum participants

minPayoutAmount

number

Minimum guaranteed prize pool

fee

number

Platform fee percentage

scoringType

string

HIGHEST_SCORE or LOWEST_SCORE

gameId

string

External game identifier

locationIds

array

Array of location UUIDs

startsAt

string

ISO 8601 start timestamp

expiresAt

string

ISO 8601 expiration timestamp

isPublic

boolean

Whether tournament is publicly visible

visibilityLevel

string

Visibility level: PUBLIC, PRIVATE_HIDDEN, or PRIVATE_VIEWABLE

privateCode

string

Private access code for joining tournament

omitAttemptCompletedCheck

boolean

Allow users to replay without finishing previous attempt (see Replayable Tournaments)

overrideImageUrl

string

Custom image URL for tournament banner

maxAttempts

number

Maximum number of attempts allowed per user (see Replayable Tournaments)

metadataString

string

JSON string for custom metadata

Note: Some fields may have restrictions based on tournament status.

Update User Scores

Update participant scores during the tournament. This endpoint requires Lucra users and matchups ID tracking. If you want to submit scores by metadata matching, user's phone number and more see Tournament Metadata Matching section.

Path Parameters:

  • matchupId (string, required) - UUID of the tournament

Request Body:

Field Descriptions:

Field
Type
Required
Description

userId

string

Yes

UUID of participant

score

number

Yes

Participant's score

metadataString

string

No

JSON string for score metadata

attemptFinished

boolean

No

If true, prevents further score updates for this attempt (see Replayable Tournaments)

Notes:

  • Users can only submit new scores when canSubmitNewScore is true

  • Setting attemptFinished: true locks the score for that round

  • Rankings update automatically based on scoringType

Complete Tournament

Finalize tournament and distribute payouts.

Path Parameters:

  • matchupId (string, required) - UUID of the tournament

Request Body:

Notes:

  • userId in payment structure specifies reward recipients

  • Completing tournament triggers payout distribution

  • Tournament status changes to CLOSED

  • Triggers TournamentCompleted webhook event

Cancel Tournament

Cancel a tournament and refund participants.

Path Parameters:

  • matchupId (string, required) - UUID of the tournament

Response:

Notes:

  • Refunds all participant entry fees

  • Tournament status changes to CANCELED

  • Triggers TournamentCanceled webhook event

Query Active Tournaments

List active tournaments with optional filtering.

Query Parameters:

Parameter
Type
Description

limit

number

Maximum records to return

offset

number

Number of records to skip (pagination)

locationId

string

Filter by location UUID

userId

string

Return only tournaments with this user (excludes closed tournaments)

Example Request:

Response:

Tournament Lifecycle

Scoring Types

  • HIGHEST_SCORE: Higher scores rank better (e.g., points-based games)

  • LOWEST_SCORE: Lower scores rank better (e.g., golf, racing)

Error Handling

Status
Meaning

200

Success

400

Bad Request - Invalid parameters or validation error

401

Unauthorized - Invalid or missing API key

404

Not Found - Tournament does not exist

500

Internal Server Error

Best Practices

Payment Structure Validation

Ensure payment structure positions are sequential and values sum appropriately:

Score Update Batching

Batch score updates when possible to reduce API calls:

Metadata Usage

Use metadataString for custom tracking needs:

Metadata can be further used when searching tournaments or updating scores without the need to track Lucra matchup IDs. See more here

Last updated