Verifying with a minimal generate call
Why this matters
Before building complex applications, you need proof that your API key works, your environment is configured correctly, and the API is responding. A minimal call surfaces authentication errors, network issues, and quota problems immediately.
Explanation
The generate_content() method is the simplest way to send a prompt to Gemini and receive a response. It takes a string prompt and returns a GenerateContentResponse object containing the model's reply. Under the hood, this method constructs an HTTP POST request to Google's API endpoint, authenticates using your API key, and waits for the model to finish generating text before returning control to your code.
The response arrives as a single complete block (synchronous), not as a stream. This makes it ideal for verification and simple queries, but for longer generations you may want streaming to show results faster to users. The response object contains the generated text in the text property, but also metadata like token counts and safety ratings if you inspect the full structure.
Use this pattern for quick tests, one-off queries, and any scenario where you don't need streaming or conversation state. Once this works, you're ready to add complexity like system prompts, multi-turn chat, or vision inputs.
Request code
import os
import google.generativeai as genai
genai.configure(api_key=os.environ['GOOGLE_API_KEY'])
model = genai.GenerativeModel('gemini-2.0-flash')
response = model.generate_content('What is 2 plus 2?')
print(response.text) Authentication
1. Get your API key from Google AI Studio (https://aistudio.google.com/apikey). 2. Set the environment variable: `export GOOGLE_API_KEY='your-actual-key-here'`. 3. The SDK automatically reads this on import. 4. Verify: your key should be a 39-character string starting with 'AIza'. 5. Never commit your key to version control: use environment variables in production.
Response shape
| Field | Description |
|---|---|
text | string: the generated response text |
content | Content object containing the response message |
prompt_feedback | safety ratings for your input prompt |
candidates | list of response candidates (usually length 1) |
Field guide
text The actual generated answer: this is what you almost always want. Safe to call immediately without checking safety fields first.
candidates Hidden field that contains the full response candidate including finish_reason and safety_ratings. Useful if you need to detect if the model refused your request (finish_reason='SAFETY').
Setup trap
The GOOGLE_API_KEY environment variable must be set BEFORE you call genai.configure(). Setting it after configure() is called won't work: the SDK reads the variable at configuration time, not at request time.
Cost
Each call to generate_content() costs based on input and output tokens. A minimal query like 'What is 2 plus 2?' costs fractions of a cent, but repeated verification calls across a team add up. For CI/CD pipelines, use a separate test key with a monthly spend limit.
Rate limits
Free tier (Gemini 1.5 Flash) allows 15 requests per minute. A single verification call won't hit this, but rapid-fire testing in loops will. Add small delays (time.sleep(1)) between verification attempts in automation.
Common gotcha
Calling response.text before checking if the response actually succeeded. If the API returns an error response or the model refused to answer due to safety filters, response.text may be empty or missing. Always wrap in error handling if building real features.
Error recovery
APIError: Invalid API KeyAttributeError: 'NoneType' object has no attribute 'text'google.api_core.exceptions.Unauthenticatedgoogle.api_core.exceptions.ResourceExhaustedExperienced dev note
Always capture the full response object, not just response.text. The candidates[0].finish_reason field tells you whether the model completed naturally ('STOP') or stopped because it hit safety filters ('SAFETY') or token limits ('MAX_TOKENS'). This single check prevents silent failures in production: you'll know if the API is censoring your use case before you ship it.
Check your understanding
If generate_content() returns successfully, why might response.text still be empty, and how would you detect it?
Show answer hint
The model can decline to respond for safety reasons even if the API call itself succeeds. The finish_reason in response.candidates[0] will tell you whether this happened.