Documentation Index Fetch the complete documentation index at: https://docs.fieldfunded.com/llms.txt
Use this file to discover all available pages before exploring further.
Build a Parlay Calculator with Real Odds
Most parlay calculators online use manual input — you type in odds by hand. This one pulls real live odds and lets users build parlays by clicking selections.
What You’ll Use
SDK Method Endpoint Purpose getEvents()GET /v1/eventsList events with main market odds getEvent()GET /v1/events/{id}Get all markets for an event checkParlay()POST /v1/bets/check-parlayValidate parlay and get combined odds
The Idea
User browses live/upcoming events
Clicks selections to add to a bet slip
App calculates combined odds in real-time
User enters stake → sees potential payout
Optional: verify with checkParlay() for settlement simulation
Step 1: Fetch Events with Odds
import { FieldFundedSDK } from '@fieldfunded/sdk' ;
const client = new FieldFundedSDK ({
apiKey: process . env . FIELDFUNDED_API_KEY ! ,
baseUrl: 'https://api.fieldfunded.com/v1' ,
});
// Fetch today's games with main market odds included
async function getTodaysGames ( sport : string ) {
const events = await client . getEvents ({
sport ,
status: 'prematch' ,
starts_within: '12h' ,
});
return events . events ;
}
Step 2: Build the Bet Slip (React)
interface Selection {
event_id : string ;
home_team : string ;
away_team : string ;
market : string ;
outcome : string ;
odds : number ;
market_id ?: number ;
selection_id ?: number ;
}
const [ slip , setSlip ] = useState < Selection []>([]);
const [ stake , setStake ] = useState < number >( 10 );
function addToSlip ( selection : Selection ) {
// Prevent same event twice
if ( slip . some ( s => s . event_id === selection . event_id )) return ;
setSlip ([ ... slip , selection ]);
}
function removeFromSlip ( eventId : string ) {
setSlip ( slip . filter ( s => s . event_id !== eventId ));
}
// Combined odds = product of all decimal odds
const combinedOdds = slip . reduce (( acc , s ) => acc * s . odds , 1 );
const potentialPayout = stake * combinedOdds ;
FieldFunded supports decimal, american, and fractional via the odds_format parameter:
// Fetch with specific format
const events = await client . getEvents ({
sport: 'soccer' ,
odds_format: 'american' , // or 'decimal' or 'fractional'
});
// Or convert client-side
function decimalToAmerican ( decimal : number ) : string {
if ( decimal >= 2.0 ) return `+ ${ Math . round (( decimal - 1 ) * 100 ) } ` ;
return `- ${ Math . round ( 100 / ( decimal - 1 )) } ` ;
}
function decimalToFractional ( decimal : number ) : string {
const fraction = decimal - 1 ;
// Simple approximation
const denominator = 100 ;
const numerator = Math . round ( fraction * denominator );
const gcd = ( a : number , b : number ) : number => b ? gcd ( b , a % b ) : a ;
const d = gcd ( numerator , denominator );
return ` ${ numerator / d } / ${ denominator / d } ` ;
}
Step 4: Validate with the API
Use checkParlay() to verify the parlay is valid and get the official combined odds:
async function validateParlay () {
const result = await client . checkParlay ({
legs: slip . map ( s => ({
event_id: s . event_id ,
market: s . market ,
outcome: s . outcome ,
odds: s . odds ,
market_id: s . market_id ,
selection_id: s . selection_id ,
})),
stake ,
});
console . log ( `Status: ${ result . payout . status } ` );
console . log ( `Combined odds: ${ result . payout . combined_odds } ` );
console . log ( `Potential payout: $ ${ result . payout . payout } ` );
// If any leg is voided, the API recalculates automatically
return result ;
}
Step 5: Display the Slip
< div className = "bet-slip" >
< h3 > Bet Slip ( { slip . length } selections) </ h3 >
{ slip . map ( s => (
< div key = { s . event_id } className = "slip-item" >
< span > { s . home_team } vs { s . away_team } </ span >
< span > { s . market } : { s . outcome } @ { s . odds . toFixed ( 2 ) } </ span >
< button onClick = { () => removeFromSlip ( s . event_id ) } > × </ button >
</ div >
)) }
< div className = "slip-summary" >
< div > Combined Odds: { combinedOdds . toFixed ( 2 ) } </ div >
< input
type = "number"
value = { stake }
onChange = { e => setStake ( Number ( e . target . value )) }
placeholder = "Stake"
/>
< div className = "payout" >
Potential Payout: < strong > $ { potentialPayout . toFixed ( 2 ) } </ strong >
</ div >
</ div >
</ div >
Rate Limit Math
Browsing events: 1 request per sport/filter
Loading event detail: 1 request per event clicked
Validating parlay: 1 request per validation
Typical session: 5-10 requests
Free tier (10K/month) supports ~1,000 user sessions
Check Parlay Reference See parlay endpoint docs →
Events Reference See event filters and odds_format →
Get Your Free API Key Start building in 5 minutes — 10,000 free requests/month