Appearance
Go
Get geolocation data in your Go application.
Prerequisites
- Go 1.18+
- A Hummingbird API key (get one free)
Usage
Basic lookup
go
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
type GeoResponse struct {
Success bool `json:"success"`
Data GeoData `json:"data"`
}
type GeoData struct {
IP string `json:"ip"`
IPType string `json:"ip_type"`
Location GeoLocation `json:"location"`
Time GeoTime `json:"time"`
Currency GeoCurrency `json:"currency"`
Network GeoNetwork `json:"network"`
}
type GeoLocation struct {
ContinentCode string `json:"continent_code"`
ContinentName string `json:"continent_name"`
CountryCode string `json:"country_code"`
CountryCodeISO3 string `json:"country_code_iso3"`
CountryName string `json:"country_name"`
CountryCapital string `json:"country_capital"`
CountryTLD string `json:"country_tld"`
CountryCallingCode string `json:"country_calling_code"`
CountryFlagEmoji string `json:"country_flag_emoji"`
CountryLanguages []string `json:"country_languages"`
CountryAreaKm2 int64 `json:"country_area_km2"`
CountryPopulation int64 `json:"country_population"`
CountryNeighbors []string `json:"country_neighbors"`
CountryIsEU bool `json:"country_is_eu"`
RegionCode string `json:"region_code"`
RegionName string `json:"region_name"`
CityName string `json:"city_name"`
PostalCode string `json:"postal_code"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
WeatherCode string `json:"weather_code"`
}
type GeoTime struct {
Zone string `json:"zone"`
Abbr string `json:"abbr"`
UTCOffset string `json:"utc_offset"`
UTCOffsetSeconds int `json:"utc_offset_seconds"`
CurrentTime string `json:"current_time"`
CurrentTimestamp int64 `json:"current_timestamp"`
IsDST bool `json:"is_dst"`
}
type GeoCurrency struct {
Code string `json:"code"`
Name string `json:"name"`
Symbol string `json:"symbol"`
}
type GeoNetwork struct {
ASN *int `json:"asn,omitempty"`
ASNOrganization string `json:"asn_organization"`
ISP string `json:"isp"`
Organization string `json:"organization"`
ConnectionType string `json:"connection_type"`
UserType string `json:"user_type"`
}
func main() {
client := &http.Client{}
req, _ := http.NewRequest("GET",
"https://api.hummingbirdapi.com/v1/geo/lookup?ip=8.8.8.8", nil)
req.Header.Set("X-API-Key", os.Getenv("HUMMINGBIRD_API_KEY"))
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result GeoResponse
json.NewDecoder(resp.Body).Decode(&result)
if result.Success {
fmt.Printf("Location: %s, %s\n",
result.Data.Location.CityName, result.Data.Location.CountryName)
fmt.Printf("Timezone: %s (%s)\n",
result.Data.Time.Zone, result.Data.Time.Abbr)
fmt.Printf("Currency: %s %s\n",
result.Data.Currency.Symbol, result.Data.Currency.Code)
// Location: Mountain View, United States
// Timezone: America/Los_Angeles (PST)
// Currency: $ USD
}
}Look up visitor's IP
Omit the ip parameter to look up the caller's IP address:
go
req, _ := http.NewRequest("GET",
"https://api.hummingbirdapi.com/v1/geo/lookup", nil)
req.Header.Set("X-API-Key", os.Getenv("HUMMINGBIRD_API_KEY"))
resp, _ := client.Do(req)
defer resp.Body.Close()
var result GeoResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Your IP: %s\n", result.Data.IP)HTTP handler example
go
package main
import (
"encoding/json"
"net/http"
"os"
)
func locationHandler(w http.ResponseWriter, r *http.Request) {
clientIP := r.Header.Get("X-Forwarded-For")
if clientIP == "" {
clientIP = r.RemoteAddr
}
client := &http.Client{}
req, _ := http.NewRequest("GET",
"https://api.hummingbirdapi.com/v1/geo/lookup?ip="+clientIP, nil)
req.Header.Set("X-API-Key", os.Getenv("HUMMINGBIRD_API_KEY"))
resp, err := client.Do(req)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer resp.Body.Close()
var result GeoResponse
json.NewDecoder(resp.Body).Decode(&result)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(result)
}
func main() {
http.HandleFunc("/api/location", locationHandler)
http.ListenAndServe(":8080", nil)
}Error handling
go
type ApiResponse struct {
Success bool `json:"success"`
Data *GeoData `json:"data"`
Error bool `json:"error"`
ErrorCode *int `json:"error_code"`
ErrorMessage *string `json:"error_message"`
}
func lookup(ip string) (*GeoData, error) {
client := &http.Client{}
req, _ := http.NewRequest("GET",
"https://api.hummingbirdapi.com/v1/geo/lookup?ip="+ip, nil)
req.Header.Set("X-API-Key", os.Getenv("HUMMINGBIRD_API_KEY"))
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result ApiResponse
json.NewDecoder(resp.Body).Decode(&result)
if !result.Success {
return nil, fmt.Errorf("error %d: %s",
*result.ErrorCode, *result.ErrorMessage)
}
return result.Data, nil
}Response
All responses use the unified envelope format with fields in this order: success, data, error, error_code, error_message.
json
{
"success": true,
"data": {
"ip": "8.8.8.8",
"ip_type": "ipv4",
"location": {
"continent_code": "NA",
"continent_name": "North America",
"country_code": "US",
"country_code_iso3": "USA",
"country_name": "United States",
"country_capital": "Washington",
"country_tld": ".us",
"country_calling_code": "+1",
"country_flag_emoji": "🇺🇸",
"country_languages": ["en", "es"],
"country_area_km2": 9833520,
"country_population": 331449281,
"country_neighbors": ["CA", "MX"],
"country_is_eu": false,
"region_code": "CA",
"region_name": "California",
"city_name": "Mountain View",
"postal_code": "94043",
"latitude": 37.386,
"longitude": -122.084,
"weather_code": "USCA0746"
},
"time": {
"zone": "America/Los_Angeles",
"abbr": "PST",
"utc_offset": "-08:00",
"utc_offset_seconds": -28800,
"current_time": "2026-01-26T10:30:00-08:00",
"current_timestamp": 1737913800,
"is_dst": false
},
"currency": {
"code": "USD",
"name": "US Dollar",
"symbol": "$"
},
"network": {
"asn": 15169,
"asn_organization": "Google LLC",
"isp": "Google LLC",
"organization": "Google LLC",
"connection_type": "Corporate",
"user_type": "hosting"
}
},
"error": false,
"error_code": null,
"error_message": null
}Next steps
- Authentication — Secure your API key
- Rate Limits — Understand request limits
- Error Handling — Handle errors gracefully
- IP Geolocation API Reference — Full endpoint documentation