Introduction to Gemini 3.1 Flash and Go

Welcome to the first lesson of our course, "Creating Images with Gemini 3.1 Flash and Go." In this course, you will explore AI-driven image generation using Google's Gemini API and its Gemini 3.1 Flash image model. Our journey begins with understanding how to set up the environment and generate a simple image using Go. This foundational lesson will set the stage for more advanced topics in subsequent units.

Setting Up the Environment

Before we dive into generating images, it's crucial to set up our environment correctly. First, ensure you have access to the Gemini API by retrieving your API key. This key is essential for authenticating your requests to the API. You can set this key in your environment variables. For this lesson, you'll need to use Go Modules, Go's package management system, to install the necessary libraries. You can use the net/http package for making HTTP requests.

Note that the environment will be fully set up for the practices section, so you can focus on the exercises without worrying about the setup.

Getting the URL and API Keys

You can get more details about how to use the Gemini Image Generation API from Google's documents. There, you can get the important details about connecting to the API, namely the GEMINI_BASE_URL and the GEMINI_API_KEY.

For example, when connecting directly to Gemini, the GEMINI_BASE_URL will be https://generativelanguage.googleapis.com/ and the GEMINI_API_KEY is your own secret. In all of our examples and practices, we will provide these variables to you so you don't need to be concerned with them for now.

Using libraries

Although Go client libraries exist for many Gemini workflows, this course uses the REST API directly for image generation so the request structure is clear and consistent with the practices.

We will later encapsulate this REST request behind a reusable helper function.

Retrieving your URL and API Keys

First, we need to retrieve the Base URL and API key from your environment variables. From there, we can construct an API request to the Image Generation model, which has a full URL of:

https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-image:generateContent

From there, we attach the API key as a request header and we have a fully constructed request:

// Load API key from environment
apiKey := os.Getenv("GEMINI_API_KEY")
baseUrl := os.Getenv("GEMINI_BASE_URL")
if apiKey == "" || baseUrl == "" {
    log.Fatal("❌ GEMINI_API_KEY or GEMINI_BASE_URL environment variable not set.")
}

// Define endpoint and payload
endpoint := fmt.Sprintf(
    "%s/v1beta/models/gemini-3.1-flash-image:generateContent",
    strings.TrimRight(baseUrl, "/"),
)

This setup ensures that your application can securely communicate with the Gemini API.

Constructing a request

Next, we can construct a JSON payload with our prompt. The minimal JSON payload will look like this:

{
  "contents": [
    {
      "parts": [
        {"text": "A monkey giving a penguin a high five"}
      ]
    }
  ],
  "generationConfig": {
    "responseModalities": ["TEXT", "IMAGE"],
    "imageConfig": {
      "aspectRatio": "1:1"
    }
  }
}

With payload, we can POST to the URL we constructed:

prompt := "A monkey giving a penguin a high five"

// Create request payload
requestData := map[string]interface{}{
    "contents": []map[string]interface{}{
        {
            "parts": []map[string]interface{}{
                {"text": prompt},
            },
        },
    },
    "generationConfig": map[string]interface{}{
        "responseModalities": []string{"TEXT", "IMAGE"},
        "imageConfig": map[string]interface{}{
            "aspectRatio": "1:1",
        },
    },
}

// Marshal request to JSON
jsonData, _ := json.Marshal(requestData)

// Create HTTP client and request
req, _ := http.NewRequest("POST", endpoint, bytes.NewBuffer(jsonData))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-goog-api-key", apiKey)

// Make the request
resp, err := (&http.Client{}).Do(req)
if err != nil {
    log.Fatalf("❌ API request failed: %v", err)
}
defer resp.Body.Close()
Processing the response

Next, we need to extract the data out of the response. The data will come back as Base64 encoded JSON data.

// Read response body
body, err := io.ReadAll(resp.Body)
if err != nil {
    log.Fatalf("❌ Failed to read response body: %v", err)
}

// Handle non-200 responses
if resp.StatusCode != http.StatusOK {
    log.Fatalf("❌ API request failed. Status code: %d, Response: %s", resp.StatusCode, string(body))
}

// Parse response JSON
var responseData map[string]interface{}
if err := json.Unmarshal(body, &responseData); err != nil {
    log.Fatalf("❌ Failed to unmarshal response: %v", err)
}
Decoding the image data and saving it to a file

Once the image is generated, the next step is to process and display it. Here's how you can handle the Base64 encoded image data and save it to a file:

// Create output directory
outputDir := "server/static/images/"
os.MkdirAll(outputDir, 0777)

// Save image if available
candidates := responseData["candidates"].([]interface{})
if len(candidates) > 0 {
    content := candidates[0].(map[string]interface{})["content"].(map[string]interface{})
    parts := content["parts"].([]interface{})
    for _, rawPart := range parts {
        part := rawPart.(map[string]interface{})
        inlineData, ok := part["inlineData"].(map[string]interface{})
        if !ok {
            continue
        }

        imageData, _ := base64.StdEncoding.DecodeString(inlineData["data"].(string))
        outputPath := filepath.Join(outputDir, "output-image.jpg")
        if err := os.WriteFile(outputPath, imageData, 0644); err != nil {
            log.Fatalf("❌ Failed to save image: %v", err)
        }

        fmt.Printf("✅ Image saved as %s\n", outputPath)
        break
    }
}

Summary and Next Steps

If all of this seems too complicated, don't fret! We'll encapsulate it for you and most of the course will utilize a simple generation function called generateGeminiImages(). It's important to understand how the code works so you can replicate it in your own projects!

In this lesson, you learned how to set up your environment, configure the Gemini API, and generate a simple image using a prompt. We also explored how to process and save the generated image using Go. This foundational knowledge will be crucial as you progress through the course. As you move on to the practice exercises, I encourage you to experiment with different prompts and configurations to see the diverse range of images you can create. This hands-on practice will solidify your understanding and prepare you for more advanced topics in the upcoming lessons.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal