Documentation
¶
Overview ¶
Package goalapi is the Go client for the GOAL API: football fixtures, live scores, standings, player stats and odds. Standard library only.
https://goal-api.com/documentation
client, err := goalapi.New(os.Getenv("GOAL_API_KEY"))
if err != nil {
log.Fatal(err)
}
page, err := client.Fixtures.Live(ctx, nil)
Index ¶
- Constants
- Variables
- func AuthMessageWithToken(token string) map[string]any
- func CSV(values ...string) string
- func ListSubscriptionsMessage() map[string]any
- func PingMessage() map[string]any
- func StatusMessage() map[string]any
- func SubscribeMessage(matchID string) map[string]any
- func UnsubscribeMessage(matchID string) map[string]any
- func VerifyWebhook(payload []byte, signatureHeader, secret string, tolerance time.Duration) (json.RawMessage, error)
- type Client
- func (c *Client) AuthMessage() map[string]any
- func (c *Client) BaseURL() string
- func (c *Client) CollectInto(ctx context.Context, fetch PageFunc, opts *PaginateOptions, dst any) error
- func (c *Client) CollectRows(ctx context.Context, fetch PageFunc, opts *PaginateOptions) ([]map[string]any, error)
- func (c *Client) Get(ctx context.Context, path string, params Params, out any) error
- func (c *Client) Live(opts ...LiveOption) *LiveClient
- func (c *Client) MintConnectToken(ctx context.Context) (*ConnectToken, error)
- func (c *Client) Paginate(fetch PageFunc, opts *PaginateOptions) *Paginator
- func (c *Client) Post(ctx context.Context, path string, body any, out any) error
- func (c *Client) RateLimit() RateLimit
- func (c *Client) WebSocketHeader() http.Header
- func (c *Client) WebSocketURL() string
- type CoachesService
- func (s *CoachesService) ByCountry(ctx context.Context, country string, params Params) (*Page, error)
- func (s *CoachesService) ByTeam(ctx context.Context, teamID string) (*Page, error)
- func (s *CoachesService) Get(ctx context.Context, coachID string) (*Item, error)
- func (s *CoachesService) List(ctx context.Context, params Params) (*Page, error)
- func (s *CoachesService) Search(ctx context.Context, query string, params Params) (*Page, error)
- type ConnectToken
- type CountriesService
- type Error
- type FixturesService
- func (s *FixturesService) ByDate(ctx context.Context, date string, params Params) (*Page, error)
- func (s *FixturesService) Cards(ctx context.Context, fixtureID string) (*Page, error)
- func (s *FixturesService) Commentary(ctx context.Context, fixtureID string) (*Page, error)
- func (s *FixturesService) Events(ctx context.Context, fixtureID string) (*Page, error)
- func (s *FixturesService) Get(ctx context.Context, fixtureID string) (*Item, error)
- func (s *FixturesService) Lineups(ctx context.Context, fixtureID string) (*Item, error)
- func (s *FixturesService) List(ctx context.Context, params Params) (*Page, error)
- func (s *FixturesService) Live(ctx context.Context, params Params) (*Page, error)
- func (s *FixturesService) LiveOdds(ctx context.Context, fixtureID string) (*Page, error)
- func (s *FixturesService) Odds(ctx context.Context, fixtureID string) (*Page, error)
- func (s *FixturesService) Predictions(ctx context.Context, fixtureID string) (*Item, error)
- func (s *FixturesService) Statistics(ctx context.Context, fixtureID string, params Params) (*Item, error)
- func (s *FixturesService) Substitutions(ctx context.Context, fixtureID string) (*Page, error)
- type H2HService
- type Item
- type LeaguesService
- func (s *LeaguesService) Fixtures(ctx context.Context, leagueID string, params Params) (*Page, error)
- func (s *LeaguesService) Get(ctx context.Context, leagueID string) (*Item, error)
- func (s *LeaguesService) List(ctx context.Context, params Params) (*Page, error)
- func (s *LeaguesService) Results(ctx context.Context, leagueID string, params Params) (*Page, error)
- func (s *LeaguesService) Standings(ctx context.Context, leagueID string, params Params) (*Page, error)
- func (s *LeaguesService) Teams(ctx context.Context, leagueID string, params Params) (*Page, error)
- func (s *LeaguesService) TopScorers(ctx context.Context, leagueID string, params Params) (*Page, error)
- type LiveClient
- func (l *LiveClient) Close() error
- func (l *LiveClient) Connect(ctx context.Context) error
- func (l *LiveClient) Connected() bool
- func (l *LiveClient) ListSubscriptions() error
- func (l *LiveClient) Messages() <-chan LiveMessage
- func (l *LiveClient) On(event string, handler func(LiveMessage)) func()
- func (l *LiveClient) Ping() error
- func (l *LiveClient) RequestStatus() error
- func (l *LiveClient) Run(ctx context.Context) error
- func (l *LiveClient) Subscribe(matchID string) error
- func (l *LiveClient) Subscriptions() []string
- func (l *LiveClient) Unsubscribe(matchID string) error
- type LiveMessage
- type LiveOption
- func WithLiveAuthTimeout(d time.Duration) LiveOption
- func WithLiveAutoReconnect(enabled bool) LiveOption
- func WithLiveConnectToken(token string) LiveOption
- func WithLiveMaxReconnectAttempts(n int) LiveOption
- func WithLivePingInterval(d time.Duration) LiveOption
- func WithLiveQueueSize(n int) LiveOption
- func WithLiveReadTimeout(d time.Duration) LiveOption
- func WithLiveTLSConfig(cfg *tls.Config) LiveOption
- func WithLiveURL(rawURL string) LiveOption
- type OddsService
- type Option
- type Page
- type PageFunc
- type PaginateOptions
- type Pagination
- type Paginator
- type Params
- type PlayersService
- func (s *PlayersService) Compare(ctx context.Context, ids ...string) (*Page, error)
- func (s *PlayersService) Get(ctx context.Context, playerID string) (*Item, error)
- func (s *PlayersService) List(ctx context.Context, params Params) (*Page, error)
- func (s *PlayersService) Search(ctx context.Context, query string, params Params) (*Page, error)
- func (s *PlayersService) Statistics(ctx context.Context, playerID string, params Params) (*Item, error)
- func (s *PlayersService) Top(ctx context.Context, stat string, params Params) (*Page, error)
- type PredictionsService
- type RateLimit
- type Raw
- type ResultsService
- func (s *ResultsService) ByDate(ctx context.Context, date string) (*Page, error)
- func (s *ResultsService) ByLeague(ctx context.Context, leagueID string, params Params) (*Page, error)
- func (s *ResultsService) ByTeam(ctx context.Context, teamID string, params Params) (*Page, error)
- func (s *ResultsService) HighScoring(ctx context.Context, params Params) (*Page, error)
- func (s *ResultsService) List(ctx context.Context, params Params) (*Page, error)
- func (s *ResultsService) Stats(ctx context.Context, params Params) (*Item, error)
- func (s *ResultsService) Today(ctx context.Context) (*Page, error)
- func (s *ResultsService) Yesterday(ctx context.Context) (*Page, error)
- type StandingsService
- func (s *StandingsService) Away(ctx context.Context, leagueID string, params Params) (*Page, error)
- func (s *StandingsService) Form(ctx context.Context, leagueID string, params Params) (*Page, error)
- func (s *StandingsService) Get(ctx context.Context, leagueID string, params Params) (*Page, error)
- func (s *StandingsService) Home(ctx context.Context, leagueID string, params Params) (*Page, error)
- func (s *StandingsService) Team(ctx context.Context, leagueID, teamID string) (*Item, error)
- func (s *StandingsService) Zones(ctx context.Context, leagueID string, params Params) (*Item, error)
- type StatusService
- func (s *StatusService) Coverage(ctx context.Context) (Raw, error)
- func (s *StatusService) CoverageCountries(ctx context.Context) (Raw, error)
- func (s *StatusService) CoverageLeague(ctx context.Context, leagueID string) (Raw, error)
- func (s *StatusService) CoverageLeagues(ctx context.Context, params Params) (Raw, error)
- func (s *StatusService) Get(ctx context.Context) (Raw, error)
- type TeamsService
- func (s *TeamsService) Fixtures(ctx context.Context, teamID string, params Params) (*Page, error)
- func (s *TeamsService) Get(ctx context.Context, teamID string, params Params) (*Item, error)
- func (s *TeamsService) List(ctx context.Context, params Params) (*Page, error)
- func (s *TeamsService) Players(ctx context.Context, teamID string, params Params) (*Page, error)
- func (s *TeamsService) Results(ctx context.Context, teamID string, params Params) (*Page, error)
- func (s *TeamsService) Statistics(ctx context.Context, teamID string, params Params) (*Item, error)
- func (s *TeamsService) Upcoming(ctx context.Context, teamID string, params Params) (*Page, error)
- type VideosService
- func (s *VideosService) ByDate(ctx context.Context, date string, params Params) (*Page, error)
- func (s *VideosService) ByLeague(ctx context.Context, leagueID string, params Params) (*Page, error)
- func (s *VideosService) ByMatch(ctx context.Context, matchID string) (*Page, error)
- func (s *VideosService) List(ctx context.Context, params Params) (*Page, error)
- func (s *VideosService) Recent(ctx context.Context, params Params) (*Page, error)
Constants ¶
const ( // DefaultBaseURL is the production GOAL API endpoint. DefaultBaseURL = "https://api.goal-api.com/v1" // Version of this SDK, sent as part of the User-Agent. Version = "1.0.0" )
const ( LiveAuthSuccess = "auth_success" LiveMatchUpdate = "match_update" LivePong = "pong" LiveStatus = "status" LiveServerShutdown = "server_shutdown" LiveError = "error" LiveSubscribeResponse = "subscribe_response" LiveUnsubscribeResponse = "unsubscribe_response" LiveGetSubscriptionsResponse = "get_subscriptions_response" )
Server to client message types. Replies to client requests are named "<request>_response", so subscribe is answered with subscribe_response.
const ( LiveEventOpen = "open" LiveEventClose = "close" // LiveEventAny receives every message, whatever its type. LiveEventAny = "*" )
LiveEventOpen and LiveEventClose are emitted by the SDK rather than the server, so a caller can react to the transport itself. They are delivered to On handlers and to Messages like any other event.
const ( StatusScheduled = "SCHEDULED" StatusLive = "LIVE" StatusFinished = "FINISHED" StatusHalfTime = "HALF_TIME" StatusAfterET = "AFTER_ET" StatusAfterPen = "AFTER_PEN" StatusPostponed = "POSTPONED" StatusCancelled = "CANCELLED" StatusAwarded = "AWARDED" StatusAbandoned = "ABANDONED" StatusSuspended = "SUSPENDED" )
Values accepted by the "status" query param.
const ( PlayerTypeGoalkeepers = "Goalkeepers" PlayerTypeDefenders = "Defenders" PlayerTypeMidfielders = "Midfielders" PlayerTypeForwards = "Forwards" )
Values accepted by the "type" query param on player endpoints.
const ( StatGoals = "goals" StatAssists = "assists" StatYellowCards = "yellowCards" StatRedCards = "redCards" StatRating = "rating" StatMatchPlayed = "matchPlayed" StatMinutes = "minutes" StatSaves = "saves" StatTackles = "tackles" StatShotsTotal = "shotsTotal" StatKeyPasses = "keyPasses" StatPasses = "passes" StatInterceptions = "interceptions" StatDuelsWon = "duelsWon" StatDribbleSucc = "dribbleSucc" )
Values accepted as the stat path segment of /players/top/{stat}.
const ( HalfFull = "full" HalfFirst = "1half" HalfSecond = "2half" )
Values accepted by the "half" query param on fixture statistics.
const ( EventMatchStarted = "match.started" EventMatchFinished = "match.finished" EventGoalScored = "goal.scored" EventScoreChanged = "score.changed" EventMatchStatusChanged = "match.status_changed" )
Webhook event names.
const ( SignatureHeader = "X-Goal-Signature" EventHeader = "X-Goal-Event" DeliveryHeader = "X-Goal-Delivery" )
Headers on an inbound webhook delivery.
const DefaultWebhookTolerance = 5 * time.Minute
DefaultWebhookTolerance is how much clock skew / delivery latency is accepted before a delivery is treated as a replay.
Variables ¶
var ( ErrValidation = sentinel("validation failed") ErrAuthentication = sentinel("authentication failed") ErrPermission = sentinel("access denied") ErrPlanUpgradeRequired = sentinel("plan upgrade required") ErrNotFound = sentinel("not found") ErrConflict = sentinel("conflict") ErrRateLimited = sentinel("rate limited") ErrServer = sentinel("server error") ErrTimeout = sentinel("request timed out") ErrNetwork = sentinel("network error") )
Sentinels for errors.Is. See Error.Is for the mapping.
var ErrWebhookSignature = errors.New("goalapi: webhook signature verification failed")
ErrWebhookSignature wraps every verification failure, so callers can branch with errors.Is(err, goalapi.ErrWebhookSignature) and answer 400.
var MatchStatuses = []string{ StatusScheduled, StatusLive, StatusFinished, StatusHalfTime, StatusAfterET, StatusAfterPen, StatusPostponed, StatusCancelled, StatusAwarded, StatusAbandoned, StatusSuspended, }
MatchStatuses lists every value the "status" query param accepts.
var PlayerStats = []string{ StatGoals, StatAssists, StatYellowCards, StatRedCards, StatRating, StatMatchPlayed, StatMinutes, StatSaves, StatTackles, StatShotsTotal, StatKeyPasses, StatPasses, StatInterceptions, StatDuelsWon, StatDribbleSucc, }
PlayerStats lists every value /players/top/{stat} accepts.
var WebhookEvents = []string{ EventMatchStarted, EventMatchFinished, EventGoalScored, EventScoreChanged, EventMatchStatusChanged, }
WebhookEvents lists every event a webhook endpoint can subscribe to.
Functions ¶
func AuthMessageWithToken ¶
AuthMessageWithToken is the browser-side variant, using a token from MintConnectToken rather than the raw API key.
func ListSubscriptionsMessage ¶
ListSubscriptionsMessage asks the server which matches this connection is subscribed to.
func PingMessage ¶
PingMessage builds a keepalive frame. The server replies with a "pong".
func StatusMessage ¶
StatusMessage asks for the connection's plan, subscriptions and feature flags.
func SubscribeMessage ¶
SubscribeMessage builds the frame that subscribes to a match.
func UnsubscribeMessage ¶
UnsubscribeMessage builds the frame that unsubscribes from a match.
func VerifyWebhook ¶
func VerifyWebhook(payload []byte, signatureHeader, secret string, tolerance time.Duration) (json.RawMessage, error)
VerifyWebhook verifies an inbound webhook and returns the raw JSON body.
payload MUST be the exact request bytes, read before any JSON decoding. Re-encoding a decoded struct reorders keys and changes whitespace, which changes the HMAC and fails every time:
func handler(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(io.LimitReader(r.Body, 1<<20))
raw, err := goalapi.VerifyWebhook(body, r.Header.Get(goalapi.SignatureHeader), secret, 0)
if err != nil {
http.Error(w, "bad signature", http.StatusBadRequest)
return
}
// r.Header.Get(goalapi.EventHeader) tells you which event this is
}
tolerance of 0 uses DefaultWebhookTolerance. Negative disables the timestamp check, which is only sensible if you dedupe on X-Goal-Delivery yourself.
Types ¶
type Client ¶
type Client struct {
// Resource groups.
Status *StatusService
Countries *CountriesService
Leagues *LeaguesService
Teams *TeamsService
Fixtures *FixturesService
Standings *StandingsService
Players *PlayersService
Coaches *CoachesService
H2H *H2HService
Results *ResultsService
Videos *VideosService
Odds *OddsService
Predictions *PredictionsService
// contains filtered or unexported fields
}
Client is a GOAL API client, safe for concurrent use. Share one: the http.Client pools connections and the rate-limit snapshot is per-client.
func New ¶
New creates a client. Get an API key at https://goal-api.com/dashboard.
func (*Client) AuthMessage ¶
AuthMessage builds the frame that must be sent first on a new connection. Anything else first and the server closes with 4001.
func (*Client) CollectInto ¶
func (c *Client) CollectInto(ctx context.Context, fetch PageFunc, opts *PaginateOptions, dst any) error
CollectInto walks every page and decodes all rows into dst, a pointer to a slice.
var teams []Team err := client.CollectInto(ctx, fetch, nil, &teams)
func (*Client) CollectRows ¶
func (c *Client) CollectRows(ctx context.Context, fetch PageFunc, opts *PaginateOptions) ([]map[string]any, error)
CollectRows walks every page and returns generic maps. Fine for scripts; use CollectInto elsewhere.
func (*Client) Get ¶
Get decodes a raw GET into out, for endpoints not wrapped here yet. Prefer the service methods. out may be *Page, *Item, *Raw or your own type.
func (*Client) Live ¶
func (c *Client) Live(opts ...LiveOption) *LiveClient
Live creates a live feed client. Nothing connects until Connect is called.
func (*Client) MintConnectToken ¶
func (c *Client) MintConnectToken(ctx context.Context) (*ConnectToken, error)
MintConnectToken mints a token for a browser client.
Go servers can set the Authorization header, so they don't need this. Use it when your backend hands a token to a frontend, so the browser can connect to wss://.../ws?wsToken=<token> without seeing your API key. Single-use, consumed on first connect.
func (*Client) Paginate ¶
func (c *Client) Paginate(fetch PageFunc, opts *PaginateOptions) *Paginator
Paginate builds a Paginator. opts may be nil for the defaults.
func (*Client) Post ¶
Post performs a raw POST. Not retried: /ws/token is single-use, so a retry would burn the token the first attempt may already have minted.
func (*Client) RateLimit ¶
RateLimit returns quota from the last response. Zero until the first authenticated call.
func (*Client) WebSocketHeader ¶
WebSocketHeader returns the headers to send on the handshake. Pass it to your WebSocket library's dial options.
func (*Client) WebSocketURL ¶
WebSocketURL returns the live endpoint, derived from the client's base URL so a staging override carries over.
Note the path is /ws on the host root, not /v1/ws. nginx routes the socket with "location ^~ /ws", the only location carrying the Upgrade headers; /v1/ws falls into the REST location and silently answers 200 rather than upgrading.
type CoachesService ¶
type CoachesService struct {
// contains filtered or unexported fields
}
CoachesService covers /coaches.
type ConnectToken ¶
ConnectToken is a short-lived, single-use WebSocket handshake token.
type CountriesService ¶
type CountriesService struct {
// contains filtered or unexported fields
}
CountriesService covers /countries.
type Error ¶
type Error struct {
// StatusCode is the HTTP status, or 0 for a network/timeout failure.
StatusCode int
// Message comes from the response body, or from the SDK on a transport failure.
Message string
// Code is the API's machine-readable code, e.g. "VALIDATION_ERROR".
Code string
// Category groups the code, e.g. "validation", "not_found".
Category string
// Details is per-field validation info: an object from the gateway, an array from
// football-service.
Details json.RawMessage
// CorrelationID is set on gateway errors only, not on football-service ones.
CorrelationID string
// Timeout is true when the request exceeded the client timeout.
Timeout bool
// Network is true when no HTTP response was produced at all.
Network bool
// RetryAfter is the server-requested wait in seconds, set on 429.
RetryAfter int
// Limit, Remaining, Reset and RateLimitType mirror the X-RateLimit-* headers on a 429.
Limit int
Remaining int
Reset int64
RateLimitType string
// contains filtered or unexported fields
}
Error is the only error type this SDK returns. Branch on the class of failure with errors.Is against the sentinels below, and get at the fields with errors.As:
var apiErr *goalapi.Error
if errors.As(err, &apiErr) {
log.Printf("%s (correlation %s)", apiErr.Code, apiErr.CorrelationID)
}
type FixturesService ¶
type FixturesService struct {
// contains filtered or unexported fields
}
FixturesService covers /fixtures.
func (*FixturesService) Commentary ¶
func (*FixturesService) Odds ¶
Odds accepts a matchApiId as well as a fixture id, as do the three below.
func (*FixturesService) Predictions ¶
func (*FixturesService) Statistics ¶
func (s *FixturesService) Statistics(ctx context.Context, fixtureID string, params Params) (*Item, error)
Statistics takes an optional "half": HalfFull, HalfFirst or HalfSecond.
func (*FixturesService) Substitutions ¶
type H2HService ¶
type H2HService struct {
// contains filtered or unexported fields
}
H2HService covers /h2h. The two ids must differ, and 404 means the teams have never met.
type Item ¶
type Item struct {
Success bool `json:"success"`
Data json.RawMessage `json:"data"`
Source string `json:"source,omitempty"`
FixtureID string `json:"fixtureId,omitempty"`
MatchAPIID string `json:"matchApiId,omitempty"`
}
Item is a single-resource response.
type LeaguesService ¶
type LeaguesService struct {
// contains filtered or unexported fields
}
LeaguesService covers /leagues.
func (*LeaguesService) TopScorers ¶
type LiveClient ¶
type LiveClient struct {
// contains filtered or unexported fields
}
LiveClient is a connection to the live match feed.
It owns the socket, the auth handshake, keepalives and reconnection. Create one with Client.Live, register handlers, then Connect:
live := client.Live()
live.On(goalapi.LiveMatchUpdate, func(m goalapi.LiveMessage) {
var match Match
_ = m.Into(&match)
})
if err := live.Connect(ctx); err != nil {
return err
}
defer live.Close()
live.Subscribe(fixtureID)
live.Run(ctx)
Or skip handlers entirely and range over Messages, which is usually the more Go-shaped way to write it:
for msg := range live.Messages() {
if msg.Type == goalapi.LiveMatchUpdate {
// ...
}
}
Handlers run on the reader goroutine, one message at a time and in registration order. A handler that blocks stops the feed, so hand slow work to a goroutine of your own.
func (*LiveClient) Close ¶
func (l *LiveClient) Close() error
Close shuts the connection down and stops reconnecting. Safe to call more than once.
func (*LiveClient) Connect ¶
func (l *LiveClient) Connect(ctx context.Context) error
Connect dials, authenticates and starts the reader.
It returns once the server has accepted the auth frame, so a caller can Subscribe immediately afterwards. The ctx bounds the connect only; use Close or Run's ctx to stop the feed later.
func (*LiveClient) Connected ¶
func (l *LiveClient) Connected() bool
Connected reports whether the socket is up and authenticated.
func (*LiveClient) ListSubscriptions ¶
func (l *LiveClient) ListSubscriptions() error
ListSubscriptions asks the server what this connection is subscribed to. The answer arrives as a LiveGetSubscriptionsResponse message.
func (*LiveClient) Messages ¶
func (l *LiveClient) Messages() <-chan LiveMessage
Messages returns the message stream. It is closed when the client stops for good, so it is safe to range over.
func (*LiveClient) On ¶
func (l *LiveClient) On(event string, handler func(LiveMessage)) func()
On registers a handler and returns a function that removes it.
Event is a server message type such as LiveMatchUpdate, one of LiveEventOpen or LiveEventClose, or LiveEventAny for everything.
func (*LiveClient) Ping ¶
func (l *LiveClient) Ping() error
Ping sends a keepalive. The server answers with LivePong. The ping loop already does this on a timer.
func (*LiveClient) RequestStatus ¶
func (l *LiveClient) RequestStatus() error
RequestStatus asks for the connection's plan, subscriptions and feature flags. The answer arrives as a LiveStatus message.
func (*LiveClient) Run ¶
func (l *LiveClient) Run(ctx context.Context) error
Run blocks until the client stops, ctx is cancelled, or reconnection gives up.
It returns nil for a clean shutdown, ctx.Err() on cancellation, and the underlying failure otherwise.
func (*LiveClient) Subscribe ¶
func (l *LiveClient) Subscribe(matchID string) error
Subscribe asks for updates on a match.
The id is recorded before the frame goes out, so it survives a reconnect even if the write fails. The server caps concurrent subscriptions by plan and client messages at 60/minute.
func (*LiveClient) Subscriptions ¶
func (l *LiveClient) Subscriptions() []string
Subscriptions lists the matches this connection is subscribed to, sorted. They are replayed automatically after a reconnect.
func (*LiveClient) Unsubscribe ¶
func (l *LiveClient) Unsubscribe(matchID string) error
Unsubscribe stops updates for a match.
type LiveMessage ¶
type LiveMessage struct {
Type string `json:"type"`
Data json.RawMessage `json:"data,omitempty"`
Timestamp int64 `json:"timestamp,omitempty"`
Success *bool `json:"success,omitempty"`
// Set on an "error" frame.
Message string `json:"message,omitempty"`
Code string `json:"code,omitempty"`
}
LiveMessage is a frame from the live WebSocket.
func (*LiveMessage) Into ¶
func (m *LiveMessage) Into(dst any) error
Into decodes the Data payload into dst.
type LiveOption ¶
type LiveOption func(*LiveClient)
LiveOption configures a LiveClient.
func WithLiveAuthTimeout ¶
func WithLiveAuthTimeout(d time.Duration) LiveOption
WithLiveAuthTimeout bounds the wait for auth_success. Defaults to 10s.
func WithLiveAutoReconnect ¶
func WithLiveAutoReconnect(enabled bool) LiveOption
WithLiveAutoReconnect enables or disables reconnection. On by default.
func WithLiveConnectToken ¶
func WithLiveConnectToken(token string) LiveOption
WithLiveConnectToken authenticates with a token from MintConnectToken instead of the client's API key. Single-use, and consumed on first connect, so it cannot be replayed by the reconnect loop.
func WithLiveMaxReconnectAttempts ¶
func WithLiveMaxReconnectAttempts(n int) LiveOption
WithLiveMaxReconnectAttempts caps consecutive reconnects. Zero or less means unlimited, which is the default.
func WithLivePingInterval ¶
func WithLivePingInterval(d time.Duration) LiveOption
WithLivePingInterval sets the keepalive period. Defaults to 30s.
func WithLiveQueueSize ¶
func WithLiveQueueSize(n int) LiveOption
WithLiveQueueSize sets the Messages buffer. Defaults to 1000. When the buffer is full the oldest message is dropped, so a slow consumer degrades instead of stalling the feed.
func WithLiveReadTimeout ¶
func WithLiveReadTimeout(d time.Duration) LiveOption
WithLiveReadTimeout sets how long a silent connection is tolerated before it is treated as dead. Defaults to three ping intervals.
func WithLiveTLSConfig ¶
func WithLiveTLSConfig(cfg *tls.Config) LiveOption
WithLiveTLSConfig overrides the TLS settings used for wss connections.
func WithLiveURL ¶
func WithLiveURL(rawURL string) LiveOption
WithLiveURL overrides the derived WebSocket endpoint.
type OddsService ¶
type OddsService struct {
// contains filtered or unexported fields
}
OddsService covers /odds: "bookmaker", "matchId", "limit" (max 200, default 50), "offset".
type Option ¶
type Option func(*Client)
Option configures a Client.
func WithBaseURL ¶
WithBaseURL overrides the API endpoint, e.g. for staging.
func WithHTTPClient ¶
WithHTTPClient supplies your own *http.Client, for a custom transport or proxy. Its Timeout, if set, applies per attempt and overrides WithTimeout.
func WithHeader ¶
WithHeader adds a header to every request.
func WithMaxRetries ¶
WithMaxRetries sets retries for 429, 5xx and network errors. Default 2, zero to disable.
func WithTimeout ¶
WithTimeout sets the per-attempt timeout. Default 30s.
func WithUserAgent ¶
WithUserAgent overrides the User-Agent header.
type Page ¶
type Page struct {
Success bool `json:"success"`
Data json.RawMessage `json:"data"`
Pagination *Pagination `json:"pagination,omitempty"`
Source string `json:"source,omitempty"`
// Set on the betting endpoints (/fixtures/{id}/odds, /live-odds, /commentary).
FixtureID string `json:"fixtureId,omitempty"`
MatchAPIID string `json:"matchApiId,omitempty"`
Count int `json:"count,omitempty"`
}
Page is a collection response. Data stays json.RawMessage because rows are provider-shaped and change; decode into your own type:
var teams []Team
if err := page.Into(&teams); err != nil { ... }
type PageFunc ¶
PageFunc fetches one page. The paginator supplies limit and offset; merge in whatever else the endpoint needs:
func(ctx context.Context, p Params) (*Page, error) {
p["leagueId"] = leagueID
return client.Teams.List(ctx, p)
}
type PaginateOptions ¶
type PaginateOptions struct {
// PageSize defaults to 100, the limit ceiling on most endpoints. /results and
// /countries take 500.
PageSize int
// MaxItems caps the total rows returned. Zero means no cap.
MaxItems int
// StartOffset begins partway into the collection.
StartOffset int
}
PaginateOptions tunes a Paginator.
type Pagination ¶
type Pagination struct {
Total int `json:"total"`
Limit int `json:"limit"`
Offset int `json:"offset"`
HasMore bool `json:"hasMore"`
}
Pagination is the envelope's pagination block on list endpoints.
type Paginator ¶
type Paginator struct {
// contains filtered or unexported fields
}
Paginator walks every page of a list endpoint.
pager := client.Paginate(func(ctx context.Context, p Params) (*Page, error) {
return client.Leagues.Teams(ctx, leagueID, p)
}, nil)
for pager.Next(ctx) {
var team Team
if err := json.Unmarshal(pager.Row(), &team); err != nil { ... }
fmt.Println(team.Name)
}
if err := pager.Err(); err != nil { ... }
func (*Paginator) Next ¶
Next advances one row, fetching another page when the buffer empties. Returns false at the end or on the first error; check Err.
func (*Paginator) Page ¶
Page returns the envelope the current row came from, for Pagination.Total and Source.
func (*Paginator) Row ¶
func (p *Paginator) Row() json.RawMessage
Row returns the current row as raw JSON. Only valid after Next returned true.
type Params ¶
Params are query parameters. Nil and empty values are dropped, so you can build one unconditionally:
goalapi.Params{"leagueId": leagueID, "status": "SCHEDULED", "limit": 100}
Booleans go out as "true"/"false", which is what the validators check for. Slices are comma-joined, as /players/compare expects. Accepted keys: ENDPOINTS.md
type PlayersService ¶
type PlayersService struct {
// contains filtered or unexported fields
}
PlayersService covers /players.
func (*PlayersService) Statistics ¶
type PredictionsService ¶
type PredictionsService struct {
// contains filtered or unexported fields
}
PredictionsService covers /predictions: "matchId", "leagueName", "limit" (max 200, default 50), "offset".
type RateLimit ¶
type RateLimit struct {
// Limit is the plan's ceiling for the current window.
Limit int
// Remaining is how many calls are left in it.
Remaining int
// Reset is when the window rolls over, as unix seconds.
Reset int64
// Type is "DAILY" or "MONTHLY".
Type string
}
RateLimit is the quota reported by the last response.
type Raw ¶
type Raw json.RawMessage
Raw is a response body with no {success, data} envelope. The /public/* endpoints return bare objects, so Page or Item would invent a .data field that isn't there.
func (Raw) MarshalJSON ¶
MarshalJSON round-trips the original bytes.
func (*Raw) UnmarshalJSON ¶
UnmarshalJSON keeps the body verbatim.
type ResultsService ¶
type ResultsService struct {
// contains filtered or unexported fields
}
ResultsService covers /results. Its list endpoints take limit up to 500.
func (*ResultsService) HighScoring ¶
type StandingsService ¶
type StandingsService struct {
// contains filtered or unexported fields
}
StandingsService covers /standings. Every method takes an optional "stage".
Home and Away 404 for leagues where the provider has no home/away split, even when the base table has rows.
type StatusService ¶
type StatusService struct {
// contains filtered or unexported fields
}
StatusService covers the unauthenticated status and coverage endpoints, rate limited by IP rather than by key.
These return Raw, not Page or Item: /public/* answers with bare objects.
func (*StatusService) Coverage ¶
func (s *StatusService) Coverage(ctx context.Context) (Raw, error)
Coverage returns {leagues, countries, teams, players, fixtures, ...}.
func (*StatusService) CoverageCountries ¶
func (s *StatusService) CoverageCountries(ctx context.Context) (Raw, error)
CoverageCountries returns {countries[], total}.
func (*StatusService) CoverageLeague ¶
CoverageLeague returns a bare league object.
func (*StatusService) CoverageLeagues ¶
CoverageLeagues returns {leagues[], total, page, limit, pages}. Paginates with "page" and "limit", not "offset". Also accepts "q" and "country".
type TeamsService ¶
type TeamsService struct {
// contains filtered or unexported fields
}
TeamsService covers /teams.