@fieldfunded/sdk
v1.0.5
Published
Official TypeScript SDK for the FieldFunded Sports API — Real-time odds, scores, and settlements for 30+ sports & esports
Maintainers
Readme
@fieldfunded/sdk
Official TypeScript SDK for the FieldFunded Sports API — real-time odds, scores, and settlements for 30+ sports & esports.
Requirements
- Node.js 18+, Deno, Bun, or any modern browser with
fetch()support - No native dependencies — works in serverless environments (AWS Lambda, Vercel, Cloudflare Workers)
Features
- 25 typed methods covering every API endpoint
- Zero dependencies — uses native
fetch() - Full TypeScript support — intellisense, autocompletion, type safety
- Auto-retry on 429/500 errors with exponential backoff
- Dual-mode auth — works with RapidAPI or direct API keys
- Works everywhere — Node.js 18+, Deno, Bun, browsers
Install
npm install @fieldfunded/sdkQuick Start
import { FieldFundedSDK } from '@fieldfunded/sdk';
// RapidAPI mode (default)
const client = new FieldFundedSDK({
apiKey: 'YOUR_RAPIDAPI_KEY',
});
// Direct API mode
const client = new FieldFundedSDK({
apiKey: 'YOUR_API_KEY',
baseUrl: 'https://api.fieldfunded.com/v1',
});Usage Examples
List Sports & Leagues
const sports = await client.getSports();
console.log(sports.sports); // [{ key: 'soccer', name: 'Soccer', active_events: 142, is_esport: false }, ...]
const leagues = await client.getLeagues({ sport: 'soccer' });
console.log(leagues.leagues);
// [{ slug: 'premier-league', name: 'Premier League', country: 'England', active_events: 10, live_events: 3 }, ...]Get Events (with filters)
// All live soccer in England
const events = await client.getEvents({
sport: 'soccer',
country: 'england',
status: 'live',
});
// Games starting in the next 2 hours
const upcoming = await client.getEvents({
starts_within: '2h',
sport: 'basketball',
});
// Events on a specific date
const tomorrow = await client.getEvents({
date: '2026-04-16',
league: 'premier-league',
});
// American odds format
const events = await client.getEvents({
sport: 'soccer',
odds_format: 'american',
});Event Detail
const detail = await client.getEvent('12345678');
console.log(detail.markets); // Full markets array (1,000+ on major events)
console.log(detail.scoreboard); // Period/set/map scores
console.log(detail.sport_data); // Serving indicators, power play, etc.Live Scores (lightweight polling)
// Optimized endpoint — use for frequent polling
const scores = await client.getScores({ sport: 'soccer' });
for (const game of scores.scores) {
console.log(`${game.home_team} ${game.score.home}-${game.score.away} ${game.away_team}`);
}Search by Team Name
const results = await client.search('Barcelona', { limit: 5 });
console.log(results.events); // All upcoming/live Barcelona gamesBatch Events (max 20 IDs)
const batch = await client.getEventsBatch(['123', '456', '789']);
console.log(batch.events); // Record<id, EventDetail> — full detail for each found event
console.log(batch.found); // Number of events found (e.g. 2)
console.log(batch.requested); // Number of IDs you sent (e.g. 3)Bet Check
const result = await client.checkBet({
selections: [{
event_id: '123',
market: 'Match Winner',
outcome: 'Home',
odds: 1.85,
stake: 10, // currency-agnostic — any numeric amount
market_id: 340168, // primary — recommended for 100% accuracy
selection_id: 1824650, // primary — recommended for 100% accuracy
}],
});
console.log(result.results[0].result); // 'won' | 'lost' | 'refund' | 'pending'
console.log(result.results[0].payout); // 18.50 (when won, = stake × odds)Parlay / Accumulator Check
const parlay = await client.checkParlay({
legs: [
{ event_id: '123', market: 'Match Winner', outcome: 'Home', odds: 1.85, market_id: 340168, selection_id: 1824650 },
{ event_id: '456', market: 'Over/Under 2.5', outcome: 'Over', odds: 1.92 },
],
stake: 10,
});
console.log(parlay.payout.combined_odds);
console.log(parlay.payout.payout);Settlements & Results (Fully Automatic)
[!] Settlement is fully automatic. Markets resolve without developer intervention as soon as a game ends. No manual trigger needed — just call getSettlements() periodically (e.g. every 60 seconds) to retrieve the results.
[!] Poll getSettlements() regularly after the game ends to capture all market resolutions as they arrive gradually. Core markets settle in seconds; niche markets in minutes. Obscure leagues may take longer. For permanent score data, use getEventResult().
// Check settlements every 60 seconds (e.g. via setInterval or a scheduled task)
const settlements = await client.getSettlements({ limit: 10 });
for (const s of settlements.settlements) {
console.log(`${s.event_id}: ${s.settlement_status} — ${s.resolved_markets_count} markets resolved`);
}
// Get official result for a specific event (score-only, available automatically)
const result = await client.getEventResult('12345678');
console.log(`Status: ${result.status}`); // 'ended', 'walkover', 'retired', etc.
if (result.score) {
console.log(`Final Score: ${result.score.home}-${result.score.away}`);
}
// For market-level resolutions (won/lost/refund), use getSettlements()
const settlements = await client.getSettlements({ event_id: '12345678' });
// Outright/futures settlements (also automatic)
const outrightSettlements = await client.getOutrightSettlements({ sport: 'soccer' });Outrights / Futures
// List tournaments that have outright markets
const outrights = await client.getOutrights({ sport_id: '124' });
// Get selections and odds for a specific tournament (supports odds_format)
const detail = await client.getOutright('12345', { odds_format: 'american' });
console.log(detail.events[0].markets[0].selections[0].odds);Usage & Quota
const usage = await client.getUsage();
console.log(`${usage.current.this_month} / ${usage.limits.per_month} requests used`);
console.log(`${usage.current.month_remaining} remaining`);
// Per-endpoint breakdown
const endpoints = await client.getUsageEndpoints();
console.log(endpoints.endpoints); // [{ path: '/events', count: 142 }, { path: '/live', count: 58 }, ...]
// Active warnings
const warnings = await client.getUsageWarnings();
if (warnings.warnings.length > 0) {
console.warn('[!]', warnings.warnings[0].message);
}System Health (quota-free)
These endpoints do not count against your monthly quota. They have their own fixed rate limits: 2 req/s and 120 req/h, equal for all plans.
const ping = await client.ping(); // { pong: true, timestamp: 1234567890 }
const health = await client.health(); // System health, data freshness
const status = await client.status(); // Live/prematch countsError Handling
import {
FieldFundedSDK,
RateLimitError,
AuthenticationError,
NotFoundError,
BadRequestError,
ServiceUnavailableError,
} from '@fieldfunded/sdk';
try {
const events = await client.getEvents();
} catch (err) {
if (err instanceof RateLimitError) {
console.log(`Rate limited. Retry in ${err.retryAfter}s`);
} else if (err instanceof ServiceUnavailableError) {
console.log(`Service degraded (${err.component}). Retry in ${err.retryAfter}s`);
} else if (err instanceof AuthenticationError) {
console.log('Invalid API key');
} else if (err instanceof NotFoundError) {
console.log('Event not found');
} else if (err instanceof BadRequestError) {
console.log(`Invalid request: ${err.message}`);
}
}Configuration
const client = new FieldFundedSDK({
apiKey: 'YOUR_KEY', // Required
host: 'custom-host.com', // RapidAPI host (optional)
baseUrl: 'https://...', // Direct API URL (overrides host)
timeout: 20000, // Request timeout in ms (default: 20000)
retries: 2, // Retries on 429/500 (default: 1)
});
// Note: The default timeout is set to 20s to accommodate server-side index construction on high-volume endpoints (like /settlements). Most requests return in <200ms.All Methods
| Method | Endpoint | Description |
|--------|----------|-------------|
| ping() | GET /v1/ping | Latency check (quota-free) |
| health() | GET /v1/health | System health (quota-free) |
| status() | GET /v1/status | API status (quota-free) |
| getUsage() | GET /v1/usage | Quota & consumption stats |
| getUsageEndpoints() | GET /v1/usage/endpoints | Per-endpoint breakdown |
| getUsageWarnings() | GET /v1/usage/warnings | Active quota warnings |
| getSports() | GET /v1/sports | List sports |
| getLeagues(opts?) | GET /v1/leagues | List leagues with slugs |
| getMarkets(opts?) | GET /v1/markets | List market types |
| getEvents(opts?) | GET /v1/events | List events (all filters) |
| getLive(opts?) | GET /v1/live | Live events |
| getFeatured(opts?) | GET /v1/featured | Featured games (markets: true for full depth) |
| getScores(opts?) | GET /v1/scores | Live scores |
| search(q, opts?) | GET /v1/search | Search by team/league |
| getEvent(id, opts?) | GET /v1/events/{id} | Event detail |
| getEventOdds(id, opts?) | GET /v1/events/{id}/odds | Event odds |
| getEventResult(id) | GET /v1/events/{id}/result | Score result (automatic) |
| getEventsBatch(ids, opts?) | POST /v1/events/batch | Multiple events (max 20) |
| checkBet(req) | POST /v1/bets/check | Single bet check (automatic settlement) |
| checkParlay(req) | POST /v1/bets/check-parlay | Parlay check (automatic settlement) |
| getSettlements(opts?) | GET /v1/settlements | Automatic settlement feed |
| getOutrightSettlements(opts?) | GET /v1/settlements/outrights | Automatic outright settlements |
| getOutrights(opts?) | GET /v1/outrights | Outright markets |
| getOutrightSports() | GET /v1/outrights/sports | Outright sports |
| getOutright(id, opts?) | GET /v1/outrights/{id} | Specific outright with odds |
Resources
- Quickstart Guide — Get running in 5 minutes
- API Documentation — Full endpoint documentation
- Support: [email protected]
License
MIT
