Skip to content

newsdataapi/newsdata-go-client

Repository files navigation

Newsdata.io logo

Newsdata.io Go Client

Go Reference CI Go License OpenAPI

Official Go client for the Newsdata.io News API. Wraps every endpoint (latest, archive, sources, crypto, market, count, crypto/count, market/count) with client-side parameter validation, automatic retries with exponential backoff, scroll/paginate helpers, and a typed error hierarchy. Idiomatic Go: context.Context-aware, no external runtime dependencies, safe for concurrent use.

Installation

go get github.com/newsdataapi/newsdata-go-client@latest

Go modules pull the package straight from GitHub — no separate registry to configure.

Quickstart

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/newsdataapi/newsdata-go-client"
)

func main() {
    client, err := newsdataapi.NewClient(os.Getenv("NEWSDATA_API_KEY"))
    if err != nil {
        log.Fatal(err)
    }

    resp, err := client.Latest(context.Background(), newsdataapi.Params{
        "q":        "bitcoin",
        "country":  []string{"us", "gb"},
        "language": "en",
    })
    if err != nil {
        log.Fatal(err)
    }

    articles, _ := resp.Articles()
    for _, a := range articles {
        fmt.Println(a.Title, "-", a.Link)
    }
}

Endpoints

Method Endpoint Notes
client.Latest(ctx, params) /1/latest Real-time news
client.Archive(ctx, params) /1/archive Historical news
client.Sources(ctx, params) /1/sources Available sources (single page)
client.Crypto(ctx, params) /1/crypto Cryptocurrency news
client.Market(ctx, params) /1/market Market / financial news
client.Count(ctx, params) /1/count Aggregate counts (requires from_date, to_date)
client.CryptoCount(ctx, params) /1/crypto/count Aggregate crypto counts
client.MarketCount(ctx, params) /1/market/count Aggregate market counts

Every value in Params may be a string, a []string (sent comma-joined), a bool, an int, a float64, or *bool / *float64 if you need to distinguish "unset" from a zero value. Parameter names are case-insensitive — qInTitle and qintitle are equivalent.

Pagination

Two helpers; both take an endpoint constant (EndpointLatest, EndpointArchive, …):

// 1) ScrollAll: follow nextPage cursors, return one merged Response.
all, err := client.ScrollAll(ctx, newsdataapi.EndpointLatest,
    newsdataapi.Params{"q": "news"}, 200)

articles, _ := all.Articles() // all 200 in one slice

// 2) Paginate: callback per page. Return false from yield to stop early.
err = client.Paginate(ctx, newsdataapi.EndpointLatest,
    newsdataapi.Params{"q": "news"},
    func(page *newsdataapi.Response, err error) bool {
        if err != nil {
            return false
        }
        arts, _ := page.Articles()
        process(arts)
        return true
    })

Raw query

resp, err := client.Latest(ctx, newsdataapi.Params{
    "rawQuery": "q=bitcoin&country=us&language=en",
})

rawQuery is mutually exclusive with all other parameters and is validated against the endpoint's allowed keys before the request is sent.

Client-side validation

Before any request leaves the process, parameters are validated and a typed *NewsdataValidationError is returned (no API quota spent) when:

  • a parameter is not accepted by that endpoint;
  • mutually-exclusive parameters are set together — q/qInTitle/qInMeta, country/excludecountry, category/excludecategory, language/excludelanguage, domain/domainurl/excludedomain;
  • size is outside 1–50;
  • sentiment_score is set without sentiment;
  • a count endpoint is missing from_date or to_date.

Booleans for full_content, image, video, and removeduplicate are coerced to "1"/"0".

Error handling

All SDK errors satisfy the typed hierarchy and play nicely with errors.As and errors.Is:

import "errors"

var (
    ve *newsdataapi.NewsdataValidationError
    ae *newsdataapi.NewsdataAuthError
    rl *newsdataapi.NewsdataRateLimitError
    se *newsdataapi.NewsdataServerError
    ne *newsdataapi.NewsdataNetworkError
    api *newsdataapi.NewsdataAPIError
)

switch {
case errors.As(err, &ve): /* invalid parameter: ve.Param, ve.Message */
case errors.As(err, &ae): /* 401 / 403: ae.StatusCode */
case errors.As(err, &rl): /* 429: rl.RetryAfter (seconds) */
case errors.As(err, &se): /* 5xx */
case errors.As(err, &ne): /* network/timeout/cancellation: ne.Err */
case errors.As(err, &api): /* other API errors: api.StatusCode, api.Message */
}

Hierarchy:

NewsdataError                       (catch-all base)
NewsdataValidationError             (.Param, .Message)
NewsdataAPIError                    (.StatusCode, .Message, .ResponseBody)
├── NewsdataAuthError               (401 / 403)
├── NewsdataRateLimitError          (429; .RetryAfter)
└── NewsdataServerError             (5xx)
NewsdataNetworkError                (.Err)

Configuration

client, err := newsdataapi.NewClient(apiKey,
    newsdataapi.WithTimeout(30 * time.Second),         // per-request
    newsdataapi.WithMaxRetries(5),                     // 1 = no retry
    newsdataapi.WithRetryBackoff(2 * time.Second),     // base, exponential
    newsdataapi.WithRetryBackoffMax(60 * time.Second), // cap on a single sleep
    newsdataapi.WithPaginationDelay(time.Second),
    newsdataapi.WithBaseURL("https://staging.example/api/1/"),
    newsdataapi.WithHTTPClient(myCustomClient),        // proxies / mTLS
    newsdataapi.WithIncludeHeaders(true),              // attach Response.ResponseHeaders
    newsdataapi.WithLogger(myLogger),                  // any Info(msg)/Warn(msg) value
)

Retries cover network errors, HTTP 429, and 5xx responses. 429 honours the Retry-After header (integer seconds or HTTP-date); otherwise the wait is exponential. Auth and other 4xx errors are never retried. context.Context cancellation interrupts retries immediately — passing a cancelled or deadlined context returns a NewsdataNetworkError wrapping context.Canceled or context.DeadlineExceeded.

Concurrency

Client is safe for concurrent use by multiple goroutines.

Development

go test -race ./...                # full unit suite (no API key required)
go vet ./...
go build ./examples/...

The test suite uses net/http/httptest to mock the API end-to-end — no network access required. 30 tests cover the validator, request loop, retry behaviour, scroll + paginate, error mapping, and API-key redaction.

Related libraries

Official Newsdata.io clients across languages and runtimes:

Also see free news datasets for ML / NLP work.

License

MIT

About

Official Go client (SDK) for the Newsdata.io News API — fetch real-time, historical, crypto & stock-market news with validation, retries, and typed errors.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages