Open Source · Go · REST API
go-fantasy-pl
A typed Go client for the Fantasy Premier League API. Fetch players, teams, fixtures, managers, and leagues — with built-in rate limiting, caching, and async helpers for concurrent workloads.
Go 1.21+
FPL API
Rate Limiting
In-Memory Cache
Redis Cache
Async / Concurrent
What you get
Typed Models
Strongly typed Go structs for all FPL responses — no more manual JSON wrestling.
Async Helpers
Fetch players, teams, and fixtures concurrently via channel-based helpers.
Rate Limiting
Built-in rate limiter to avoid hitting FPL API limits in high-frequency workloads.
Pluggable Cache
In-memory cache out of the box. Swap to Redis for shared cache across instances.
Full Coverage
Bootstrap, players, teams, fixtures, managers, leagues — the full FPL surface.
Simple Setup
One
NewClient() call and you're ready. Zero mandatory config.Usage
package main import ( "fmt" "log" "github.com/AbdoAnss/go-fantasy-pl/client" ) func main() { c, err := client.NewClient() if err != nil { log.Fatal(err) } teams, err := c.Teams.GetAllTeams() if err != nil { log.Fatal(err) } players, err := c.Players.GetAllPlayers() if err != nil { log.Fatal(err) } gw, err := c.Bootstrap.GetCurrentGameWeek() if err != nil { log.Fatal(err) } fmt.Printf("GW %d — teams: %d, players: %d\n", gw, len(teams), len(players)) }
package main import ( "context" "fmt" "log" "time" "github.com/AbdoAnss/go-fantasy-pl/client" ) func main() { c, err := client.NewClient() if err != nil { log.Fatal(err) } ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() // Launch all three fetches concurrently playersCh := c.Players.GetAllPlayersAsync(ctx) teamsCh := c.Teams.GetAllTeamsAsync(ctx) fixturesCh := c.Fixtures.GetAllFixturesAsync(ctx) players := <-playersCh teams := <-teamsCh fixtures := <-fixturesCh if players.Err != nil { log.Fatal(players.Err) } if teams.Err != nil { log.Fatal(teams.Err) } if fixtures.Err != nil { log.Fatal(fixtures.Err) } fmt.Printf("players: %d, teams: %d, fixtures: %d\n", len(players.Value), len(teams.Value), len(fixtures.Value)) }
package main import ( "context" "fmt" "log" "github.com/AbdoAnss/go-fantasy-pl/client" ) func main() { c, _ := client.NewClient() ctx := context.Background() // Fetch histories for multiple players concurrently ids := []int{1, 2, 3, 100, 200} results, err := c.Players.GetPlayerHistoriesBatch(ctx, ids) if err != nil { log.Fatal(err) } for id, history := range results { fmt.Printf("player %d — %d GW entries\n", id, len(history)) } }
API Reference
| Method | Description | Type |
|---|---|---|
| BootstrapGetTeams() | All teams in the current season (from bootstrap data) | sync |
| BootstrapGetPlayers() | All players in the current season (from bootstrap data) | sync |
| BootstrapGetGameWeeks() | All gameweeks / events in the current season | sync |
| BootstrapGetCurrentGameWeek() | Current gameweek ID | sync |
| BootstrapGetSettings() | Global FPL game settings | sync |
| PlayersGetAllPlayers() | All players in the current season | sync |
| PlayersGetPlayer(id) | One player by player ID | sync |
| PlayersGetPlayerHistory(id) | Detailed gameweek history for one player | sync |
| PlayersGetAllPlayersAsync(ctx) | All players via async channel result | async |
| PlayersGetPlayerHistoryAsync(ctx, id) | One player history via async channel result | async |
| PlayersGetPlayerHistoriesBatch(ctx, ids) | Multiple player histories concurrently | async |
| TeamsGetAllTeams() | All teams in the current season | sync |
| TeamsGetTeam(id) | One team by team ID | sync |
| TeamsGetAllTeamsAsync(ctx) | All teams via async channel result | async |
| FixturesGetAllFixtures() | All fixtures for the season | sync |
| FixturesGetFixture(id) | One fixture by fixture ID | sync |
| FixturesGetAllFixturesAsync(ctx) | All fixtures via async channel result | async |
| ManagersGetManager(id) | Manager profile by manager ID | sync |
| ManagersGetCurrentTeam(managerID) | Current gameweek picks for a manager | sync |
| ManagersGetManagerHistory(id) | Manager season history | sync |
| LeaguesGetClassicLeagueStandings(id, page) | Classic league standings for a page | sync |
| LeaguesGetTotalPages(league) | Compute total standings pages | sync |
Leagues.GetH2HLeague(id) exists in source as commented-out code and is not currently an active method.
Caching
In-Memory (default)
Zero-config TTL cache. Works out of the box for single-process use cases. Ideal for scripts, CLIs, and one-off data pulls.
Redis
Plug in a Redis backend to share cache across multiple instances. Useful for distributed services or repeated scheduled jobs.