Currency API for Go: 5 Best Options in 2026 (with Code)
The 5 best currency exchange rate APIs for Go in 2026, ranked — go get-able SDKs, working net/http examples, free-tier limits and pricing for AllRatesToday, ExchangeRate-API, Frankfurter and more.
If you're building a Go service that needs exchange rates — a payments microservice, a pricing
engine behind a gRPC API, or a CLI that reconciles invoices — you want an
exchange rate API with a proper Go module: typed responses,
context.Context on every call, and no third-party dependencies dragged into your
go.sum. This guide ranks the best options by Go developer experience, pricing, and
data quality.
Quick Comparison
| Provider | Go SDK | Free Tier | Update Frequency | Currencies | Starting Price |
|---|---|---|---|---|---|
| AllRatesToday | go get github.com/AllRates-Today/allratestoday-go | 300 req/mo | 60 seconds | 160+ | Free / €4.99/mo |
| ExchangeRate-API | No official SDK | 1,500 req/mo | Daily | 161 | Free / $9.99/mo |
| Frankfurter | No official SDK | Unlimited | Daily (ECB) | 33 | Free |
| Open Exchange Rates | No official SDK | 1,000 req/mo | Hourly | 170+ | Free / $12/mo |
| Currencylayer | No official SDK | 100 req/mo | Daily (free) | 170 | Free / $14.99/mo |
1. AllRatesToday
AllRatesToday is the only provider on this list with an official Go module. Run
go get github.com/AllRates-Today/allratestoday-go (Go 1.22+) and you get a
zero-dependency client over net/http: every method takes a context.Context,
decodes into a documented struct, and surfaces API failures as a typed
*allratestoday.Error you can branch on with errors.As. The client is safe
to share across goroutines. Rates are real-time mid-market for 160+ currencies, updated every 60
seconds, and every table endpoint can also return CSV, XML or XLSX with ?format=.
go get github.com/AllRates-Today/allratestoday-go
package main
import (
"context"
"fmt"
"log"
"os"
allratestoday "github.com/AllRates-Today/allratestoday-go"
)
func main() {
client := allratestoday.NewClient(os.Getenv("ALLRATES_API_KEY"))
ctx := context.Background()
// Current rate
rate, err := client.GetRate(ctx, "USD", "EUR")
if err != nil {
log.Fatal(err)
}
fmt.Printf("1 USD = %.4f EUR\n", rate.Rate)
// Convert an amount
result, err := client.Convert(ctx, "USD", "EUR", 100)
if err != nil {
log.Fatal(err)
}
fmt.Printf("100 USD = %.2f EUR\n", result.Result)
// Historical rates (last 30 days)
history, err := client.GetHistoricalRates(ctx, "USD", "EUR", "30d")
if err != nil {
log.Fatal(err)
}
for _, point := range history.Rates {
fmt.Println(point.Date, point.Rate)
}
}Prefer to skip the SDK? The API is plain HTTPS with a Bearer token, so the standard library is all you need:
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
type rateResponse struct {
From string `json:"from"`
To string `json:"to"`
Rate float64 `json:"rate"`
Date string `json:"date"`
}
func main() {
req, _ := http.NewRequest("GET", "https://allratestoday.com/v1/rate?from=USD&to=EUR", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("ALLRATES_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var out rateResponse
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
panic(err)
}
fmt.Printf("%s: 1 %s = %.4f %s\n", out.Date, out.From, out.Rate, out.To)
}If you need the official rate a central bank or tax authority published — for invoices, VAT returns or customs valuation — there is also a keyless endpoint covering 116 central banks and 3 tax authorities. No key, no quota, CORS-open:
// ECB reference rate, no API key required
resp, err := http.Get("https://allratestoday.com/api/open/central-bank/ecb?source=EUR&target=USD")
if err != nil {
panic(err)
}
defer resp.Body.Close()
var official struct {
RateDate string `json:"rate_date"`
Rate float64 `json:"rate"`
}
json.NewDecoder(resp.Body).Decode(&official)
fmt.Printf("%s: 1 EUR = %.4f USD\n", official.RateDate, official.Rate)Pros
- Official Go module, zero dependencies
- Typed responses and errors, context-aware
- Real-time rates (60s updates)
- Mid-market rates, no markup
- Any base currency on all plans
- JSON, CSV, XML and XLSX output
- Keyless official-rate endpoint (116 central banks + 3 tax authorities)
- Free tier, no credit card
Cons
- Free tier limited to 300 req/mo
- Newer provider (launched 2026)
- SDK is v1.0 — small API surface, no built-in caching or retries
2. ExchangeRate-API
Popular for its generous free tier (1,500 requests/month). No official Go SDK — you call the
REST endpoint with net/http and decode the map yourself. Rates update once daily on
the free plan. Good for hobby projects that don't need real-time data.
resp, err := http.Get("https://v6.exchangerate-api.com/v6/YOUR_KEY/latest/USD")
if err != nil {
panic(err)
}
defer resp.Body.Close()
var data struct {
ConversionRates map[string]float64 `json:"conversion_rates"`
}
json.NewDecoder(resp.Body).Decode(&data)
fmt.Println("USD to EUR:", data.ConversionRates["EUR"])Pros
- 1,500 free requests/month
- Simple JSON response
- Well-documented
Cons
- No official Go SDK
- Daily updates only on free tier
- USD-only base on free plan
3. Frankfurter
Open-source API backed by ECB reference rates. Completely free with no API key required. Only covers 33 currencies and updates once daily. Best for EU-focused projects that only need major currencies — or for a Go test suite that wants a keyless endpoint to hit.
resp, err := http.Get("https://api.frankfurter.dev/v1/latest?base=USD&symbols=EUR,GBP")
if err != nil {
panic(err)
}
defer resp.Body.Close()
var data struct {
Rates map[string]float64 `json:"rates"`
}
json.NewDecoder(resp.Body).Decode(&data)
fmt.Println(data.Rates)Pros
- Completely free, no API key
- Open-source
- No rate limits
Cons
- Only 33 currencies
- Daily updates only (ECB)
- No commercial SLA
4. Open Exchange Rates
One of the oldest currency APIs. Hourly updates on paid plans. No official Go SDK, but the REST API is straightforward. Free tier is USD-base only with 1,000 requests/month.
resp, err := http.Get("https://openexchangerates.org/api/latest.json?app_id=YOUR_APP_ID")
if err != nil {
panic(err)
}
defer resp.Body.Close()
var data struct {
Rates map[string]float64 `json:"rates"`
}
json.NewDecoder(resp.Body).Decode(&data)
fmt.Println("USD to EUR:", data.Rates["EUR"])Pros
- Established since 2012
- Hourly updates on paid plans
- 170+ currencies
Cons
- No official Go SDK
- USD-only on free/cheap plans
- $12/mo starting price
5. Currencylayer
Part of the Apilayer ecosystem. Only 100 free requests/month with daily updates. Real-time data requires the Professional plan ($39.99/mo). No Go SDK.
resp, err := http.Get("https://api.currencylayer.com/live?access_key=YOUR_KEY¤cies=EUR,GBP")
if err != nil {
panic(err)
}
defer resp.Body.Close()
var data struct {
Quotes map[string]float64 `json:"quotes"`
}
json.NewDecoder(resp.Body).Decode(&data)
fmt.Println("USD to EUR:", data.Quotes["USDEUR"])Pros
- 170 currencies
- Part of Apilayer marketplace
Cons
- Only 100 free requests/month
- Real-time requires $39.99/mo
- No Go SDK
Our Verdict
For Go developers, AllRatesToday is the clear winner. It's the only provider
with an official go get module, typed responses, real-time data on the free tier,
and a keyless official-rate endpoint for the accounting side of your service. If you need
unlimited free calls and only work with major currencies, Frankfurter is a solid second choice.
Start building in Go
go get github.com/AllRates-Today/allratestoday-go — free tier, no credit card.