ApogeoAPI quickstart — Go (net/http)
Use ApogeoAPI from Go with the standard library — no dependencies required.
1. Authenticate
Every request needs an X-API-Key header. Get your key from the dashboard — free tier or 14-day trial, no credit card.
Client setup
package apogeo
import (
"encoding/json"
"errors"
"io"
"net/http"
"os"
"time"
)
var client = &http.Client{Timeout: 5 * time.Second}
var apiKey = os.Getenv("APOGEOAPI_KEY")
const base = "https://api.apogeoapi.com/v1"
func get(path string, out any) error {
req, _ := http.NewRequest("GET", base+path, nil)
req.Header.Set("X-API-Key", apiKey)
res, err := client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode >= 400 {
return errors.New(res.Status)
}
body, _ := io.ReadAll(res.Body)
return json.Unmarshal(body, out)
}2. Get country data
Returns ISO codes, capital, currency with live exchange rate, phone code, flag URL, timezones, name translations and more — for any of the 250 countries.
Get country data
type Country struct {
ISO2 string `json:"iso2"`
Name string `json:"name"`
Capital string `json:"capital"`
Currency string `json:"currency"`
}
var ar Country
if err := get("/countries/AR", &ar); err != nil {
log.Fatal(err)
}
fmt.Println(ar.Name, ar.Capital, ar.Currency)Full country list: browse all 250 →
3. IP geolocation
Pass any IPv4 or IPv6 address. Returns country, city, timezone, coordinates and accuracy radius. Use /ip/me server-side to detect the visitor.
IP geolocation
type IPGeo struct {
IP string `json:"ip"`
Country string `json:"country"`
CountryCode string `json:"countryCode"`
Timezone string `json:"timezone"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
}
var geo IPGeo
get("/ip/8.8.8.8", &geo)
fmt.Println(geo.Country, geo.Timezone)Try it live without signup: /ip-lookup →
4. Live exchange rates
161 currencies, refreshed every 4 hours. Specify a base currency and any number of target codes.
Live exchange rates
type FX struct {
Base string `json:"base"`
Rates map[string]float64 `json:"rates"`
}
var fx FX
get("/exchange-rates/USD?targets=EUR,ARS,BRL", &fx)
fmt.Printf("1 USD = %.2f ARS\n", fx.Rates["ARS"])5. States & cities
List all states / provinces for a country (5,000+ globally). Each includes the ISO 3166-2 code and coordinates. Cities are accessible by state ID with /v1/states/:id/cities.
Country → states
type State struct {
Name string `json:"name"`
StateCode string `json:"stateCode"`
ISO3166 string `json:"iso3166_2"`
}
type StatesRes struct{ Data []State `json:"data"` }
var res StatesRes
get("/countries/AR/states?limit=30", &res)
for _, s := range res.Data {
fmt.Println(s.StateCode, s.Name)
}6. Production-grade error handling
Always handle 429 (rate limit) — read the Retry-After header and back off. For transient 5xx, retry up to 3 times with exponential backoff.
Rate-limit aware retry
func getWithRetry(path string, out any) error {
for attempt := 0; attempt < 3; attempt++ {
err := get(path, out)
if err == nil {
return nil
}
if strings.Contains(err.Error(), "429") {
time.Sleep(time.Duration(1<<attempt) * time.Second)
continue
}
return err
}
return errors.New("max retries exceeded")
}Ship this today
Get your API key in 30 seconds — free tier, no credit card.
Get your API keyOther languages
Want the full OpenAPI spec? Swagger UI →