
Research
/Security News
npm Package Uses Prompt Injection and Token Flooding to Disrupt AI Malware Scanners
A new npm package tests AI malware scanners with prompt injection, safety-triggering comments, context flooding, and obfuscated JavaScript.
@bettoredge/api
Advanced tools
Typed API client for BettorEdge applications. This package provides a collection of typed API functions with full TypeScript support and automatic authentication management.
npm install @bettoredge/api
Call APIOverrides.start() once at app startup:
import { APIOverrides } from '@bettoredge/api';
// In your App.tsx or root component
useEffect(() => {
const initializeAPI = async () => {
const authState = await APIOverrides.start({
env: 'PRODUCTION', // or 'STAGING', 'DEVELOPMENT', 'PRODUCTION_PROXY'
no_cache: false // Set to true to skip loading cached tokens
});
if (authState.authenticated) {
console.log('User is already logged in!');
// You can now call authenticated endpoints
} else {
console.log('User needs to log in');
}
};
initializeAPI();
}, []);
If authState.authenticated is true, headers are already set:
import { getPlayerProfile } from '@bettoredge/api';
// Headers are set automatically - just call the endpoint
const profile = await getPlayerProfile();
console.log(profile.player.username);
If user is not authenticated, authenticate first:
import { authLogin, APIOverrides } from '@bettoredge/api';
// 1. Login using auth endpoint
const loginResponse = await authLogin(
{ attribute: 'email', verification_session: 'abc123' },
{ value: 'user@example.com', password: 'password123' }
);
// 2. Set up API client with the auth response
await APIOverrides.authenticateApp(loginResponse, { cache: true });
// 3. Now you can call authenticated endpoints
const profile = await getPlayerProfile();
import { APIOverrides } from '@bettoredge/api';
await APIOverrides.logoutApp(); // Clears all auth headers and cached tokens
This package uses a global axios instance with managed headers. Once you call APIOverrides.start() and authenticate, all API functions automatically include the correct headers:
Authorization: Bearer {token} - Set after authenticationx-api-key - Set automatically based on environmentdistinctid - Device/analytics tracking (persisted in AsyncStorage)sessionid - Session tracking (generated per app launch)You only need to authenticate once and all endpoints will work throughout your app.
These endpoints don't require a Bearer token - they're used to authenticate:
authCheck(request) - Check if user existsauthForgot(request) - Request password resetauthLogin(request, credentials) - Login with email/username/phonegetAuthStrategy(id) - Get registration strategyexecuteAuthStrategy(request) - Register new accountverifyAuthStrategy(request) - Verify registration codeauthenticatePhone(request) - Send phone verificationverifyPhone(request) - Verify phone codeThese endpoints require Bearer authentication:
getPlayerProfile()Get the current authenticated player's profile.
GET /player/mePromise<GetPlayerProfileResponse>
message (string): Success messageplayer (MyPlayerProps): Player profile dataplayer_premium_items (any[]): Array of premium itemsExample:
// Make sure you're authenticated first!
const profile = await getPlayerProfile();
console.log(profile.player.first_name);
console.log(profile.player.email_verified);
updatePlayerName(request)Update the current authenticated player's first and last name.
POST /player/name/updaterequest.first_name (string): New first namerequest.last_name (string): New last namePromise<UpdatePlayerNameResponse>
message (string): Success messageplayer (MyPlayerProps): Updated player profile dataExample:
// Update player name
const result = await updatePlayerName({
first_name: 'John',
last_name: 'Doe'
});
console.log(result.player.first_name); // 'John'
console.log(result.player.last_name); // 'Doe'
updatePlayerUsername(request)Update the current authenticated player's username.
POST /player/username/update{ username: string }Promise<UpdatePlayerUsernameResponse> with updated playerupdatePlayerEmail(request)Update the current authenticated player's email (requires confirmation).
POST /player/email/update{ email: string }Promise<UpdatePlayerEmailResponse> - pending verification messageconfirmPlayerEmailconfirmPlayerEmail(request)Confirm email update with verification token.
POST /player/email/confirm{ token: string }Promise<ConfirmPlayerEmailResponse> with updated playerupdatePlayerPhone(request)Update the current authenticated player's phone number (requires confirmation).
POST /player/phone/update{ phone: string }Promise<UpdatePlayerPhoneResponse> - pending verification messageconfirmPlayerPhoneconfirmPlayerPhone(request)Confirm phone update with verification token.
POST /player/phone/confirm{ token: string }Promise<ConfirmPlayerPhoneResponse> with updated playerupdatePlayerDOB(request)Update the current authenticated player's date of birth.
POST /player/dob/update{ dob: string }Promise<UpdatePlayerDOBResponse> with updated playerupdatePlayerPic(request)Update the current authenticated player's profile picture.
POST /player/pic/update{ profile_pic: string }Promise<UpdatePlayerPicResponse> with updated playercreatePlayerPassword(request)Create a password for the current authenticated player.
POST /player/password/create{ password: string, re_password: string, current_password: string }Promise<CreatePlayerPasswordResponse> with updated playerupdatePlayerPassword(request)Update the current authenticated player's password (requires confirmation).
POST /player/password/update{ password: string, re_password: string }Promise<UpdatePlayerPasswordResponse> - pending verification messageconfirmPlayerPasswordconfirmPlayerPassword(request)Confirm password update with verification token.
POST /player/password/confirm{ token: string }Promise<ConfirmPlayerPasswordResponse> with updated playergetPlayerBalance()Get the current authenticated player's balance.
GET /player/balance/mePromise<GetPlayerBalanceResponse> with balance dataExample:
const result = await getPlayerBalance();
console.log(result.player_balance.balance); // Current balance
console.log(result.player_balance.free_market_balance); // Free market balance
console.log(result.player_balance.promo_balance); // Promo balance
validatePlayerAttribute(request)Validate if a player attribute value is available (e.g., check if username or email is already taken).
POST /v1/players/player/attribute/validrequest.attribute (string): The attribute to check ('username', 'email', 'phone')request.attribute_value (string): The value to validatePromise<ValidatePlayerAttributeResponse>
message (string): Validation messagevalid (boolean): true if attribute is available, false if already takenExample:
// Check if username is available
const result = await validatePlayerAttribute({
attribute: 'username',
attribute_value: 'john_doe'
});
console.log(result.valid); // true if available, false if taken
// Check if email is available
const emailCheck = await validatePlayerAttribute({
attribute: 'email',
attribute_value: 'john@example.com'
});
getDiscordPlayer()Get the current authenticated player's Discord connection status.
GET /discord/mePromise<GetDiscordPlayerResponse> with Discord connection dataconnectDiscord()Start a Discord connection for the current authenticated player.
POST /discord/connectPromise<ConnectDiscordResponse> with auth codeconfirmDiscord()Confirm a Discord connection for the current authenticated player.
POST /discord/confirmPromise<ConfirmDiscordResponse> with updated connection datadisconnectDiscord()Disconnect Discord from the current authenticated player.
POST /discord/disconnectPromise<DisconnectDiscordResponse> with reset statusExample Discord Flow:
// 1. Start connection
const connectResult = await connectDiscord();
console.log(connectResult.discord_player.auth_code); // Show to user
// 2. User validates in Discord
// 3. Confirm connection
const confirmResult = await confirmDiscord();
console.log(confirmResult.discord_player.status); // 'active'
// 4. Check status anytime
const statusResult = await getDiscordPlayer();
console.log(statusResult.discord_player.discord_id);
// 5. Disconnect if needed
await disconnectDiscord();
These Discord endpoints use x-api-key authentication (automatically set by APIOverrides.start()):
getDiscordPlayerById(discord_id)Get Discord player by Discord ID.
GET /discord/id/:discord_iddiscord_id: stringPromise<GetDiscordPlayerByIdResponse> with Discord player datarefreshDiscordToken(discord_id)Refresh Discord token by Discord ID.
POST /discord/refresh/:discord_iddiscord_id: stringPromise<RefreshDiscordTokenResponse> with refreshed tokenvalidateDiscord(request)Validate Discord connection.
POST /discord/validate{ auth_code: string, discord_id: string, username: string, image: { url: string } }Promise<ValidateDiscordResponse> with validated connection dataExample:
// x-api-key is automatically set by start()
await APIOverrides.start({ env: 'PRODUCTION', no_cache: false });
// Get player by Discord ID
const player = await getDiscordPlayerById('123456789');
// Refresh token
const refreshed = await refreshDiscordToken('123456789');
// Validate connection
const validated = await validateDiscord({
auth_code: 'code',
discord_id: '123456789',
username: 'User#1234',
image: { url: 'https://...' }
});
saveFavorite(request)Save a favorite for the current authenticated player.
POST /favorites/favorite/save{ favorite_id: string, favorite_type: string }Promise<SaveFavoriteResponse> with saved favorite dataremoveFavorite(request)Remove a favorite for the current authenticated player.
POST /favorites/favorite/remove{ player_favorite_id: string }Promise<RemoveFavoriteResponse> with removed favorite datagetPlayerFavorites(favorite_type?, offset?)Get the current authenticated player's favorites.
GET /favorites/mefavorite_type?: string - Optional filter by favorite typeoffset?: number - Optional offset for pagination (default: 0)Promise<GetPlayerFavoritesResponse> with array of favoritesExample:
// Save a favorite
const saved = await saveFavorite({
favorite_id: 'game-uuid-123',
favorite_type: 'game'
});
// Get all favorites
const allFavorites = await getPlayerFavorites();
// Get favorites by type
const gameFavorites = await getPlayerFavorites('game');
// Get favorites with pagination
const paginated = await getPlayerFavorites('game', 20);
// Remove a favorite
await removeFavorite({
player_favorite_id: 'favorite-uuid-123'
});
These endpoints require Bearer token authentication. Ensure you're authenticated via APIOverrides.authenticateApp() before calling.
getMyCodeRequest()Get the current authenticated player's code request including promo, referral, and reward information.
GET /v1/promos/request/mePromise<GetMyCodeRequestResponse>
message (string): Success messagepromo (PromoProps | undefined): Promo details if availablecode_request (CodeRequestProps | undefined): Code request informationplayer_referral (PlayerReferralProps | undefined): Player referral detailsreferrer (PublicPlayerProps | undefined): Referrer player informationreward_option (RewardOptionProps | undefined): Reward option detailsExample:
// Get the authenticated player's code request
const result = await getMyCodeRequest();
console.log(result.message); // 'Successfully retrieved code request'
if (result.promo) {
console.log(result.promo.description);
console.log(result.promo.type); // 'referral_code' | 'promo_code' | etc.
}
if (result.code_request) {
console.log(result.code_request.referral_code);
console.log(result.code_request.status); // 'requested' | 'fulfilled' | etc.
}
if (result.referrer) {
console.log(result.referrer.username); // Username of the referrer
}
These endpoints require API key authentication (x-api-key header). The API key is automatically set when you call APIOverrides.start().
getAllMarkets(status?)Get all markets with optional status filter.
GET /v1/markets/allstatus (optional): Filter by status ('active' | 'inactive')Promise<GetAllMarketsResponse> with markets arrayExample:
// Get all markets
const result = await getAllMarkets();
console.log(result.markets);
// Get only active markets
const activeMarkets = await getAllMarkets('active');
console.log(activeMarkets.markets);
getAvailableMarkets(league_ids?)Get available markets with optional league filter.
GET /v1/markets/availableleague_ids (optional): Comma-separated league IDs to filter byPromise<GetAvailableMarketsResponse> with available marketsExample:
// Get all available markets
const result = await getAvailableMarkets();
console.log(result.available_markets);
// Get available markets for specific leagues
const leagueMarkets = await getAvailableMarkets('league-1,league-2');
console.log(leagueMarkets.available_markets);
getActiveEvents(league_id?, type?, expanded?)Get active events with optional filters.
GET /v1/events/activeleague_id (optional): Filter by league IDtype (optional): Filter by event typeexpanded (optional): Set to 'true' to return full event objects instead of just IDsPromise<GetActiveEventsResponse> with event IDs and optionally full eventsExample:
// Get all active event IDs
const result = await getActiveEvents();
console.log(result.event_ids);
// Get active events for a specific league
const leagueEvents = await getActiveEvents('league-123');
console.log(leagueEvents.event_ids);
// Get full event objects
const expandedEvents = await getActiveEvents(undefined, undefined, 'true');
console.log(expandedEvents.events);
searchEvents(request)Search for events by search value.
POST /v1/events/searchSearchEventsRequest object with:
search_value (required): Search term to find eventsPromise<SearchEventsResponse> with matching eventsExample:
// Search for events
const result = await searchEvents({
search_value: 'Lakers'
});
console.log(result.message); // 'Success'
console.log(result.events);
getActiveTournaments(league_id?, expanded?)Get active tournaments with optional filters.
GET /v1/tournaments/activeleague_id (optional): Filter by league IDexpanded (optional): Set to 'true' to return full tournament objects instead of just IDsPromise<GetActiveTournamentsResponse> with tournament IDs and optionally full tournamentsExample:
// Get all active tournament IDs
const result = await getActiveTournaments();
console.log(result.tournament_ids);
// Get active tournaments for a specific league
const leagueTournaments = await getActiveTournaments('league-123');
console.log(leagueTournaments.tournament_ids);
// Get full tournament objects
const expandedTournaments = await getActiveTournaments(undefined, 'true');
console.log(expandedTournaments.tournament_ids);
searchTournaments(request)Search for tournaments by search value.
POST /v1/tournaments/search/valueSearchTournamentsRequest object with:
search_value (required): Search term to find tournamentsoffset (optional): Offset for paginationPromise<SearchTournamentsResponse> with matching tournamentsExample:
// Search for tournaments
const result = await searchTournaments({
search_value: 'Masters'
});
console.log(result.message); // 'Successfully retrieved tournaments'
console.log(result.tournaments);
// Search with offset for pagination
const paginatedResult = await searchTournaments({
search_value: 'PGA',
offset: 10
});
console.log(paginatedResult.tournaments);
getTournamentById(tournament_id)Get tournament details by ID.
GET /v1/tournaments/tournament/:tournament_idtournament_id (required): Tournament IDPromise<GetTournamentByIdResponse> with tournament detailsExample:
// Get tournament by ID
const result = await getTournamentById('tournament-uuid-123');
console.log(result.message); // 'Successfully retrieved tournament'
console.log(result.tournament);
These endpoints provide detailed golf tournament data including leaderboards, scorecards, and statistics.
getGolfDetails(tournament_id, year?)Get golf tournament details including leaderboard, athletes, course info, and active round.
GET /v1/tournaments/golf/details/:tournament_idtournament_id (required): Tournament IDyear (optional): Year filter for historical dataPromise<GetGolfDetailsResponse> with:
message (string): Success messagegolf_leaders (GolfLeaderProps[]): Leaderboard entries with positions, scores, and round detailsathletes (AthleteProps[]): Athlete details for participantsgolf_course (GolfCourseProps): Course information including holes and paractive_round (number): Current active round numberExample:
// Get golf tournament details
const result = await getGolfDetails('tournament-uuid-123');
console.log(result.golf_leaders); // Leaderboard entries
console.log(result.athletes); // Athlete details
console.log(result.golf_course); // Course information
console.log(result.active_round); // Current round number
// Get golf details for a specific year
const historicResult = await getGolfDetails('tournament-uuid-123', '2024');
getGolfScorecard(tournament_id, athlete_id?, round_number?)Get golf scorecard for a specific athlete in a tournament round.
GET /v1/tournaments/golf/scorecard/:tournament_idtournament_id (required): Tournament IDathlete_id (optional): Athlete ID to filter scorecardround_number (optional): Round number to filter scorecardPromise<GetGolfScorecardResponse> with:
message (string): Success messagegolf_scorecards (GolfScorecardProps[]): Hole-by-hole scorecard dataExample:
// Get all scorecards for a tournament
const result = await getGolfScorecard('tournament-uuid-123');
console.log(result.golf_scorecards);
// Get scorecard for specific athlete and round
const athleteScorecard = await getGolfScorecard(
'tournament-uuid-123',
'athlete-uuid-456',
'2'
);
console.log(athleteScorecard.golf_scorecards);
getGolfStatistics(tournament_id)Get golf tournament statistics including hole-by-hole and round statistics.
GET /v1/tournaments/golf/statistics/:tournament_idtournament_id (required): Tournament IDPromise<GetGolfStatisticsResponse> with:
message (string): Success messagegolf_tournament_statistics (GolfTournamentStatisticsProps): Full statistics including round and hole dataprior_year (boolean): Whether stats are from prior yearExample:
// Get golf tournament statistics
const result = await getGolfStatistics('tournament-uuid-123');
console.log(result.golf_tournament_statistics); // Full statistics object
console.log(result.golf_tournament_statistics.round_statistics); // Round-by-round stats
console.log(result.prior_year); // Whether stats are from prior year
getActiveMatches()Get all active matches.
GET /v1/matches/activePromise<GetActiveMatchesResponse> with active matchesExample:
// Get all active matches
const result = await getActiveMatches();
console.log(result.message); // 'Successfully retrieved matches'
console.log(result.matches);
getMatchesByTournamentId(tournament_id)Get matches for a specific tournament.
GET /v1/matches/tournament/:tournament_idtournament_id (required): Tournament IDPromise<GetMatchesByTournamentIdResponse> with tournament and matchesExample:
// Get matches for a tournament
const result = await getMatchesByTournamentId('tournament-uuid-123');
console.log(result.message); // 'Successfully retrieved matches'
console.log(result.tournament);
console.log(result.matches);
getMatchById(match_id)Get match details by ID.
GET /v1/matches/match/:match_idmatch_id (required): Match IDPromise<GetMatchByIdResponse> with match detailsExample:
// Get match by ID
const result = await getMatchById('match-uuid-123');
console.log(result.message); // 'Successfully retrieved matches'
console.log(result.match);
getLeagues(status?)Get all leagues with optional status filter.
GET /v1/leagues/status (optional): Filter by status ('active' | 'inactive')Promise<GetLeaguesResponse> with leagues array and timestampExample:
// Get all leagues
const result = await getLeagues();
console.log(result.message); // 'Successfully retrieved leagues'
console.log(result.leagues);
console.log(result.timestamp);
// Get only active leagues
const activeLeagues = await getLeagues('active');
console.log(activeLeagues.leagues);
These endpoints require Bearer token authentication. You must call APIOverrides.authenticateApp() before using these endpoints.
placeOrder(request)Place an order in the market.
POST /v1/orders/order/placePlaceOrderRequest object with:
order_context_hash (required): Order context hash stringprice (required): Order price (number)amount (required): Order amount (number)market_type (required): Market type stringexpire_time (optional): Order expiration timekey (optional): Optional key stringPromise<PlaceOrderResponse> with order contextExample:
// Place an order
const orderContext = await placeOrder({
order_context_hash: 'context-hash-123',
price: 0.55,
amount: 100,
market_type: 'standard',
expire_time: '2024-12-31T23:59:59Z'
});
console.log(orderContext);
cancelOrder(request)Cancel a single order.
POST /v1/orders/order/cancelCancelOrderRequest object with:
order_id (required): Order ID to cancelPromise<CancelOrderResponse> with cancelled orderExample:
// Cancel an order
const result = await cancelOrder({
order_id: 'order-uuid-123'
});
console.log(result.message); // 'Successfully cancelled order'
console.log(result.order);
bulkCancelOrders(request)Cancel multiple orders in bulk.
POST /v1/orders/bulk/cancelBulkCancelOrderRequest object with:
order_ids (required): Array of order IDs to cancelPromise<BulkCancelOrderResponse> with cancelled orders arrayExample:
// Cancel multiple orders
const result = await bulkCancelOrders({
order_ids: ['order-uuid-1', 'order-uuid-2', 'order-uuid-3']
});
console.log(result.message); // 'Successfully cancelled order'
console.log(result.orders);
getH2HHistory(h2h_id)Get head-to-head order history.
GET /v1/orders/h2h/history/:h2h_idh2h_id (required): Head-to-head IDPromise<GetH2HHistoryResponse> with H2H order historyExample:
// Get H2H history
const result = await getH2HHistory('h2h-uuid-123');
console.log(result.message); // 'Successfully retrieved h2h stats'
console.log(result.orders);
acceptH2H(request)Accept a head-to-head request.
POST /v1/orders/h2h/acceptAcceptH2HRequest object with:
order_id (required): Order ID to acceptPromise<AcceptH2HResponse> with accepted orderExample:
// Accept H2H request
const result = await acceptH2H({
order_id: 'order-uuid-123'
});
console.log(result.message); // 'Successfully accepted h2h request'
console.log(result.order);
declineH2H(request)Decline a head-to-head request.
POST /v1/orders/h2h/declineDeclineH2HRequest object with:
order_id (required): Order ID to declinePromise<DeclineH2HResponse> with declined orderExample:
// Decline H2H request
const result = await declineH2H({
order_id: 'order-uuid-123'
});
console.log(result.message); // 'Successfully declined h2h request'
console.log(result.order);
getMyRebates()Get my collectable rebates.
GET /v1/orders/rebates/mePromise<GetMyRebatesResponse> with player commission rebates arrayExample:
// Get my rebates
const result = await getMyRebates();
console.log(result.message); // 'Successfully retrieved rebates'
console.log(result.player_commission_rebates);
collectRebate(request)Collect a rebate.
POST /v1/orders/rebate/collectCollectRebateRequest object with:
player_commission_rebate_id (required): Rebate ID to collectPromise<CollectRebateResponse> with collected rebateExample:
// Collect a rebate
const result = await collectRebate({
player_commission_rebate_id: 'rebate-uuid-123'
});
console.log(result.message); // 'Successfully collected rebate!'
console.log(result.player_commission_rebate);
getRebateById(player_commission_rebate_id)Get rebate by ID.
GET /v1/orders/rebate/:player_commission_rebate_idplayer_commission_rebate_id (required): Rebate IDPromise<GetRebateByIdResponse> with rebate detailsExample:
// Get rebate by ID
const result = await getRebateById('rebate-uuid-123');
console.log(result.message); // 'Successfully retrieved rebate'
console.log(result.player_commission_rebate);
These endpoints require admin role with Bearer token authentication:
generateFlashMarket(request)Generate a flash market preview using Claude AI.
POST /admin/flash-market/generateFlashMarketGenerateRequest object with:
prompt (required): Text prompt describing the market to generatepoll_campaign_id (required): Campaign ID to associate withnum_options (optional): Number of options to generateuse_web_search (optional): Whether to use web search for contextcontest_type (optional): Contest typecontest_id (optional): Contest IDbase_stake (optional): Base stake amountmin_stake (optional): Minimum stake amountmax_stake (optional): Maximum stake amountPromise<FlashMarketGenerateResponse>
message (string): Success messagepoll_campaign_id (string): Campaign IDpreview (FlashMarketPreview): Generated preview with question, options, reasoning, and sourcesExample:
const result = await generateFlashMarket({
prompt: 'Will the Lakers win tonight?',
poll_campaign_id: 'campaign-uuid-123',
num_options: 3,
use_web_search: true
});
console.log(result.preview.poll_question);
console.log(result.preview.poll_options);
console.log(result.preview.reasoning);
createFlashMarket(request)Create a flash market from reviewed preview data.
POST /admin/flash-market/createFlashMarketCreateRequest object with:
poll_campaign_id (required): Campaign ID to create the poll underpoll_question (required): The poll question textpoll_options (required): Array of 2-6 options, each with option_name, option_value, initial_odds, and priority. Odds must sum to 1.0contest_type (optional): Contest typecontest_id (optional): Contest IDbase_stake (optional): Base stake amount (default: 100)min_stake (optional): Minimum stake amount (default: 10)max_stake (optional): Maximum stake amount (default: 1000)Promise<FlashMarketCreateResponse>
message (string): Success messagepoll (PollProps): The created pollpoll_options (PollOptionProps[]): The created poll optionsExample:
const result = await createFlashMarket({
poll_campaign_id: 'campaign-uuid-123',
poll_question: 'Will the Lakers win tonight?',
poll_options: [
{ option_name: 'Yes', option_value: 'yes', initial_odds: 0.6, priority: 1 },
{ option_name: 'No', option_value: 'no', initial_odds: 0.4, priority: 2 }
],
min_stake: 10,
max_stake: 1000
});
console.log(result.poll);
console.log(result.poll_options);
These endpoints manage poll campaigns and polls. Most require Bearer token authentication.
getMyActiveCampaigns()Get the current admin's active campaigns.
GET /v1/polls/me/activePromise<GetMyActiveCampaignsResponse> with campaigns arrayExample:
const result = await getMyActiveCampaigns();
console.log(result.campaigns);
createCampaign(request)Create a new poll campaign.
POST /v1/polls/campaigns/campaign/createCreateCampaignRequest with:
name (required): Campaign namePromise<CreateCampaignResponse> with created campaignExample:
const result = await createCampaign({ name: 'My Flash Markets' });
console.log(result.campaign.poll_campaign_id);
getCampaignDetails(poll_campaign_id)Get campaign details by ID.
GET /v1/polls/campaigns/campaign/:poll_campaign_idpoll_campaign_id (required): Campaign IDPromise<GetCampaignDetailsResponse> with campaign detailsExample:
const result = await getCampaignDetails('campaign-uuid-123');
console.log(result.campaign);
getCampaignPolls(poll_campaign_id)Get all polls in a campaign.
GET /v1/polls/campaign/:poll_campaign_idpoll_campaign_id (required): Campaign IDPromise<GetCampaignPollsResponse> with polls arrayExample:
const result = await getCampaignPolls('campaign-uuid-123');
console.log(result.polls);
getPollDetails(poll_id)Get poll details with options.
GET /v1/polls/poll/:poll_idpoll_id (required): Poll IDPromise<GetPollDetailsResponse> with poll and poll_optionsExample:
const result = await getPollDetails('poll-uuid-123');
console.log(result.poll);
console.log(result.poll_options);
createPoll(request)Create a new poll in a campaign.
POST /v1/polls/poll/createCreatePollRequest with:
poll_campaign_id (required): Campaign IDpoll_question (required): Poll question textpoll_options (optional): Array of option previewspoll_type (optional): 'select' or 'input'minimum_stake, max_stake, base_stake (optional): Stake settingsPromise<CreatePollResponse> with created poll and optionsExample:
const result = await createPoll({
poll_campaign_id: 'campaign-uuid-123',
poll_question: 'Who will win?',
poll_options: [
{ option_name: 'Team A', option_value: 'team_a', initial_odds: 0.5, priority: 1 },
{ option_name: 'Team B', option_value: 'team_b', initial_odds: 0.5, priority: 2 }
]
});
updatePoll(request)Update an existing poll.
POST /v1/polls/poll/updateUpdatePollRequest with poll_id and fields to updatePromise<UpdatePollResponse> with updated pollactivatePoll(request)Activate a pending poll.
POST /v1/polls/poll/activateActivatePollRequest with poll_idPromise<ActivatePollResponse> with activated pollclosePoll(request)Close a poll, optionally selecting a winning option.
POST /v1/polls/poll/closeClosePollRequest with poll_id and optional winning_option_idPromise<ClosePollResponse> with closed pollvoidPoll(request)Void a poll.
POST /v1/polls/poll/voidVoidPollRequest with poll_id and optional void_reasonPromise<VoidPollResponse> with voided polldeletePoll(request)Delete a poll.
POST /v1/polls/poll/deleteDeletePollRequest with poll_idPromise<DeletePollResponse> with success messagecreatePollOption(request)Create a new option for a poll.
POST /v1/polls/poll/option/createCreatePollOptionRequest with poll_id, option_name, option_value, optional initial_odds and priorityPromise<CreatePollOptionResponse> with created optionupdatePollOption(request)Update an existing poll option.
POST /v1/polls/poll/option/updateUpdatePollOptionRequest with poll_option_id and fields to updatePromise<UpdatePollOptionResponse> with updated optionThese endpoints require admin role (player.role === 'admin'):
manualVouchPlayer(request)Manually vouch a player (Admin only).
POST /vouch/manual{ player_id: string }Promise<ManualVouchPlayerResponse> with updated playerExample:
// Admin user only
const result = await manualVouchPlayer({
player_id: 'player-uuid-123'
});
console.log(result.message); // 'Successfully vouched player'
reverifyVouchPlayer(request)Request reverification for a player's vouch status (Admin only).
POST /vouch/reverify{ player_id: string }Promise<ReverifyVouchPlayerResponse> with updated playerExample:
// Admin user only
const result = await reverifyVouchPlayer({
player_id: 'player-uuid-123'
});
console.log(result.message); // 'Successfully requested re-verification'
failVouchPlayer(request)Fail a player's vouch status (Admin only).
POST /vouch/fail{ player_id: string }Promise<FailVouchPlayerResponse> with updated playerExample:
// Admin user only
const result = await failVouchPlayer({
player_id: 'player-uuid-123'
});
console.log(result.message); // 'Successfully failed vouch'
resetVouchPlayer(request)Reset a player's vouch status (Admin only).
POST /vouch/reset{ player_id: string }Promise<ResetVouchPlayerResponse> with updated playerExample:
// Admin user only
const result = await resetVouchPlayer({
player_id: 'player-uuid-123'
});
console.log(result.message); // 'Successfully reset vouch status'
All types are imported from @bettorEdge/types:
import type { MyPlayerProps, PlayerBalanceProps, DiscordPlayerProps, PlayerFavoriteProps, MarketProps, MarketLiquidityProps, PlayerCommissionRebateProps, EventProps, TournamentProps, MatchProps, LeagueProps, AuthStateProps, GolfLeaderProps, GolfCourseProps, GolfScorecardProps, GolfTournamentStatisticsProps, AthleteProps, PollProps, PollOptionProps } from '@bettorEdge/types';
import type {
GetPlayerProfileResponse,
UpdatePlayerNameRequest,
UpdatePlayerNameResponse,
UpdatePlayerUsernameRequest,
UpdatePlayerUsernameResponse,
UpdatePlayerEmailRequest,
UpdatePlayerEmailResponse,
ConfirmPlayerEmailRequest,
ConfirmPlayerEmailResponse,
UpdatePlayerPhoneRequest,
UpdatePlayerPhoneResponse,
ConfirmPlayerPhoneRequest,
ConfirmPlayerPhoneResponse,
UpdatePlayerDOBRequest,
UpdatePlayerDOBResponse,
UpdatePlayerPicRequest,
UpdatePlayerPicResponse,
CreatePlayerPasswordRequest,
CreatePlayerPasswordResponse,
UpdatePlayerPasswordRequest,
UpdatePlayerPasswordResponse,
ConfirmPlayerPasswordRequest,
ConfirmPlayerPasswordResponse,
GetPlayerBalanceResponse,
GetDiscordPlayerResponse,
ConnectDiscordResponse,
ConfirmDiscordResponse,
DisconnectDiscordResponse,
GetDiscordPlayerByIdResponse,
RefreshDiscordTokenResponse,
ValidateDiscordRequest,
ValidateDiscordResponse,
ManualVouchPlayerRequest,
ManualVouchPlayerResponse,
ReverifyVouchPlayerRequest,
ReverifyVouchPlayerResponse,
FailVouchPlayerRequest,
FailVouchPlayerResponse,
ResetVouchPlayerRequest,
ResetVouchPlayerResponse,
SaveFavoriteRequest,
SaveFavoriteResponse,
RemoveFavoriteRequest,
RemoveFavoriteResponse,
GetPlayerFavoritesResponse,
GetAllMarketsResponse,
GetAvailableMarketsResponse,
PlaceOrderRequest,
PlaceOrderResponse,
CancelOrderRequest,
CancelOrderResponse,
BulkCancelOrderRequest,
BulkCancelOrderResponse,
GetH2HHistoryResponse,
AcceptH2HRequest,
AcceptH2HResponse,
DeclineH2HRequest,
DeclineH2HResponse,
GetMyRebatesResponse,
CollectRebateRequest,
CollectRebateResponse,
GetRebateByIdResponse,
GetActiveEventsResponse,
SearchEventsRequest,
SearchEventsResponse,
GetActiveTournamentsResponse,
SearchTournamentsRequest,
SearchTournamentsResponse,
GetTournamentByIdResponse,
GetActiveMatchesResponse,
GetMatchesByTournamentIdResponse,
GetMatchByIdResponse,
GetLeaguesResponse,
GetGolfDetailsResponse,
GetGolfScorecardResponse,
GetGolfStatisticsResponse,
FlashMarketOptionPreview,
FlashMarketPreview,
FlashMarketGenerateRequest,
FlashMarketGenerateResponse,
FlashMarketCreateRequest,
FlashMarketCreateResponse
} from '@bettoredge/api';
CompetitionsApi)getActivePublicCompetitions()Retrieves all active public competitions. Uses soft authentication to enrich with user data if authenticated.
GET /v2/competitions/public (TP_SVC_API)Promise<GetActivePublicCompetitionsResponse> with competitions arraygetActivePublicSeasons()Retrieves all active public competition seasons.
GET /v2/competitions/seasons/public (TP_SVC_API)Promise<GetActivePublicSeasonsResponse> with competition_seasons arraygetActivePublicSquares()Retrieves all active public squares competitions.
GET /v1/squares/public (TP_SVC_API)Promise<GetActivePublicSquaresResponse> with squares_competitions arraygetCompetitionOptions()Retrieves all available competition types, result types, and payout types.
GET /v1/competitions/options (TP_SVC_API)Promise<GetCompetitionOptionsResponse> with competition_types, competition_result_types, competition_payout_typesgetPrivateEngage(code)Searches for a private competition by invite code. Returns matching competition, bracket, squares, or season.
POST /v2/competitions/private (TP_SVC_API)code: stringPromise<GetPrivateEngageResponse> with optional competition, squares_competition, competition_season, bracket_competitionsearchCompanies(search_value, offset)Search for companies by name. Requires authentication.
POST /v1/companies/search (AUTH_SVC_API)search_value: string, offset: numberPromise<SearchCompaniesResponse> with companies arraygetCompaniesByIds(company_ids)Retrieves multiple companies by their IDs. Public endpoint.
POST /v1/companies/bulk/get (AUTH_SVC_API)company_ids: string[]Promise<GetCompaniesByIdsResponse> with companies arraygetPlayersByIds(player_ids)Retrieves multiple players by their IDs. Requires authentication.
POST /v1/players/bulk/get (AUTH_SVC_API)player_ids: string[]Promise<GetPlayersByIdsResponse> with players arraygetActivePublicCampaigns(offset?)Retrieves all active public poll/trivia campaigns with pagination.
GET /v1/polls/public/active (AUTH_SVC_API)offset?: number (defaults to 0)Promise<GetActivePublicCampaignsResponse> with poll_campaigns arraygetBulkBrackets(bracket_ids)Retrieves multiple brackets by their IDs. Public endpoint.
POST /v1/brackets/bulk/get (EVENT_SVC_API)bracket_ids: string[]Promise<GetBulkBracketsResponse> with brackets arrayThe API client uses different base URLs based on the environment:
await APIOverrides.start({ env: 'PRODUCTION' }); // Production API
await APIOverrides.start({ env: 'STAGING' }); // Staging API
await APIOverrides.start({ env: 'DEVELOPMENT' }); // Local development
await APIOverrides.start({ env: 'PRODUCTION_PROXY' }); // Production via proxy
Tokens are automatically:
authenticateApp({ cache: true })start({ no_cache: false })logoutApp()All API functions throw errors that can be caught with try/catch:
try {
const profile = await getPlayerProfile();
} catch (error) {
if (error.response) {
// Server responded with error status
console.error('Status:', error.response.status);
console.error('Message:', error.response.data.message);
} else if (error.request) {
// Request made but no response received
console.error('No response received');
} else {
// Error setting up the request
console.error('Error:', error.message);
}
}
Problem: "Failed to fetch player profile" or 401 error
Solutions:
Did you call APIOverrides.start()?
await APIOverrides.start({ env: 'PRODUCTION', no_cache: false });
Did you authenticate after login?
const loginResponse = await authLogin(request, credentials);
await APIOverrides.authenticateApp(loginResponse, { cache: true });
Check if user is authenticated:
const authState = await APIOverrides.start({ env: 'PRODUCTION', no_cache: false });
if (!authState.authenticated) {
// User needs to log in
}
Problem: "Authentication session has expired"
Solution: The refresh token failed. User needs to log in again:
await APIOverrides.logoutApp(); // Clear old tokens
// Show login screen
Problem: API calls aren't including authentication headers
Solution: Make sure you call APIOverrides.start() at app initialization (not in component mount):
// β
Correct - in App.tsx or _layout.tsx
useEffect(() => {
APIOverrides.start({ env: 'PRODUCTION', no_cache: false });
}, []);
// β Wrong - in a screen component
useEffect(() => {
APIOverrides.start({ env: 'PRODUCTION', no_cache: false });
}, []); // This runs too late
Problem: User has to log in every time app restarts
Solution: Make sure you're caching tokens:
// When authenticating
await APIOverrides.authenticateApp(authResponse, { cache: true }); // β
cache: true
// When starting
await APIOverrides.start({ env: 'PRODUCTION', no_cache: false }); // β
no_cache: false
Problem: Getting 404 or connection errors
Solution: Check your environment setting:
// Make sure you're using the right environment
await APIOverrides.start({
env: 'PRODUCTION', // Not 'DEVELOPMENT' if you want prod
no_cache: false
});
CRITICAL INSTRUCTIONS FOR CLAUDE CODE:
When adding endpoints to this package, you MUST follow these steps exactly. You will be provided:
IMPORTANT: Before proceeding with implementation, you MUST ASK THE USER which file to add the endpoint to. Do NOT assume the file location based on the endpoint domain. Wait for explicit confirmation from the user.
Your responsibilities:
REQUIRED: You must do TWO things:
A) Read the route file to understand:
/player/balance/me)B) Check the routes/index.ts file for the prefix:
app.use('/v1/players', players)router.get('/player/balance/me')/v1/players/player/balance/mePath to check: /Users/jamesseils/Desktop/Desktop/BettorEdge/[service-name]/routes/index.ts
CRITICAL: You MUST check both files to get the complete endpoint URL
@bettorEdge/types - NEVER RECREATEπ¨π¨π¨ ABSOLUTE CRITICAL RULE - ZERO TOLERANCE π¨π¨π¨
NEVER EVER EVER CREATE AN INTERFACE IN THIS PACKAGE THAT REPRESENTS A DATABASE MODEL
YOU MUST:
@bettorEdge/types package at /Users/jamesseils/Desktop/bettordev/components/packages/types/src/player.types.ts@bettorEdge/types and use it[TypeName] does not exist in @bettorEdge/types"[server file path]"THIS MEANS:
MyPlayerProps in server response β Import from @bettorEdge/typesPlayerBalanceProps in server response β Check @bettorEdge/types, IF NOT THERE: STOP AND TELL USERGameProps in server response β Import from @bettorEdge/types@bettorEdge/typesWORKFLOW - YOU MUST FOLLOW THIS EXACTLY:
player_balance: PlayerBalanceProps)@bettorEdge/types/src/player.types.ts for that typePlayerBalanceProps which doesn't exist in @bettorEdge/types. I found it at [server path]. Please add it to @bettorEdge/types first."@bettorEdge/typesExample - CORRECT:
import type { MyPlayerProps } from '@bettorEdge/types';
export interface GetPlayerProfileResponse {
message: string;
player: MyPlayerProps; // β
Using existing type from @bettorEdge/types
player_premium_items: any[];
}
Example - ABSOLUTELY WRONG - NEVER DO THIS:
// βββ NEVER EVER DO THIS - ZERO TOLERANCE βββ
export interface PlayerBalanceProps {
player_balance_id: string;
player_id: string;
// ... ANY interface representing database data
}
// This is WRONG - Claude must NEVER create this
// Claude must STOP and ask the user to add it to @bettorEdge/types first
π¨ REQUIRED: ASK THE USER BEFORE PROCEEDING
Before implementing the endpoint, you MUST ask the user which file to use. Present them with options based on the endpoint domain, but wait for their explicit confirmation.
Example question to ask:
"I found the endpoint
POST /player/name/updatein the server file. This appears to be a player-related endpoint. Should I add this to:
src/players.ts(recommended for player endpoints)src/auth.ts(if auth-related)- A new file (please specify the name)
Which file should I use?"
Common file organization:
src/players.tssrc/games.ts (create if needed)src/bets.ts (create if needed)src/auth.ts (already exists)DO NOT proceed to Step 4 until the user confirms the file location.
Request Types:
@bettorEdge/types that the server uses?) exactly as the server defines themResponse Types:
@bettorEdge/types (e.g., MyPlayerProps, GameProps)Example:
import type { MyPlayerProps, BetProps } from '@bettorEdge/types';
// Request type - matching server exactly
export interface CreateBetRequest {
game_id: string;
amount: number;
bet_type: 'SPREAD' | 'MONEYLINE' | 'TOTAL';
selection?: string; // Optional on server = optional here
}
// Response type - using imported types from @bettorEdge/types
export interface CreateBetResponse {
message: string;
bet: BetProps; // β
Imported from @bettorEdge/types
player: MyPlayerProps; // β
Imported from @bettorEdge/types
}
Include comprehensive JSDoc with:
POST /v1/bets)Template:
/**
* [Brief description of what this endpoint does]
*
* **Authentication: [Required/Optional]** - [Specify type: Bearer token, API key, etc.]
*
* Endpoint: `[HTTP_METHOD] /path/to/endpoint`
*
* @param request - [Description of request parameters]
* @returns [Description of success response]
* @throws Error if [describe error conditions from server]
*
* @example
* ```typescript
* // [Show realistic usage example]
* const result = await yourEndpoint(request);
* console.log(result.data);
* ```
*/
Follow this exact pattern:
For Authenticated Endpoints:
export const yourEndpoint = async (
request: YourRequestType
): Promise<YourResponseType> => {
try {
const endpoints = APIOverrides.getEndpoints();
const AUTH_SVC_API = endpoints.AUTH_SVC_API as string;
// Uses global axios instance with Bearer token set by APIOverrides
const response = await axios.post<YourResponseType>(
`${AUTH_SVC_API}/your/endpoint/path`,
request
);
return response.data;
} catch (error: any) {
// Return structured error response if available
if (error.response?.data) {
throw new Error(error.response.data.message || 'Operation failed');
}
throw error;
}
};
For Unauthenticated Endpoints (like auth/login):
export const yourEndpoint = async (
request: YourRequestType
): Promise<YourResponseType> => {
try {
const endpoints = APIOverrides.getEndpoints();
const AUTH_SVC_API = endpoints.AUTH_SVC_API as string;
// No Bearer token needed for unauthenticated endpoints
const response = await axios.post<YourResponseType>(
`${AUTH_SVC_API}/your/endpoint/path`,
request
);
return response.data;
} catch (error: any) {
if (error.response?.data) {
throw new Error(error.response.data.message || 'Operation failed');
}
throw error;
}
};
Add your new function to src/index.ts:
// Your domain endpoints
export { yourFunction } from './your-domain';
export type { YourRequestType, YourResponseType } from './your-domain';
Add your endpoint to the "Available Endpoints" section:
For Authenticated Endpoints:
#### `yourEndpoint(request)`
[Brief description]
- **Endpoint**: `POST /your/endpoint/path`
- **Authentication**: Required
- **Returns**: `Promise<YourResponseType>`
- `field1` (type): Description
- `field2` (type): Description
**Example**:
\`\`\`typescript
const result = await yourEndpoint({ param: 'value' });
console.log(result.data);
\`\`\`
npm run build
npm run typescript
Ensure both commands complete without errors.
@bettorEdge/types for existing types - NEVER RECREATE@bettorEdge/typessrc/index.tsnpm run build and npm run typescript to verify# Type check
npm run typescript
# Build
npm run build
@bettorEdge/types: Shared type definitionsaxios: HTTP clientMIT
FAQs
Typed API client for BettorEdge applications
We found that @bettoredge/api demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
A new npm package tests AI malware scanners with prompt injection, safety-triggering comments, context flooding, and obfuscated JavaScript.

Product
Socket now detects supply chain risks in project manifests, starting with missing lockfiles that can make dependency installs non-reproducible.

Research
/Security News
The trojanized extensions use TinyGo-compiled WebAssembly and Solana transaction memos to resolve command-and-control infrastructure.