This guide covers integrating Google's Gemini API with OwlMetric for comprehensive cost tracking and analytics. Both proxy and direct SDK methods are supported.
| Model Family | Models | Token Tracking | Cost Tracking |
|---|---|---|---|
| Gemini 2.0 | gemini-2.0-flash-exp | ✅ Full | ✅ Real-time |
| Gemini 1.5 | gemini-1.5-pro, gemini-1.5-flash | ✅ Full | ✅ Real-time |
| Gemini 1.0 | gemini-pro, gemini-pro-vision | ✅ Full | ✅ Real-time |
Get Your OwlMetric API Key
# From your OwlMetric project dashboard
OWLMETRIC_API_KEY=pk_your_project_key_here
Update Your Gemini Client
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({
apiKey: process.env.GEMINI_API_KEY,
httpOptions: {
baseUrl: "https://owlmetric.com/api/proxy",
headers: {
"x-owlmetric": process.env.OWLMETRIC_API_KEY,
},
},
});
Use as Normal
// All your existing Gemini code works unchanged
const response = await ai.models.generateContent({
model: "gemini-2.0-flash-exp",
contents: "Hello, Gemini!",
});
Custom Headers:
const ai = new GoogleGenAI({
apiKey: process.env.GEMINI_API_KEY,
httpOptions: {
baseUrl: "https://owlmetric.com/api/proxy",
headers: {
"x-owlmetric": process.env.OWLMETRIC_API_KEY,
"x-owlmetric-user-id": "user-123", // Optional: user tracking
"x-owlmetric-session-id": "session-456", // Optional: session tracking
},
},
});
npm install @owlmetric/tracker
import { GoogleGenAI } from "@google/genai";
import { createTrackedClient } from "@owlmetric/tracker";
const client = createTrackedClient(GoogleGenAI, {
apiKey: process.env.GEMINI_API_KEY,
owlmetricToken: process.env.OWLMETRIC_GEMINI_TOKEN,
});
// Use exactly like the regular GoogleGenAI client
const completion = await client.models.generateContent({
model: "gemini-2.0-flash-exp",
contents: "Hello!",
});
With Custom Provider Name:
const client = createTrackedClient(GoogleGenAI, {
apiKey: process.env.GEMINI_API_KEY,
owlmetricToken: process.env.OWLMETRIC_GEMINI_TOKEN,
provider: "Google-Gemini-Custom", // Custom provider name in dashboard
});
Simple Generation:
const response = await ai.models.generateContent({
model: "gemini-1.5-flash",
contents: "Explain the concept of renewable energy in simple terms.",
});
console.log(response.text);
// Costs and tokens automatically tracked in OwlMetric dashboard
With Generation Config:
const response = await ai.models.generateContent({
model: "gemini-1.5-pro",
contents: "Write a creative story about space exploration.",
generationConfig: {
temperature: 0.8,
topP: 0.9,
topK: 40,
maxOutputTokens: 500,
},
});
const stream = await ai.models.generateContentStream({
model: "gemini-2.0-flash-exp",
contents: "Count from 1 to 10 with explanations.",
});
for await (const chunk of stream) {
const text = chunk.text();
if (text) process.stdout.write(text);
}
// Final usage statistics tracked when stream completes
const chat = ai.models.startChat({
model: "gemini-1.5-pro",
history: [
{
role: "user",
parts: [{ text: "Hello, how are you?" }],
},
{
role: "model",
parts: [{ text: "Hello! I'm doing well, thank you for asking. How can I help you today?" }],
},
],
});
const result = await chat.sendMessage("Can you explain quantum computing?");
console.log(result.response.text());
// All conversation turns tracked cumulatively
Image Analysis:
const response = await ai.models.generateContent({
model: "gemini-1.5-pro",
contents: [
{
role: "user",
parts: [
{ text: "What do you see in this image?" },
{
inlineData: {
mimeType: "image/jpeg",
data: base64Image
}
}
]
}
]
});
// Vision tokens tracked with appropriate pricing
Multiple Images:
const response = await ai.models.generateContent({
model: "gemini-1.5-pro",
contents: [
{
role: "user",
parts: [
{ text: "Compare these two images:" },
{
inlineData: {
mimeType: "image/jpeg",
data: base64Image1
}
},
{
inlineData: {
mimeType: "image/jpeg",
data: base64Image2
}
}
]
}
]
});
const functions = {
get_weather: {
description: "Get current weather for a location",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "City name"
}
},
required: ["location"]
}
}
};
const response = await ai.models.generateContent({
model: "gemini-1.5-pro",
contents: "What's the weather like in Tokyo?",
tools: [{ functionDeclarations: [functions.get_weather] }],
});
// Function call tokens tracked separately
const response = await ai.models.generateContent({
model: "gemini-1.5-pro",
contents: "Generate a Python function that calculates the Fibonacci sequence",
generationConfig: {
temperature: 0.2, // Lower temperature for code generation
maxOutputTokens: 1000,
},
});
// Code generation tokens tracked with standard pricing
# Google Configuration
GEMINI_API_KEY=your-google-api-key
# OwlMetric Configuration
OWLMETRIC_API_KEY=pk_your_project_key_here
# Google Configuration
GEMINI_API_KEY=your-google-api-key
# OwlMetric Tracking Token
OWLMETRIC_GEMINI_TOKEN=pt_your_gemini_tracking_token
OwlMetric automatically tracks detailed token usage for Gemini:
{
"prompt_tokens": 125,
"completion_tokens": 287,
"total_tokens": 412,
"prompt_tokens_details": {
"cached_tokens": 0,
"audio_tokens": 0
},
"completion_tokens_details": {
"audio_tokens": 0
}
}
Real-time cost calculation based on current Google Gemini pricing:
const response = await ai.models.generateContent({
model: "gemini-1.5-pro",
contents: "Tell me about AI safety.",
safetySettings: [
{
category: "HARM_CATEGORY_HARASSMENT",
threshold: "BLOCK_MEDIUM_AND_ABOVE"
},
{
category: "HARM_CATEGORY_HATE_SPEECH",
threshold: "BLOCK_MEDIUM_AND_ABOVE"
}
]
});
// Safety filtering doesn't affect token counting
Both methods handle Gemini API errors gracefully:
try {
const response = await ai.models.generateContent({
model: "gemini-1.5-pro",
contents: "Hello!",
});
} catch (error) {
console.error('Gemini API Error:', error.message);
// Error details tracked in OwlMetric for debugging
}
Rate Limit Errors:
Error: Quota exceeded
Authentication Errors:
Error: API key not valid
Model Not Available:
Error: Model not found
Tracking Not Working:
x-owlmetric header is includedpt_...)Test Basic Functionality:
const testResponse = await ai.models.generateContent({
model: "gemini-1.5-flash",
contents: "Say 'integration working'",
});
console.log('Response:', testResponse.text());
// Check OwlMetric dashboard for this request
Test Streaming:
const stream = await ai.models.generateContentStream({
model: "gemini-1.5-flash",
contents: "Count from 1 to 3",
});
for await (const chunk of stream) {
const text = chunk.text();
if (text) process.stdout.write(text);
}
// Verify final usage appears in dashboard
maxOutputTokens limits// Before
const ai = new GoogleGenAI({
apiKey: process.env.GEMINI_API_KEY,
});
// After (add httpOptions)
const ai = new GoogleGenAI({
apiKey: process.env.GEMINI_API_KEY,
httpOptions: { // Add this
baseUrl: "https://owlmetric.com/api/proxy", // Add this
headers: { // Add this
"x-owlmetric": process.env.OWLMETRIC_API_KEY, // Add this
}, // Add this
}, // Add this
});
// Before (Proxy)
const ai = new GoogleGenAI({
apiKey: process.env.GEMINI_API_KEY,
httpOptions: {
baseUrl: "https://owlmetric.com/api/proxy",
headers: {
"x-owlmetric": process.env.OWLMETRIC_API_KEY,
},
},
});
// After (SDK)
import { createTrackedClient } from "@owlmetric/tracker";
const ai = createTrackedClient(GoogleGenAI, {
apiKey: process.env.GEMINI_API_KEY,
owlmetricToken: process.env.OWLMETRIC_GEMINI_TOKEN,
});
Google's built-in safety features are preserved:
const response = await ai.models.generateContent({
model: "gemini-1.5-pro",
contents: "Tell me about AI safety measures.",
safetySettings: [
{
category: "HARM_CATEGORY_DANGEROUS_CONTENT",
threshold: "BLOCK_MEDIUM_AND_ABOVE"
}
]
});
// Safety filtering applied before response generation
// All safety-related processing tracked in costs
const response = await ai.models.generateContent({
model: "gemini-1.5-pro",
systemInstruction: "You are a helpful coding assistant. Always provide clean, well-commented code examples.",
contents: "Show me how to create a REST API in Python using FastAPI.",
});
// System instruction tokens counted separately
For repeated context (coming soon):
const response = await ai.models.generateContent({
model: "gemini-1.5-pro",
contents: "Continue our previous conversation about machine learning.",
// Context caching will be tracked separately when available
});
For Google Cloud Vertex AI:
// Using Vertex AI endpoint
const ai = new GoogleGenAI({
apiKey: process.env.GOOGLE_CLOUD_API_KEY,
httpOptions: {
baseUrl: "https://owlmetric.com/api/proxy/vertex",
headers: {
"x-owlmetric": process.env.OWLMETRIC_API_KEY,
"x-google-project": process.env.GOOGLE_CLOUD_PROJECT,
},
},
});