How to Call the OpenWeather API in Go

This tutorial walks you through building a small Go program that fetches weather data from the OpenWeather API. You’ll also learn how to securely store your API key using an environment variable — a best practice for any real-world application. We picked OpenWeather just because it's easy. Once you learn APIs, you can use other useful ones, that provide stock market or government data.

First, you'll need to obtain a free OpenWeatherMap API key — sign up at OpenWeatherMap and get an API key, then replace the string your_api_key_here in the script.

The key is generated immediately, but it takes a couple of hours before they activate it. You will see your key on the 'API Keys' tab (it is a string of random letters). I covered it with a red rectangle on the screenshot to prevent others from using mine:


1. Why You Should Use Environment Variables

When working with external APIs, you must authenticate using an API key. Hard‑coding this key directly into your Go source file is dangerous because:

Environment variables solve all of these problems. They keep secrets out of your code and let you configure your application cleanly.


2. Setting the Environment Variable

macOS / Linux

export OPENWEATHER_API_KEY="your_api_key_here"

Windows (PowerShell)

setx OPENWEATHER_API_KEY "your_api_key_here"

After setting it, restart your terminal so the variable becomes available to new processes.


3. Go Code to Call the OpenWeather API

Below is a minimal but production‑friendly example using net/http and encoding/json. It reads your API key from the environment variable, sends a request, and prints the weather.

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "os"
    "time"
)

type WeatherResp struct {
    Name string `json:"name"`
    Main struct {
        Temp      float64 `json:"temp"`
        FeelsLike float64 `json:"feels_like"`
        Humidity  int     `json:"humidity"`
    } `json:"main"`
    Weather []struct {
        Main        string `json:"main"`
        Description string `json:"description"`
    } `json:"weather"`
}

func getCurrentWeather(city, apiKey string) (*WeatherResp, error) {
    client := &http.Client{Timeout: 10 * time.Second}

    url := fmt.Sprintf(
        "https://api.openweathermap.org/data/2.5/weather?q=%s&units=metric&appid=%s",
        city, apiKey,
    )

    req, err := http.NewRequest(http.MethodGet, url, nil)
    if err != nil {
        return nil, err
    }

    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        return nil, fmt.Errorf("unexpected status: %s", resp.Status)
    }

    var w WeatherResp
    if err := json.NewDecoder(resp.Body).Decode(&w); err != nil {
        return nil, err
    }

    return &w, nil
}

func main() {
    apiKey := os.Getenv("OPENWEATHER_API_KEY")
    if apiKey == "" {
        log.Fatal("Environment variable OPENWEATHER_API_KEY is not set")
    }

    city := "Paris"
    weather, err := getCurrentWeather(city, apiKey)
    if err != nil {
        log.Fatalf("Error fetching weather: %v", err)
    }

    fmt.Printf("Location: %s\n", weather.Name)
    fmt.Printf("Temperature: %.1f°C (feels like %.1f°C)\n",
        weather.Main.Temp, weather.Main.FeelsLike)
    fmt.Printf("Humidity: %d%%\n", weather.Main.Humidity)
    fmt.Printf("Condition: %s - %s\n",
        weather.Weather[0].Main, weather.Weather[0].Description)
}

4. How the Code Works


5. Running the Program

Once your environment variable is set, run:

go run main.go

You should see output similar to:

Location: Paris
Temperature: 12.3°C (feels like 10.8°C)
Humidity: 55%
Condition: Clouds - broken clouds

6. Next Steps