Image Generation API Authentication Guide | GenRelay

Aug 22, 2026·6 min read

You just created a GenRelay account and have an API key in front of you. Before your first image generation request lands, there are three questions to answer: what exact header does the API expect, where do you put the key so it never ends up in a Git commit, and what does it mean when the API returns a 401 or 403? This guide answers all three — with working code you can use immediately.


What authentication method does the GenRelay image API use?

The GenRelay image API uses Bearer token authentication — the same scheme used by most modern AI APIs. Every request must include an Authorization header in this exact format:

Authorization: Bearer YOUR_API_KEY

This applies to all image models on GenRelay: Nano Banana Pro, Nano Banana 2, and GPT-image-2. The same header format is used for video generation — one authentication scheme covers the entire platform, so you only manage one key regardless of which model you call.


How do I get a GenRelay API key?

Sign in to your GenRelay account, navigate to Settings → API Keys, and click Create new key. The key is displayed once. Copy it immediately and store it somewhere secure — if you lose it, you will need to create a new key and revoke the old one.

You can create multiple keys for different environments (development, staging, production). Each key can be revoked independently without affecting the others.


How do I authenticate in Python?

Load your key from an environment variable and pass it in the request header. Never hardcode the key string in your source code.

import os
import requests

API_KEY = os.environ["GENRELAY_API_KEY"]  # set this in your shell before running

def generate_image(prompt: str, model: str = "nano-banana-pro", size: str = "1024x1024") -> dict:
    response = requests.post(
        "https://genrelay.ai/v1/images/generations",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json",
        },
        json={"model": model, "prompt": prompt, "size": size},
        timeout=60,
    )
    response.raise_for_status()  # raises HTTPError on 4xx/5xx
    return response.json()["data"][0]

result = generate_image("a ceramic bowl on a white background, product photography")
print(result["url"])  # direct URL to the generated image

The same pattern applies to all image models. Swap the model value to switch between nano-banana-pro, nano-banana-2, or gpt-image-2 — no other part of the request changes.


How do I authenticate with curl?

# Reference the key from an environment variable — never paste it inline
curl https://genrelay.ai/v1/images/generations \
  -H "Authorization: Bearer $GENRELAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "nano-banana-pro",
    "prompt": "a ceramic bowl on a white background, product photography",
    "size": "1024x1024"
  }'

Always reference $GENRELAY_API_KEY from the environment. Command history is logged on most systems, and inline keys in shell commands can appear in .bash_history or .zsh_history.


Where should I store my API key in production?

Store your API key as an environment variable injected at runtime. Never commit it to source control. The .gitignore-based .env approach works for local development; for deployed environments, use the platform's native secrets mechanism.

Local development:

# .env — add this exact filename to .gitignore
GENRELAY_API_KEY=gr-your-key-here
from dotenv import load_dotenv
import os

load_dotenv()  # reads .env only when the file exists (local dev)
api_key = os.environ["GENRELAY_API_KEY"]

Production options:

Environment Recommended approach
Docker / Kubernetes env: block in pod spec or Docker -e flag
AWS Lambda Lambda environment variables or AWS Secrets Manager
GCP Cloud Run Secret Manager secrets mapped to environment variables
Vercel / Netlify Environment variable dashboard, marked secret
GitHub Actions Repository secrets, accessed as ${{ secrets.GENRELAY_API_KEY }}

The shared principle: the key enters the process as an environment variable at startup. Your code reads it with os.environ (Python) or process.env (Node.js). No config files in the repository, no hardcoded strings.


What do authentication error responses look like?

When authentication fails the API returns a JSON error body alongside the HTTP status code.

Status Typical body Cause Fix
401 Unauthorized {"error": "invalid_api_key"} Key is missing, malformed, or revoked Verify the header is Authorization: Bearer <key> with no extra spaces or characters
403 Forbidden {"error": "permission_denied"} Key is valid but lacks access to the model or endpoint Check your plan tier
429 Too Many Requests {"error": "rate_limit_exceeded"} Request rate exceeds plan limits Implement exponential backoff

Handling authentication errors in Python with retry logic:

import os
import time
import requests
from requests.exceptions import HTTPError

def generate_image_with_retry(
    prompt: str,
    model: str = "nano-banana-pro",
    max_retries: int = 3,
) -> dict:
    headers = {
        "Authorization": f"Bearer {os.environ['GENRELAY_API_KEY']}",
        "Content-Type": "application/json",
    }

    for attempt in range(max_retries):
        try:
            response = requests.post(
                "https://genrelay.ai/v1/images/generations",
                headers=headers,
                json={"model": model, "prompt": prompt, "size": "1024x1024"},
                timeout=60,
            )
            response.raise_for_status()
            return response.json()["data"][0]
        except HTTPError as e:
            status = e.response.status_code
            if status == 401:
                # Retrying with a bad key will never succeed — fail fast
                raise ValueError("Invalid API key — check GENRELAY_API_KEY") from e
            if status == 429 and attempt < max_retries - 1:
                time.sleep(2 ** attempt)  # 1 s, 2 s, 4 s
                continue
            raise

    raise RuntimeError("Max retries reached")

The 401 case raises immediately — there is no point retrying with a bad key. The 429 case uses exponential backoff because rate limit errors are transient.


How do I rotate an API key without downtime?

Rotation is a two-step process: deploy the new key before revoking the old one.

  1. Create a new key in the GenRelay dashboard under Settings → API Keys.
  2. Update your environment or secrets manager with the new key value.
  3. Deploy your app so it starts using the new key.
  4. Confirm a generation request succeeds with the new key.
  5. Revoke the old key in the dashboard.

Between steps 2 and 5, both keys are valid. Your app never makes a request with a revoked key, even if there are requests in flight during the deploy window.


Does the same API key work for all models?

Yes. One API key covers all image models (Nano Banana Pro, Nano Banana 2, GPT-image-2) and all video models (Veo 3.1, Grok Imagine, Omni Flash) on GenRelay. The Authorization: Bearer header is identical regardless of which model you call or which endpoint you target.

For a complete walkthrough of building your first image generation request after authentication is configured, see the image generation API guide.


Frequently asked questions

Can I use my API key directly in frontend JavaScript?
No. Client-side code is publicly readable — any user can extract the key from browser DevTools. Route all API calls through your backend. If you need a browser-facing generation experience, have your server proxy the request to GenRelay.

The API returns 401, but I'm sure the key is correct. What should I check?
Verify the exact header format: Authorization: Bearer gr-yourkey. Common mistakes are a missing Bearer prefix, extra whitespace, or the key being set as Authorization: gr-yourkey without the scheme. Also confirm the key has not been revoked in the dashboard.

How many API keys can I create per account?
GenRelay supports multiple API keys per account. Create a separate key for each service or environment and revoke individual keys as needed without disrupting others.

Does GenRelay support IP allowlisting for API keys?
IP restrictions per key are not currently available. Protect keys through secure environment injection and rotate any key that may have been exposed.

What's a practical key naming convention for teams?
Use names like prod-backend, staging-worker, dev-local-yourname. Descriptive names make it clear which service owns each key and simplify revocation if one is compromised.

Related posts

Join our DiscordImage Generation API Authentication Guide | GenRelay — GenRelay