go-modelsdev is a Go library for consuming the models.dev API. It provides a cached client that returns LLM provider and model metadata — pricing, context limits, modalities, and capabilities — for use in services that need to look up model info at runtime.
Pre-1.0 (v0.x.y). The exported API surface is small and intended to remain stable, but breaking changes can still land in minor bumps before v1.0 — see CHANGELOG.md for each release's contract.
go get github.com/hollis-labs/go-modelsdevpackage main
import (
"context"
"fmt"
"log"
"github.com/hollis-labs/go-modelsdev/modelsdev"
)
func main() {
c := modelsdev.New()
if err := c.Refresh(context.Background()); err != nil {
log.Fatal(err)
}
m, ok := c.Get("anthropic", "claude-sonnet-4-5")
if !ok {
fmt.Println("model not found")
return
}
fmt.Printf("%s — input: $%.2f/M tokens\n", m.Name, m.Cost.Input)
}The refresher keeps the cache fresh without blocking your application startup:
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := modelsdev.New()
c.StartRefresher(ctx) // returns immediately; refreshes in background
// c.Get, c.List, etc. are safe to call immediately (reads from disk cache
// if the in-memory catalog is not yet populated).Use WithOnRefresh to be notified when the catalog has been updated — useful for pushing data into your own registry without polling:
c := modelsdev.New(modelsdev.WithOnRefresh(func(c *modelsdev.Client) {
log.Printf("catalog refreshed: %d models", len(c.List()))
}))
c.StartRefresher(ctx)for _, ref := range c.List() {
fmt.Printf("%s/%s — context window: %d\n",
ref.ProviderID, ref.ID, ref.Limit.ContextWindow)
}See examples/ — each example is its own main package that runs end-to-end against the live API:
examples/lookup— one-shot fetch +Getlookup.examples/refresher—StartRefresher+WithOnRefreshhook, prints a catalog summary.
go run ./examples/lookup
go run ./examples/refresher- Default cache directory:
~/.cache/go-modelsdev/(viaos.UserCacheDir()) - Cache file:
catalog.json - Default TTL: 24 hours
- Atomic write contract: the cache is written to a
.tmpfile first, then renamed into place. If a fetch or write fails, the existing cache remains intact and the client continues serving stale-but-valid data.
| Option | Default | Description |
|---|---|---|
WithCacheDir(dir string) |
~/.cache/go-modelsdev/ |
Override the cache directory |
WithCacheTTL(d time.Duration) |
24h |
How long a cached catalog is considered fresh |
WithHTTPClient(c *http.Client) |
30s-timeout client | Replace the HTTP client (useful for tests) |
WithURL(url string) |
https://models.dev/api.json |
Override the API endpoint |
WithOnRefresh(fn func(*Client)) |
nil | Callback fired after every successful refresh |
github.com/cenkalti/backoff/v5— exponential backoff for fetch retries (3 attempts).github.com/stretchr/testify— test assertions (test only).
go test -race ./...Tests use httptest.NewServer and t.TempDir() — no network access or real API keys required.
MIT © Hollis Labs.