Create a tournament
Check creator eligibility and fund the stage-1 buy-in on-chain before authoring a bracket tournament.
By the end: you'll know the paid create prerequisites — eligibility and vault deposit. Tournament authoring APIs are not published in these docs.
Prerequisites
tournamentsBaseUrlandtournamentsAuth(JWT from marketseoaLogin)- Markets-host JWT that can call
POST /bento/user/custodial/tournament-vault/deposit(managed smart wallet; rawsend-transactionwas removed) - Credits or USDC balance for the stage-1 buy-in (testnet: auto-mint faucet after register; register alone does not fund you)
- Tournament vault address for the chain (credits vault for
stakeAsset: 'credits')
Important: create is not a single POST
The host enforces a minimum stage-1 buy-in of 5 USDC or 5 credits. Free (buyinUsdc: '0') is rejected.
For any stage-1 buy-in greater than 0, create requires:
| Field | Meaning |
|---|---|
clientTournamentId | 24-character hex id you generate before create |
creatorDepositTxHash | Vault deposit tx for that id, stage 1, buy-in amount |
Skipping the vault step returns HTTP 400:
Paid tournaments require clientTournamentId … deposit to the vault … creatorDepositTxHash.
Check eligibility
import { createBentoSdk, jwtAuthProvider, walletAuthProvider } from '@bento.fun/sdk';
const token = process.env.BENTO_JWT!;
const sdk = createBentoSdk({
baseUrl: process.env.BENTO_URL!, // https://internal-server.bento.fun
apiKey: process.env.BENTO_BUILDER_API_KEY!,
tournamentsBaseUrl: process.env.PARLAY_TOURNAMENT_URL,
auth: walletAuthProvider(() => ({ Authorization: `Bearer ${token}` })),
tournamentsAuth: jwtAuthProvider({ getAccessToken: () => token }),
});
const stage1BuyinRaw = '5000000000000000000'; // 5 credits (18 decimals)
const eligibility = await sdk.tournaments!.tournaments.getCreatorCreateFlowEligibility({
wallet: managedWalletAddress,
stakeAsset: 'credits',
stage1BuyinRaw,
minEntriesToActivate: 2,
});
// Inspect eligibility.canProceed before fundingFund creator buy-in (on-chain)
import { tournamentMongoIdToBytes32 } from '@bento.fun/sdk';
const stage1BuyinRaw = '5000000000000000000'; // 5 units
// 12 random bytes as a 24-character hex id.
const clientTournamentId = Array.from(
crypto.getRandomValues(new Uint8Array(12)),
(b) => b.toString(16).padStart(2, '0'),
).join('');
const creditsVault = process.env.TOURNAMENT_VAULT_CREDITS!;
// Custodial path: approve (if needed) + TournamentVault.deposit in one call.
// Raw /user/wallet/send-transaction was removed in the audit hardening.
const depositRes = await fetch(
`${process.env.BENTO_URL}/bento/user/custodial/tournament-vault/deposit`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
'x-builder-api-key': process.env.BENTO_BUILDER_API_KEY!,
},
body: JSON.stringify({
vaultAddress: creditsVault,
tournamentIdBytes32: tournamentMongoIdToBytes32(clientTournamentId),
stageIndex: '1',
amountRaw: stage1BuyinRaw,
stakeAsset: 'credits',
}),
},
);
const { txHash: creatorDepositTxHash } = await depositRes.json();
// Keep clientTournamentId + creatorDepositTxHash for the authoring step.buyinUsdc is always the raw amount string (the field name is historical). Credits and BSC-testnet USDC use 18 decimals; Base USDC uses 6.
Participant flow
Once a tournament is live, other players use the Enter a tournament guide (depositAndEnterTournament, claims). That path deposits against an existing tournament id; creator create deposits before the tournament exists, using clientTournamentId.
Related
- Enter a tournament: player deposit, chip picks on matches, claims
- Authentication: Bearer JWT
- Common patterns: paid-create errors
- SDK API reference: public / user / tournaments methods