AI Integration
Connect to 200+ AI models via OpenRouter including GPT-4, Claude, Gemini, Llama, and more - all in one unified API.
Overview
The AI SaaS Starter Kit uses OpenRouter to provide access to multiple AI models through a single, consistent API. This allows you to switch between models easily and offer users choice in their AI provider.
OpenRouter Setup
1. Create Account
- Sign up at openrouter.ai
- Verify your email
- Add credits to your account
2. Get API Key
- Go to Settings → API Keys
- Generate a new API key
- Copy to
.env:
OPENROUTER_API_KEY="sk-or-v1-your-key-here"Available Models
Popular Models
GPT-4 Turbo
OpenAI's most capable model
openai/gpt-4-turboClaude 3.5 Sonnet
Anthropic's latest model
anthropic/claude-3.5-sonnetGemini Pro
Google's multimodal model
google/gemini-proLlama 3 70B
Meta's open-source model
meta-llama/llama-3-70b-instructMaking API Calls
Basic Chat Completion
const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.OPENROUTER_API_KEY}`,
"HTTP-Referer": "https://yourdomain.com",
"X-Title": "Your App Name",
"Content-Type": "application/json"
},
body: JSON.stringify({
"model": "openai/gpt-4-turbo",
"messages": [
{
"role": "user",
"content": "Hello! How are you?"
}
]
})
});
const data = await response.json();
const message = data.choices[0].message.content;With System Prompt
{
"model": "anthropic/claude-3.5-sonnet",
"messages": [
{
"role": "system",
"content": "You are a helpful AI assistant specialized in coding."
},
{
"role": "user",
"content": "How do I create a React component?"
}
]
}Streaming Responses
const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.OPENROUTER_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"model": "openai/gpt-4-turbo",
"messages": [...],
"stream": true // Enable streaming
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
// Process chunk
}Credit System Integration
Deduct Credits
// Before API call
const user = await prisma.user.findUnique({
where: { id: userId },
});
if (user.credits < requiredCredits) {
throw new Error("Insufficient credits");
}
// Make AI call
const aiResponse = await callOpenRouter(messages);
// Deduct credits
await prisma.$transaction([
prisma.user.update({
where: { id: userId },
data: { credits: { decrement: creditsUsed } },
}),
prisma.creditUsage.create({
data: {
userId,
amount: creditsUsed,
description: `AI Chat - ${modelName}`,
},
}),
]);Cost Calculation
Different models have different costs. Example pricing:
| Model | Cost per 1K tokens |
|---|---|
| GPT-4 Turbo | $0.01 / $0.03 (input/output) |
| Claude 3.5 Sonnet | $0.003 / $0.015 |
| GPT-3.5 Turbo | $0.0005 / $0.0015 |
| Llama 3 70B | $0.00059 / $0.00079 |
Chat History
Database Schema
model Chat {
id String @id @default(cuid())
userId String
title String?
model String // Model used
messages Json // Array of messages
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}Storing Conversations
await prisma.chat.create({
data: {
userId,
title: "Chat about Next.js",
model: "gpt-4-turbo",
messages: [
{ role: "user", content: "How do I..." },
{ role: "assistant", content: "To do that..." }
],
},
});Error Handling
Common Errors
- 401 Unauthorized - Invalid API key
- 402 Payment Required - Insufficient OpenRouter credits
- 429 Rate Limit - Too many requests
- 500 Server Error - Model provider issue
Example Error Handling
try {
const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
// ...config
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || "AI request failed");
}
return await response.json();
} catch (error) {
console.error("OpenRouter error:", error);
// Return user-friendly error
throw new Error("Unable to process AI request. Please try again.");
}Model Selection
Let Users Choose
const models = [
{
id: "openai/gpt-4-turbo",
name: "GPT-4 Turbo",
description: "Most capable",
creditsPerMessage: 10,
},
{
id: "anthropic/claude-3.5-sonnet",
name: "Claude 3.5 Sonnet",
description: "Great for coding",
creditsPerMessage: 8,
},
{
id: "openai/gpt-3.5-turbo",
name: "GPT-3.5 Turbo",
description: "Fast and affordable",
creditsPerMessage: 2,
},
];Best Practices
- Implement rate limiting per user
- Cache common responses when possible
- Monitor API usage and costs
- Provide clear error messages to users
- Show credit cost before making requests
- Implement conversation history limits
- Add timeout for long-running requests
- Use streaming for better UX
Advanced Features
Function Calling
Some models support function calling for tool use:
{
"model": "openai/gpt-4-turbo",
"messages": [...],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": { "type": "string" }
}
}
}
}
]
}Vision Models
Send images to vision-capable models:
{
"model": "openai/gpt-4-vision-preview",
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "What's in this image?" },
{
"type": "image_url",
"image_url": { "url": "https://..." }
}
]
}
]
}Monitoring
- Track API usage per user
- Monitor response times
- Log errors and failures
- Set up alerts for high usage
- Review credit consumption patterns