Ready-made HTTP handler adapters that expose the UniRate API — free currency exchange rates, conversion, supported currencies, and VAT rates — through the three most popular Go web frameworks: Gin, Echo, and Fiber.
One module, one line to mount, four routes:
| Route | Query params | Description |
|---|---|---|
GET /rate |
from (default USD), to (required) |
Current exchange rate |
GET /convert |
from (default USD), to (required), amount (default 1) |
Convert an amount |
GET /currencies |
— | List supported currency codes |
GET /vat |
country (optional ISO-3166 alpha-2) |
VAT rate(s); omit country for all |
Currency and country codes are uppercased automatically. UniRate errors are mapped to the appropriate HTTP status code and a JSON body of the form {"error": "...", "status": <code>}.
- Go 1.25 or newer
- One of:
github.com/gin-gonic/gin,github.com/labstack/echo/v4,github.com/gofiber/fiber/v2
go get github.com/UniRate-API/unirate-go-webEach adapter package re-exports New to build a UniRate client, so you only need to import the one adapter you use. (The client is the same one from unirate-api-go; if you already hold a *unirate.Client you can pass it straight to Register.)
package main
import (
"os"
"github.com/gin-gonic/gin"
unirategin "github.com/UniRate-API/unirate-go-web/gin"
)
func main() {
client := unirategin.New(os.Getenv("UNIRATE_API_KEY"))
r := gin.Default()
unirategin.Register(r, client) // mounts /rate, /convert, /currencies, /vat
// or under a group:
// unirategin.Register(r.Group("/api/fx"), client)
r.Run(":8080")
}package main
import (
"os"
"github.com/labstack/echo/v4"
unirateecho "github.com/UniRate-API/unirate-go-web/echo"
)
func main() {
client := unirateecho.New(os.Getenv("UNIRATE_API_KEY"))
e := echo.New()
unirateecho.Register(e, client) // or Register(e.Group("/api/fx"), client)
e.Start(":8080")
}package main
import (
"os"
"github.com/gofiber/fiber/v2"
uniratefiber "github.com/UniRate-API/unirate-go-web/fiber"
)
func main() {
client := uniratefiber.New(os.Getenv("UNIRATE_API_KEY"))
app := fiber.New()
uniratefiber.Register(app, client) // or Register(app.Group("/api/fx"), client)
app.Listen(":8080")
}curl 'http://localhost:8080/rate?from=USD&to=EUR'
# {"from":"USD","to":"EUR","rate":0.92}
curl 'http://localhost:8080/convert?from=USD&to=EUR&amount=100'
# {"from":"USD","to":"EUR","amount":100,"result":92.5}
curl 'http://localhost:8080/currencies'
# {"currencies":["USD","EUR","GBP", ...]}
curl 'http://localhost:8080/vat?country=DE'
# {"country":"DE","vat_data":{"country_code":"DE","country_name":"Germany","vat_rate":19.0}}Every adapter shares one error-mapping table, so behaviour is identical across frameworks:
| Condition | HTTP status | JSON error |
|---|---|---|
Missing to / bad amount |
400 |
query parameter '...' is required / ... must be a number |
| Invalid API key (upstream 401) | 401 |
Missing or invalid API key |
| Unknown currency (upstream 404) | 404 |
Currency not found or no data available |
| Rate limit (upstream 429) | 429 |
Rate limit exceeded |
| Pro-gated endpoint (upstream 403) | 403 |
Endpoint requires a Pro subscription |
| Service unavailable (upstream 503) | 503 |
Service unavailable |
| Network / unknown | 500 |
Internal server error |
Only free-tier endpoints (rate, convert, currencies, vat) are exposed as routes. Historical and time-series data are Pro-gated on the UniRate API.
Each adapter also exposes the individual handlers if you want to mount them under custom paths or middleware:
- Gin:
unirategin.Handlers(client)returns the fourgin.HandlerFuncs. - Echo:
unirateecho.RateHandler,.ConvertHandler,.CurrenciesHandler,.VATHandler. - Fiber:
uniratefiber.RateHandler,.ConvertHandler,.CurrenciesHandler,.VATHandler.
Runnable servers live under examples/: examples/gin, examples/echo, examples/fiber. Each reads UNIRATE_API_KEY from the environment:
UNIRATE_API_KEY=your-key go run ./examples/gin- unirate-api-go — the underlying Go client
- UniRate API docs
MIT — see LICENSE.