Gemini API — Build AI Apps with Google AI 2026
Advertisement
Introduction
Why This Matters
The Gemini API provides programmatic access to Google's most capable models, with a free tier through Google AI Studio and competitive pricing for production. Its combination of real-time search access, a 1M-token context window, and the lowest per-token cost among major providers makes it an important option for developers building high-volume or research-heavy AI features. This guide covers everything from first call to production deployment.
Authentication and Setup
Option 1: Google AI Studio (Recommended for development)
- Go to aistudio.google.com
- Click "Get API key"
- Create a new project or use an existing one
- Copy the key — it starts with
AIza
Option 2: Google Cloud Vertex AI (For enterprise/production)
Uses Google Cloud authentication and supports VPC networking, IAM, and audit logging.
pip install google-generativeai # Python SDK
npm install @google/generative-ai # Node.js SDK# Set your API key
export GOOGLE_API_KEY="AIza..."Basic Text Generation
import google.generativeai as genai
import os
genai.configure(api_key=os.environ["GOOGLE_API_KEY"])
model = genai.GenerativeModel(
model_name="gemini-2.0-flash",
generation_config={
"temperature": 0.2,
"top_p": 0.95,
"max_output_tokens": 2048,
},
system_instruction="You are a senior software architect. Be specific and practical.",
)
response = model.generate_content(
"What are the trade-offs between event sourcing and CRUD for a financial ledger system?"
)
print(response.text)
print(f"\nFinish reason: {response.candidates[0].finish_reason}")
print(f"Input tokens: {response.usage_metadata.prompt_token_count}")
print(f"Output tokens: {response.usage_metadata.candidates_token_count}")Streaming Responses
import google.generativeai as genai
genai.configure(api_key="AIza...")
model = genai.GenerativeModel("gemini-2.0-flash")
def stream_explanation(topic: str) -> str:
full_text = ""
for chunk in model.generate_content(
f"Explain {topic} with a practical Python example.",
stream=True,
):
print(chunk.text, end="", flush=True)
full_text += chunk.text
print() # New line after stream ends
return full_text
stream_explanation("Python asyncio event loop internals")Function Calling
import google.generativeai as genai
import json
genai.configure(api_key="AIza...")
# Define tools
get_repo_stats = genai.protos.FunctionDeclaration(
name="get_repo_stats",
description="Get GitHub repository statistics including stars, forks, and open issues",
parameters=genai.protos.Schema(
type=genai.protos.Type.OBJECT,
properties={
"owner": genai.protos.Schema(
type=genai.protos.Type.STRING,
description="Repository owner or organization",
),
"repo": genai.protos.Schema(
type=genai.protos.Type.STRING,
description="Repository name",
),
},
required=["owner", "repo"],
),
)
tool = genai.protos.Tool(function_declarations=[get_repo_stats])
model = genai.GenerativeModel("gemini-2.0-flash", tools=[tool])
def fetch_repo_stats(owner: str, repo: str) -> dict:
# In production, call GitHub API here
return {"stars": 12500, "forks": 890, "open_issues": 45, "language": "Python"}
def run_agent(question: str) -> str:
chat = model.start_chat()
response = chat.send_message(question)
while response.candidates[0].content.parts[0].function_call.name:
fn_call = response.candidates[0].content.parts[0].function_call
fn_name = fn_call.name
fn_args = dict(fn_call.args)
if fn_name == "get_repo_stats":
result = fetch_repo_stats(**fn_args)
else:
result = {"error": f"Unknown function: {fn_name}"}
response = chat.send_message(
genai.protos.Content(
parts=[
genai.protos.Part(
function_response=genai.protos.FunctionResponse(
name=fn_name,
response=result,
)
)
]
)
)
return response.text
print(run_agent("How popular is the FastAPI repository on GitHub?"))Embeddings
Gemini provides text embeddings for semantic search, clustering, and similarity tasks:
import google.generativeai as genai
import numpy as np
genai.configure(api_key="AIza...")
def get_embedding(text: str) -> list[float]:
result = genai.embed_content(
model="models/text-embedding-004",
content=text,
task_type="retrieval_document",
)
return result["embedding"]
def cosine_similarity(a: list[float], b: list[float]) -> float:
a_arr = np.array(a)
b_arr = np.array(b)
return float(np.dot(a_arr, b_arr) / (np.linalg.norm(a_arr) * np.linalg.norm(b_arr)))
# Build a simple semantic search
documents = [
"FastAPI is a modern Python web framework for building APIs",
"PostgreSQL is an open-source relational database",
"Docker enables containerized application deployment",
"Redis is an in-memory data structure store used as a cache",
]
doc_embeddings = [get_embedding(doc) for doc in documents]
def semantic_search(query: str, top_k: int = 2) -> list[str]:
query_embedding = get_embedding(query)
similarities = [cosine_similarity(query_embedding, de) for de in doc_embeddings]
top_indices = sorted(range(len(similarities)), key=lambda i: similarities[i], reverse=True)[:top_k]
return [documents[i] for i in top_indices]
results = semantic_search("How do I cache database results?")
print(results) # Returns Redis and PostgreSQL documents as most relevantJavaScript / TypeScript Integration
import { GoogleGenerativeAI } from '@google/generative-ai';
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY!);
const model = genAI.getGenerativeModel({
model: 'gemini-2.0-flash',
systemInstruction: 'You are a TypeScript expert. Provide concise, typed examples.',
});
async function generateCode(prompt: string): Promise<string> {
const result = await model.generateContent(prompt);
return result.response.text();
}
// Streaming in TypeScript
async function streamCode(prompt: string): Promise<void> {
const result = await model.generateContentStream(prompt);
for await (const chunk of result.stream) {
const text = chunk.text();
process.stdout.write(text);
}
console.log();
}
await streamCode(
'Write a TypeScript utility type that makes all properties of T optional recursively.'
);Common Mistakes
- Using
AIzaAPI keys in Vertex AI calls — these are different authentication systems - Not checking
finish_reason—SAFETYmeans content was blocked, not a successful response - Forgetting
genai.configure(api_key=...)before creating a model — results in authentication errors - Using embedding models for generation tasks —
text-embedding-004only returns vectors, not text - Not handling rate limits — free tier has significant rate limits; production requires billing
Best Practices
- Set
generation_configwith explicitmax_output_tokensto control cost on every model call - Use
task_typeparameter on embeddings —"retrieval_document"for indexed documents,"retrieval_query"for queries - Enable request caching (context caching) for repeated use of the same large document context
- Monitor
usage_metadataon every response for cost tracking and quota management - Use Vertex AI for production workloads requiring SLA guarantees, VPC networking, and IAM controls
Key Takeaways
- The Gemini API is accessed via
google-generativeai(Python) or@google/generative-ai(Node.js) - API keys from Google AI Studio (
AIza...) are separate from Google Cloud service account authentication - Function calling in Gemini uses
genai.protos.FunctionDeclarationwith typed parameter schemas text-embedding-004provides 768-dimensional embeddings for semantic search and clustering- The
finish_reasonfield distinguishes normal completion from safety blocks — always check it in production - Free tier at Google AI Studio is generous for development; Vertex AI is the production path for enterprise
gemini-2.0-flashis the default choice: fastest, cheapest, 1M context window with real-time search- Streaming uses
generate_content(..., stream=True)in Python andgenerateContentStream()in JavaScript
Advertisement