Skip to content

Go SDK

The Go client handles authentication, decodes every response into a struct, and returns one error type that says what went wrong. It needs Go 1.21 or newer and uses only the standard library.

Download the module, unpack it beside your code, and point your module at it:

curl -LO https://docs.ai4mproject.com/downloads/ai4m-sdk-go-0.4.0.zip
mkdir -p third_party && unzip ai4m-sdk-go-0.4.0.zip -d third_party/ai4m
go mod edit -require github.com/ai4m-project/ai4m-api/sdk/[email protected]
go mod edit -replace github.com/ai4m-project/ai4m-api/sdk/go=./third_party/ai4m

The current version is 0.4.0. New versions are announced in the changelog.

import ai4m "github.com/ai4m-project/ai4m-api/sdk/go"
client := ai4m.NewClient(os.Getenv("AI4M_API_KEY"))
ctx := context.Background()
Option Default Meaning
ai4m.WithBaseURL(url) https://api.ai4mproject.com The API’s address
ai4m.WithHTTPClient(client) A client with a ten-second timeout Your own *http.Client, for a different timeout or transport

Every method takes a context.Context first, so a call can be cancelled or given a deadline.

Method Returns Endpoint
Periods(ctx) *Periods Periods
StateRisk(ctx, period) *StateRiskReport State risk
LGARisk(ctx, state, period) *LGARiskReport LGA risk
StateForecasts(ctx, months) []StateRiskReport State forecasts
LGAForecasts(ctx, state, months) []LGARiskReport LGA forecasts
Transmission(ctx) *TransmissionReport State transmission
LGASeasons(ctx, state) *LGASeasonReport LGA transmission
TransmissionModel(ctx) map[string]any Transmission model
StateContext(ctx) []StateContext State context
LGAContext(ctx, state) []LGAContext LGA context
StateBoundaries(ctx) map[string]any State boundaries
LGABoundaries(ctx, state) map[string]any LGA boundaries

An empty period means the latest estimated month, and 0 months means all four forecast months.

periods, err := client.Periods(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Estimated to %s, forecast to %s\n", periods.LastEstimated, periods.LastForecast)
// The five highest-risk states this month.
report, err := client.StateRisk(ctx, "")
if err != nil {
log.Fatal(err)
}
sort.Slice(report.States, func(i, j int) bool { return report.States[i].Score > report.States[j].Score })
for _, state := range report.States[:5] {
fmt.Printf("%-12s %.2f %s\n", state.State, state.Score, state.Level)
}
// Every LGA in Kano, its forecast, and when cases are expected to be highest.
kano, err := client.LGARisk(ctx, "KN", "")
forecasts, err := client.LGAForecasts(ctx, "KN", 3)
seasons, err := client.LGASeasons(ctx, "KN")

Struct fields follow Go naming, and each carries the API’s JSON name: ScoreLow is score_low, LGACode is lga_code, PeakMonth is peak_month. A value the API may leave out, such as ScoreLow, is a pointer and is nil when absent. See Scores and levels for what the fields mean.

Every error is an *ai4m.Error, with Kind, StatusCode, Message and, where the API sends one, Code.

Kind Status Meaning
KindValidation 400 The request was wrong
KindAuthentication 401 The key is missing, wrong, expired or revoked
KindPermission 403 The key lacks the scope
KindNotFound 404 Unknown state, or no data for that month
KindRateLimit 429 A limit was reached. RetryAfter is in seconds
report, err := client.LGARisk(ctx, "KN", "")
var failure *ai4m.Error
if errors.As(err, &failure) {
switch {
case failure.Kind == ai4m.KindRateLimit && failure.Code == "RATE_LIMITED":
time.Sleep(time.Duration(failure.RetryAfter) * time.Second) // then try again
case failure.Kind == ai4m.KindPermission:
log.Println("This key can't read risk scores:", failure.Message)
default:
log.Fatal(err)
}
}