BentoSDK

Common patterns & pitfalls

Practical tips for integrating @bento.fun/sdk — IDs, response shapes, auth, and errors.

Answers to questions that come up often when wiring the SDK against live APIs.

Two hosts, one factory

const sdk = createBentoSdk({
  baseUrl: process.env.BENTO_URL!,
  tournamentsBaseUrl: process.env.PARLAY_TOURNMENT_URL,
  auth: walletAuthProvider(() => ({ /* x-wallet-* */ })),
  tournamentsAuth: jwtAuthProvider({ getAccessToken: () => token }),
});
ClientHost envTypical auth
sdk.public / sdk.userBENTO_URLWallet headers on user
sdk.tournamentsPARLAY_TOURNMENT_URLJWT on tournamentsAuth

See Two API hosts.

id vs duelId on market rows

listDuels / listMarkets return rows with two identifiers:

FieldExampleUse for
id6a1ef4329676cfd69ceec4f0Database row id — do not pass to getDuelById
duelId94c88855f750…On-chain duel id — use this for detail, bets, charts
const { data } = await sdk.public.listDuels({ page: 1, limit: 10 });
const row = data[0];

// ✓ Correct
await sdk.public.getDuelById({ duelId: row.duelId });

// ✗ 404 — wrong id type
await sdk.public.getDuelById({ duelId: row.id });

Wrapped API responses

Some tournaments endpoints return objects, not bare arrays:

// Parlay markets
const { markets } = await sdk.tournaments!.parlay.listMarkets() as {
  markets: unknown[];
};

// Bracket tournaments list
const { tournaments, total } = await sdk.tournaments!.tournaments.list({
  status: 'active',
}) as { tournaments: unknown[]; total: number };

Check the Tournaments OpenAPI schema when typing responses.

HTTP acceptance ≠ on-chain finality

placeBet, sellBet, createDuel, pack picks, and tournament enters return when the server accepted the request — not when the chain finalized.

After mutations:

  1. Poll reads (getDuelById, getUserShares, tournament status)
  2. Use waitFor* helpers where provided
  3. Subscribe via sdk.realtime or tournament chat/Ably

See Mutation semantics.

Auth providers by integration

Your appProviderPass as
Browser walletwalletAuthProviderauth
JWT session (tournaments)jwtAuthProvidertournamentsAuth
Bulk user registrationbulkRegisterAuthProvider(apiKey)auth on user.bulkRegister
Agent v1 APIagentV1AuthProvidertournamentsAuth or client headers
External agent APIexternalAgentAuthProvidertournamentsAuth

See Authentication.

Idempotency for bets

Always pass an idempotency key when placing bets:

await sdk.user.placeBet(
  { duelId, option: 'YES', amount: '10' },
  { idempotencyKey: `bet-${duelId}-${Date.now()}` },
);

Errors

Failed HTTP calls throw BentoSdkErrorException with error.sdkError:

import { isGeoblockError } from '@bento.fun/sdk';

try {
  await sdk.user.placeBet(/* … */);
} catch (error) {
  if (isGeoblockError(error)) {
    // show geo-blocked UI
  }
  // error.sdkError.status, .message, .correlationId
}

Where to look next

NeedPage
Every SDK method + routeSDK API reference
JSON request/response shapesMarkets · Tournaments OpenAPI
Smoke-test published npm packageTest the SDK
End-to-end flowsQuickstart · Guides

On this page