Skip to content
datasportsAPI

GoGo SDK

Plain structs, contexts and errors.Is.

Module github.com/datasportsapi/datasportsapi-go, package datasportsapi. Every call takes a context, every response is a typed struct, and errors match with errors.Is and errors.As like the rest of your code.

Package
github.com/datasportsapi/datasportsapi-go
Runs on
Go 1.23+ · context everywhere
Key
DATASPORTSAPI_API_KEY
Status
Not published yet
Install
$ go get github.com/datasportsapi/datasportsapi-go

The install line goes live with the first release; nothing is on a public registry yet. Everything on this page describes the client as it will ship.

  1. Install

    Add the module to your go.mod. The import path ends in -go; the package inside is plain datasportsapi.

    shell
    $ go get github.com/datasportsapi/datasportsapi-go
  2. Authenticate

    NewClient reads DATASPORTSAPI_API_KEY when no key option is given. WithAPIKey takes precedence when you load the key yourself.

    client.go
    import datasportsapi "github.com/datasportsapi/datasportsapi-go"
    
    client := datasportsapi.NewClient() // reads DATASPORTSAPI_API_KEY
    
    // or explicitly
    client = datasportsapi.NewClient(datasportsapi.WithAPIKey(key))
  3. First calls

    Path parameters are arguments after the context; query parameters ride in a typed Params struct, with Ptr for the optional ones. Each method returns the envelope as a struct.

    first_calls.go
    live, err := client.Livescores.List(ctx, &datasportsapi.LivescoresListParams{
        Sport: datasportsapi.Ptr("football"),
    })
    if err != nil {
        log.Fatal(err)
    }
    for _, f := range live.Data {
        fmt.Println(f.Home.Name, *f.HomeScore.Current, "-", *f.AwayScore.Current, f.Away.Name)
    }
    
    table, err := client.Leagues.Standings(ctx, 17, &datasportsapi.LeaguesStandingsParams{Season: 76986})
  4. Errors

    One sentinel per HTTP status for errors.Is, and an *APIError with Status, Code, Message and RetryAfter for errors.As. Switch on Code when one status covers several cases.

    errors.go
    _, err := client.Fixtures.WinProbability(ctx, 480112, nil)
    
    var apiErr *datasportsapi.APIError
    switch {
    case errors.Is(err, datasportsapi.ErrForbidden): // 403: endpoint_not_in_plan, history_not_in_plan, …
        showUpgradeHint()
    case errors.Is(err, datasportsapi.ErrNotFound): // 404: not_found, no_data, not_supported
        hidePanel()
    case errors.As(err, &apiErr):
        log.Printf("%d %s (retry in %ds)", apiErr.Status, apiErr.Code, apiErr.RetryAfter)
    }
    Go error type for each HTTP status, and the codes each status can carry
    StatusSentinel (errors.Is)error.code
    400ErrBadRequestbad_request
    401ErrUnauthorizedunauthorized
    403ErrForbiddenendpoint_not_in_planhistory_not_in_planws_not_availableorigin_not_allowedip_not_allowed
    404ErrNotFoundnot_foundno_datanot_supported
    429ErrTooManyRequestsrate_limitedquota_exceeded
    500ErrInternalinternal_error
    503ErrUnavailableupstream_unavailable
  5. Paging

    Paged endpoints get a …Pages method that returns a range-over-func iterator: each step yields a page and an error, and the loop ends after the last page.

    paging.go
    params := &datasportsapi.TeamsFixturesParams{Type: datasportsapi.Ptr("recent")}
    
    for page, err := range client.Teams.FixturesPages(ctx, 42, params) {
        if err != nil {
            log.Fatal(err)
        }
        archive(page.Data)
    }
  6. WebSocket stream

    Business

    client.Stream gets a single-use ticket on its own, subscribes, reconnects and replays missed frames, folding each delta into the fixtures it tracks. Frames arrive on a channel; cancel the context or call Close to stop.

    stream.go
    s, err := client.Stream(ctx, []string{"livescores", "fixture:480112"}, nil)
    if err != nil {
        log.Fatal(err)
    }
    defer s.Close()
    
    for frame := range s.Frames() {
        if d, ok := frame.Value.(*datasportsapi.WsDelta); ok {
            fmt.Println("delta", d.ID)
        }
        inPlay, _ := s.Fixtures("livescores") // merged state, any time
        _ = inPlay
    }

    Channels, frames and replay rules are in the WebSocket guide. Without a Business key the stream answers 403 ws_not_available.

  7. Options

    Functional options, all optional. 429 rate_limited and 503 are retried after Retry-After, twice by default; 429 quota_exceeded comes straight back as an error.

    options.go
    client := datasportsapi.NewClient(
        datasportsapi.WithAPIKey(key),                     // default: DATASPORTSAPI_API_KEY
        datasportsapi.WithBaseURL("https://api.datasportsapi.com"), // default: DATASPORTSAPI_BASE_URL
        datasportsapi.WithTimeout(30*time.Second),         // per attempt
        datasportsapi.WithMaxRetries(2),                   // rate_limited and 503 only
    )

    Base URL resolution: the option or flag first, then DATASPORTSAPI_BASE_URL, then https://api.datasportsapi.com.

From the endpoint pages

Every endpoint shows its Go call.

All endpoints

Other clients

Your key is one form away.

1,000 free requests a day during the beta. No card, no sales call.