A TypeScript wrapper for the Yahoo Fantasy Sports API with OAuth 1.0 and OAuth 2.0 support.
- TypeScript client for Yahoo Fantasy Sports
- OAuth 1.0 (public API) and OAuth 2.0 (user auth)
- Token refresh support for OAuth 2.0
- Resource clients: user, league, team, player, transaction, game
- Integration-tested against real Yahoo Fantasy leagues (primarily NHL)
- Transaction APIs are implemented but still experimental
npm install yfs-api
# or
yarn add yfs-api
# or
pnpm add yfs-api
# or
bun add yfs-apiUseful for public data like game info, player search, and league metadata:
import { YahooFantasyClient } from "yfs-api";
const client = new YahooFantasyClient({
clientId: process.env.YAHOO_CLIENT_ID!,
clientSecret: process.env.YAHOO_CLIENT_SECRET!,
publicMode: true, // OAuth 1.0 for public endpoints
});
// Get available games
const games = await client.game.getGames({ isAvailable: true });
// Search for players
const players = await client.game.searchPlayers("nhl", {
search: "mcdavid",
count: 10,
});
console.log(`Found ${players.length} players`);For accessing user-specific data (teams, leagues, rosters):
import { YahooFantasyClient } from "yfs-api";
const client = new YahooFantasyClient({
clientId: process.env.YAHOO_CLIENT_ID!,
clientSecret: process.env.YAHOO_CLIENT_SECRET!,
redirectUri: "oob", // or your callback URL
});
// Step 1: Get authorization URL
const authUrl = client.getAuthUrl();
console.log("Visit this URL to authorize:", authUrl);
// Step 2: After user authorizes, exchange code for tokens
await client.authenticate(authorizationCode);
// Step 3: Use authenticated endpoints
const user = await client.user.getCurrentUser();
const teams = await client.user.getTeams({ gameCode: "nhl" });
console.log(`Found ${teams.length} teams for user ${user.guid}`);
// Get league details
const league = await client.league.get(teams[0].league.leagueKey);
console.log(`League: ${league.name} (${league.season})`);
// Get team roster
const roster = await client.team.getRoster(teams[0].teamKey);
console.log(`Roster has ${roster.players.length} players`);
// Get league standings
const standings = await client.league.getStandings(league.leagueKey);
console.log(`${standings.length} teams in standings`);
// Search for players in league
const freeAgents = await client.player.search(league.leagueKey, {
status: "FA",
position: "C",
count: 25,
});Save and restore tokens between sessions:
import { YahooFantasyClient } from "yfs-api";
import * as fs from "fs/promises";
// Create token storage
const tokenStorage = {
save: async (tokens) => {
await fs.writeFile(".tokens.json", JSON.stringify(tokens));
},
load: async () => {
try {
const data = await fs.readFile(".tokens.json", "utf-8");
return JSON.parse(data);
} catch {
return null;
}
},
clear: async () => {
await fs.unlink(".tokens.json").catch(() => {});
},
};
const client = new YahooFantasyClient(
{
clientId: process.env.YAHOO_CLIENT_ID!,
clientSecret: process.env.YAHOO_CLIENT_SECRET!,
redirectUri: "oob",
},
tokenStorage
);
// Try to load existing tokens
await client.loadTokens();
// If no tokens, authenticate
if (!client.hasValidTokens()) {
const authUrl = client.getAuthUrl();
console.log("Visit:", authUrl);
// ... get authorization code ...
await client.authenticate(code);
}
// Tokens are automatically saved and refreshed
const teams = await client.user.getTeams({ gameCode: "nhl" });| Resource | Methods | Status |
|---|---|---|
| User | getCurrentUser, getGames, getTeams | Tested |
| League | get, getSettings, getStandings, getScoreboard, getTeams | Tested |
| Team | get, getRoster, getMatchups, getStats | Tested |
| Player | get, search, getStats, getOwnership | Tested |
| Game | get, getGames, searchPlayers, getPositionTypes, getStatCategories | Tested |
| Resource | Methods | Status |
|---|---|---|
| Transaction | addPlayer, dropPlayer, addDropPlayer, proposeTradeWithVote |
Transaction operations are implemented but have limited real-world testing so far. Use with caution and please report any issues.
| Sport | Status | Notes |
|---|---|---|
| π NHL | Primary focus | Actively tested with real leagues |
| π NBA | Basic support | Core endpoints have some coverage, not exhaustive |
| π NFL | Experimental | Likely to work; types may need refinement |
| βΎ MLB | Experimental | Likely to work; types may need refinement |
Feedback and contributions to improve support for any sport are welcome.
- Go to Yahoo Developer Network
- Create a new app
- Get your Client ID (Consumer Key) and Client Secret (Consumer Secret)
- Set your Redirect URI (use
oobfor out-of-band if testing locally)
Check out the /examples directory for complete working examples:
examples/hockey/01-authentication.ts- Traditional OAuth 2.0 flowexamples/hockey/02-client-test.ts- Testing API endpointsexamples/public-api/01-public-endpoints.ts- Public API without authexamples/token-storage/usage-example.ts- Token persistenceexamples/advanced-query/usage-examples.ts- Advanced query builder for complex requests
For complex API requests not covered by the standard methods, use the advanced query builder. Note: This API is experimental and may change before the 1.1.0 release:
import { YahooFantasyClient } from "yfs-api";
const client = new YahooFantasyClient({
clientId: process.env.YAHOO_CLIENT_ID!,
clientSecret: process.env.YAHOO_CLIENT_SECRET!,
redirectUri: "oob",
});
// Complex chain: User's NFL leagues with settings and standings
const result = await client.advanced()
.resource('users')
.param('use_login', '1')
.collection('games')
.param('game_keys', 'nfl')
.collection('leagues')
.out(['settings', 'standings'])
.execute();
// Team roster for specific week
const roster = await client.advanced()
.resource('team', '423.l.12345.t.1')
.collection('roster')
.param('week', '10')
.collection('players')
.execute();
// Available players with filters
const qbs = await client.advanced()
.resource('league', '423.l.12345')
.collection('players')
.params({
position: 'QB',
status: 'A',
sort: 'AR',
count: '25'
})
.execute();See Advanced Query README for comprehensive documentation.
- Integration Test Setup - Running integration tests
- OAuth 2.0 Implementation - OAuth details
- Advanced Query Implementation - Complex query builder documentation
- Bun v1.0.0 or later (for development)
- Node.js >= 18.0.0 (for runtime)
- Yahoo Developer Application credentials
# Install dependencies
bun install
# Run type checking
bun run type-check
# Run unit tests
bun test tests/unit
# Run integration tests (requires .env.test)
bun test tests/integration
# Lint and format
bun run lint
bun run format
# Build the project
bun run buildSee docs/INTEGRATION_TEST_SETUP.md for detailed setup instructions.
# 1. Copy environment template
cp .env.test.example .env.test
# 2. Add your credentials to .env.test
# 3. Discover your league and team keys
bun run scripts/discover-test-resources.ts
# 4. Run tests
source .env.test && bun test tests/integrationyfs-api/
βββ src/
β βββ client/ # OAuth clients and main client
β βββ resources/ # Resource-specific clients
β βββ types/ # TypeScript type definitions
β β βββ resources/ # Resource types (league, team, etc.)
β β βββ sports/ # Sport-specific types (NHL, etc.)
β β βββ common.ts # Common types
β β βββ errors.ts # Error types
β βββ utils/ # Utilities (validators, formatters)
βββ tests/
β βββ unit/ # Unit tests (301 passing)
β βββ integration/ # Integration tests (45 passing)
β βββ fixtures/ # Test fixtures and mock data
βββ examples/ # Usage examples
βββ docs/ # User documentation
βββ scripts/ # Development and discovery scripts
This library aims to be easy to understand and use while staying close to Yahoo's API. Over time the goal is to improve type safety, documentation, and examples as real-world usage surfaces gaps.
Contributions welcome! Please:
- Follow existing code patterns and style
- Add comprehensive JSDoc comments
- Include tests for new functionality
- Update documentation
- Test against real Yahoo Fantasy API when possible
If you have real-world usage that surfaces missing or incomplete types, contributions to improve type information are very welcomeβplease open an issue or pull request.
- Transaction APIs are experimental and untested
- NFL/MLB types may need refinement based on real usage
- Stat Categories are sport-specific and may vary
- League Settings support most options but some edge cases may exist
Please report issues or contribute improvements where you see gaps or rough edges.
MIT License - see LICENSE file for details
Built by jbru for the fantasy sports community πβΎππ
See CHANGELOG.md for release history.
Last Updated: 2025-11-24