Skip to main content 首页 创作者 bobmatnyc claude-mpm-skills openrouter
openrouter OpenRouter unified AI API - Access 200+ LLMs through single interface with intelligent routing, streaming, cost optimization, and model fallbacks
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill openrouter命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... 同仓库更多 Skills LinkedIn automation via the Linked API CLI - fetch profiles, search people and companies, send messages, manage connections, create posts, react, comment, and run Sales Navigator and custom workflows. Use when the user wants to interact with LinkedIn.
Xquik X data automation API - Use REST or MCP for tweet search, user lookup, follower exports, media downloads, monitors, webhooks, giveaway draws, and confirmation-gated X actions.
MCP (Model Context Protocol) - Build AI-native servers with tools, resources, and prompts. TypeScript/Python SDKs for Claude Desktop integration.
name openrouter description OpenRouter unified AI API - Access 200+ LLMs through single interface with intelligent routing, streaming, cost optimization, and model fallbacks user-invocable false disable-model-invocation true version 1.0.0 category ai-service author Claude MPM Team license MIT progressive_disclosure {"entry_point":{"summary":"Unified AI gateway: 200+ models (GPT-4, Claude, Llama, Gemini), single API, intelligent routing, streaming, cost optimization","when_to_use":"Multi-model AI apps, cost-optimized inference, model fallbacks, A/B testing, production LLM deployments, avoiding vendor lock-in","quick_start":"1. Get API key at openrouter.ai 2. POST to /api/v1/chat/completions 3. Set model param 4. Handle streaming responses"}} context_limit 4200 tags ["ai","llm","api","openai-compatible","streaming","cost-optimization","multi-model"] requires_tools []
OpenRouter - Unified AI API Gateway
Overview
OpenRouter provides a single API to access 200+ language models from OpenAI, Anthropic, Google, Meta, Mistral, and more. It offers intelligent routing, streaming, cost optimization, and standardized OpenAI-compatible interface.
Key Features :
Access 200+ models through one API
OpenAI-compatible interface (drop-in replacement)
Intelligent model routing and fallbacks
Real-time streaming responses
Cost tracking and optimization
Model performance analytics
Function calling support
Vision model support
Pricing Model :
Pay-per-token (no subscriptions)
Volume discounts available
Free tier with credits
Per-model pricing varies
Installation :
npm install openai
pip install openai
Quick Start
1. Get API Key
export OPENROUTER_API_KEY="sk-or-v1-..."
2. Basic Chat Completion
import OpenAI from 'openai' ;
const client = new OpenAI ({
baseURL : 'https://openrouter.ai/api/v1' ,
apiKey : process.env .OPENROUTER_API_KEY ,
defaultHeaders : {
'HTTP-Referer' : 'https://your-app.com' ,
'X-Title' : 'Your App Name' ,
}
});
async function ( ) {
completion = client. . . ({
: ,
: [
{ : , : }
],
});
. (completion. [ ]. . );
}
chat
const
await
chat
completions
create
model
'anthropic/claude-3.5-sonnet'
messages
role
'user'
content
'Explain quantum computing in simple terms'
console
log
choices
0
message
content
3. Streaming Response async function streamChat ( ) {
const stream = await client.chat .completions .create ({
model : 'openai/gpt-4-turbo' ,
messages : [
{ role : 'user' , content : 'Write a short story about AI' }
],
stream : true ,
});
for await (const chunk of stream) {
const content = chunk.choices [0 ]?.delta ?.content || '' ;
process.stdout .write (content);
}
}
Model Selection Strategy
Available Model Categories Flagship Models (Highest Quality):
const flagshipModels = {
claude : 'anthropic/claude-3.5-sonnet' ,
gpt4 : 'openai/gpt-4-turbo' ,
gemini : 'google/gemini-pro-1.5' ,
opus : 'anthropic/claude-3-opus' ,
};
Fast Models (Low Latency):
const fastModels = {
claude : 'anthropic/claude-3-haiku' ,
gpt35 : 'openai/gpt-3.5-turbo' ,
gemini : 'google/gemini-flash-1.5' ,
llama : 'meta-llama/llama-3.1-8b-instruct' ,
};
const budgetModels = {
haiku : 'anthropic/claude-3-haiku' ,
gemini : 'google/gemini-flash-1.5' ,
llama : 'meta-llama/llama-3.1-8b-instruct' ,
mixtral : 'mistralai/mixtral-8x7b-instruct' ,
};
const specializedModels = {
vision : 'openai/gpt-4-vision-preview' ,
code : 'anthropic/claude-3.5-sonnet' ,
longContext : 'google/gemini-pro-1.5' ,
function : 'openai/gpt-4-turbo' ,
};
Model Selection Logic interface ModelSelector {
task : 'chat' | 'code' | 'vision' | 'function' | 'summary' ;
priority : 'quality' | 'speed' | 'cost' ;
maxCost ?: number ;
contextSize ?: number ;
}
function selectModel (criteria : ModelSelector ): string {
if (criteria.task === 'vision' ) {
return 'openai/gpt-4-vision-preview' ;
}
if (criteria.task === 'code' ) {
return criteria.priority === 'quality'
? 'anthropic/claude-3.5-sonnet'
: 'meta-llama/llama-3.1-70b-instruct' ;
}
if (criteria.contextSize && criteria.contextSize > 100000 ) {
return 'google/gemini-pro-1.5' ;
}
switch (criteria.priority ) {
case 'quality' :
return 'anthropic/claude-3.5-sonnet' ;
case 'speed' :
return 'anthropic/claude-3-haiku' ;
case 'cost' :
return criteria.maxCost && criteria.maxCost < 0.5
? 'google/gemini-flash-1.5'
: 'anthropic/claude-3-haiku' ;
default :
return 'openai/gpt-4-turbo' ;
}
}
const model = selectModel ({
task : 'code' ,
priority : 'quality' ,
});
Streaming Implementation
TypeScript Streaming with Error Handling async function robustStreamingChat (
prompt : string ,
model : string = 'anthropic/claude-3.5-sonnet'
) {
try {
const stream = await client.chat .completions .create ({
model,
messages : [{ role : 'user' , content : prompt }],
stream : true ,
max_tokens : 4000 ,
});
let fullResponse = '' ;
for await (const chunk of stream) {
const delta = chunk.choices [0 ]?.delta ;
if (delta?.content ) {
fullResponse += delta.content ;
process.stdout .write (delta.content );
}
if (delta?.function_call ) {
console .log ('\nFunction call:' , delta.function_call );
}
if (chunk.choices [0 ]?.finish_reason ) {
console .log (`\n[Finished: ${chunk.choices[0 ].finish_reason} ]` );
}
}
return fullResponse;
} catch (error) {
if (error instanceof Error ) {
console .error ('Streaming error:' , error.message );
}
throw error;
}
}
Python Streaming from openai import OpenAI
client = OpenAI(
base_url="https://openrouter.ai/api/v1" ,
api_key=os.environ.get("OPENROUTER_API_KEY" ),
)
def stream_chat (prompt: str , model: str = "anthropic/claude-3.5-sonnet" ):
stream = client.chat.completions.create(
model=model,
messages=[{"role" : "user" , "content" : prompt}],
stream=True ,
)
full_response = ""
for chunk in stream:
if chunk.choices[0 ].delta.content:
content = chunk.choices[0 ].delta.content
full_response += content
print (content, end="" , flush=True )
print ()
return full_response
React Streaming Component import { useState } from 'react' ;
function StreamingChat ( ) {
const [response, setResponse] = useState ('' );
const [isStreaming, setIsStreaming] = useState (false );
async function handleSubmit (prompt : string ) {
setIsStreaming (true );
setResponse ('' );
try {
const res = 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 : 'anthropic/claude-3.5-sonnet' ,
messages : [{ role : 'user' , content : prompt }],
stream : true ,
}),
});
const reader = res.body ?.getReader ();
const decoder = new TextDecoder ();
while (true ) {
const { done, value } = await reader!.read ();
if (done) break ;
const chunk = decoder.decode (value);
const lines = chunk.split ('\n' ).filter (line => line.trim ());
for (const line of lines) {
if (line.startsWith ('data: ' )) {
const data = line.slice (6 );
if (data === '[DONE]' ) continue ;
try {
const parsed = JSON .parse (data);
const content = parsed.choices [0 ]?.delta ?.content || '' ;
setResponse (prev => prev + content);
} catch (e) {
}
}
}
}
} catch (error) {
console .error ('Streaming error:' , error);
} finally {
setIsStreaming (false );
}
}
return (
<div >
<textarea
value ={response}
readOnly
rows ={20}
cols ={80}
placeholder ="Response will appear here..."
/>
<button onClick ={() => handleSubmit('Explain AI')}>
{isStreaming ? 'Streaming...' : 'Send'}
</button >
</div >
);
}
Function Calling
Basic Function Calling const tools = [
{
type : 'function' ,
function : {
name : 'get_weather' ,
description : 'Get current weather for a location' ,
parameters : {
type : 'object' ,
properties : {
location : {
type : 'string' ,
description : 'City name, e.g. San Francisco' ,
},
unit : {
type : 'string' ,
enum : ['celsius' , 'fahrenheit' ],
},
},
required : ['location' ],
},
},
},
];
async function chatWithFunctions ( ) {
const completion = await client.chat .completions .create ({
model : 'openai/gpt-4-turbo' ,
messages : [
{ role : 'user' , content : 'What is the weather in Tokyo?' }
],
tools,
tool_choice : 'auto' ,
});
const message = completion.choices [0 ].message ;
if (message.tool_calls ) {
for (const toolCall of message.tool_calls ) {
console .log ('Function:' , toolCall.function .name );
console .log ('Arguments:' , toolCall.function .arguments );
const args = JSON .parse (toolCall.function .arguments );
const result = await getWeather (args.location , args.unit );
const followUp = await client.chat .completions .create ({
model : 'openai/gpt-4-turbo' ,
messages : [
{ role : 'user' , content : 'What is the weather in Tokyo?' },
message,
{
role : 'tool' ,
tool_call_id : toolCall.id ,
content : JSON .stringify (result),
},
],
tools,
});
console .log (followUp.choices [0 ].message .content );
}
}
}
Multi-Step Function Calling async function multiStepFunctionCall (userQuery : string ) {
const messages = [{ role : 'user' , content : userQuery }];
let iterationCount = 0 ;
const maxIterations = 5 ;
while (iterationCount < maxIterations) {
const completion = await client.chat .completions .create ({
model : 'openai/gpt-4-turbo' ,
messages,
tools,
tool_choice : 'auto' ,
});
const message = completion.choices [0 ].message ;
messages.push (message);
if (!message.tool_calls ) {
return message.content ;
}
for (const toolCall of message.tool_calls ) {
const functionName = toolCall.function .name ;
const args = JSON .parse (toolCall.function .arguments );
const result = await executeFunctionCall (functionName, args);
messages.push ({
role : 'tool' ,
tool_call_id : toolCall.id ,
content : JSON .stringify (result),
});
}
iterationCount++;
}
throw new Error ('Max iterations reached' );
}
Cost Optimization
Token Counting and Cost Estimation import { encoding_for_model } from 'tiktoken' ;
interface CostEstimate {
promptTokens : number ;
completionTokens : number ;
promptCost : number ;
completionCost : number ;
totalCost : number ;
}
const modelPricing = {
'anthropic/claude-3.5-sonnet' : { input : 3.00 , output : 15.00 },
'anthropic/claude-3-haiku' : { input : 0.25 , output : 1.25 },
'openai/gpt-4-turbo' : { input : 10.00 , output : 30.00 },
'openai/gpt-3.5-turbo' : { input : 0.50 , output : 1.50 },
'google/gemini-flash-1.5' : { input : 0.075 , output : 0.30 },
};
function estimateCost (
prompt : string ,
expectedCompletion : number ,
model : string
): CostEstimate {
const encoder = encoding_for_model ('gpt-4' );
const promptTokens = encoder.encode (prompt).length ;
const completionTokens = expectedCompletion;
const pricing = modelPricing[model] || { input : 0 , output : 0 };
const promptCost = (promptTokens / 1_000_000 ) * pricing.input ;
const completionCost = (completionTokens / 1_000_000 ) * pricing.output ;
return {
promptTokens,
completionTokens,
promptCost,
completionCost,
totalCost : promptCost + completionCost,
};
}
const estimate = estimateCost (
'Explain quantum computing' ,
500 ,
'anthropic/claude-3.5-sonnet'
);
console .log (`Estimated cost: $${estimate.totalCost.toFixed(4 )} ` );
Dynamic Model Selection by Budget async function budgetOptimizedChat (
prompt : string ,
maxCostPerRequest : number = 0.01
) {
const expensiveEstimate = estimateCost (
prompt,
1000 ,
'anthropic/claude-3.5-sonnet'
);
let selectedModel = 'anthropic/claude-3.5-sonnet' ;
if (expensiveEstimate.totalCost > maxCostPerRequest) {
const cheapEstimate = estimateCost (
prompt,
1000 ,
'anthropic/claude-3-haiku'
);
if (cheapEstimate.totalCost > maxCostPerRequest) {
selectedModel = 'google/gemini-flash-1.5' ;
} else {
selectedModel = 'anthropic/claude-3-haiku' ;
}
}
console .log (`Selected model: ${selectedModel} ` );
const completion = await client.chat .completions .create ({
model : selectedModel,
messages : [{ role : 'user' , content : prompt }],
});
return completion.choices [0 ].message .content ;
}
Batching for Cost Reduction async function batchProcess (prompts : string [], model : string ) {
const concurrency = 5 ;
const results = [];
for (let i = 0 ; i < prompts.length ; i += concurrency) {
const batch = prompts.slice (i, i + concurrency);
const batchResults = await Promise .all (
batch.map (prompt =>
client.chat .completions .create ({
model,
messages : [{ role : 'user' , content : prompt }],
max_tokens : 500 ,
})
)
);
results.push (...batchResults);
if (i + concurrency < prompts.length ) {
await new Promise (resolve => setTimeout (resolve, 1000 ));
}
}
return results;
}
Model Fallback and Retry Strategy
Automatic Fallback const modelFallbackChain = [
'anthropic/claude-3.5-sonnet' ,
'openai/gpt-4-turbo' ,
'anthropic/claude-3-haiku' ,
'google/gemini-flash-1.5' ,
];
async function chatWithFallback (
prompt : string ,
maxRetries : number = 3
): Promise <string > {
for (const model of modelFallbackChain) {
try {
console .log (`Trying model: ${model} ` );
const completion = await client.chat .completions .create ({
model,
messages : [{ role : 'user' , content : prompt }],
max_tokens : 2000 ,
});
return completion.choices [0 ].message .content || '' ;
} catch (error) {
console .warn (`Model ${model} failed:` , error);
if (model === modelFallbackChain[modelFallbackChain.length - 1 ]) {
throw new Error ('All models failed' );
}
}
}
throw new Error ('No models available' );
}
Exponential Backoff for Rate Limits async function retryWithBackoff<T>(
fn : () => Promise <T>,
maxRetries : number = 5
): Promise <T> {
let lastError : Error ;
for (let i = 0 ; i < maxRetries; i++) {
try {
return await fn ();
} catch (error) {
lastError = error as Error ;
if (error.status === 429 ) {
const delay = Math .pow (2 , i) * 1000 ;
console .log (`Rate limited. Retrying in ${delay} ms...` );
await new Promise (resolve => setTimeout (resolve, delay));
} else {
throw error;
}
}
}
throw lastError!;
}
const result = await retryWithBackoff (() =>
client.chat .completions .create ({
model : 'anthropic/claude-3.5-sonnet' ,
messages : [{ role : 'user' , content : 'Hello' }],
})
);
Prompt Engineering Best Practices
System Prompts for Consistency const systemPrompts = {
concise : 'You are a helpful assistant. Be concise and direct.' ,
detailed : 'You are a knowledgeable expert. Provide comprehensive answers with examples.' ,
code : 'You are an expert programmer. Provide clean, well-commented code with explanations.' ,
creative : 'You are a creative writing assistant. Be imaginative and engaging.' ,
};
async function chatWithPersonality (
prompt : string ,
personality : keyof typeof systemPrompts
) {
const completion = await client.chat .completions .create ({
model : 'anthropic/claude-3.5-sonnet' ,
messages : [
{ role : 'system' , content : systemPrompts[personality] },
{ role : 'user' , content : prompt },
],
});
return completion.choices [0 ].message .content ;
}
Few-Shot Prompting async function fewShotClassification (text : string ) {
const completion = await client.chat .completions .create ({
model : 'openai/gpt-4-turbo' ,
messages : [
{
role : 'system' ,
content : 'Classify text sentiment as positive, negative, or neutral.' ,
},
{ role : 'user' , content : 'I love this product!' },
{ role : 'assistant' , content : 'positive' },
{ role : 'user' , content : 'This is terrible.' },
{ role : 'assistant' , content : 'negative' },
{ role : 'user' , content : 'It works fine.' },
{ role : 'assistant' , content : 'neutral' },
{ role : 'user' , content : text },
],
});
return completion.choices [0 ].message .content ;
}
Chain of Thought Prompting async function reasoningTask (problem : string ) {
const completion = await client.chat .completions .create ({
model : 'anthropic/claude-3.5-sonnet' ,
messages : [
{
role : 'user' ,
content : `${problem} \n\nLet's solve this step by step:\n1.` ,
},
],
max_tokens : 3000 ,
});
return completion.choices [0 ].message .content ;
}
Rate Limits and Throttling
Rate Limit Handler class RateLimitedClient {
private requestQueue : Array <() => Promise <any >> = [];
private processing = false ;
private requestsPerMinute = 60 ;
private requestInterval = 60000 / this .requestsPerMinute ;
async enqueue<T>(request : () => Promise <T>): Promise <T> {
return new Promise ((resolve, reject ) => {
this .requestQueue .push (async () => {
try {
const result = await request ();
resolve (result);
} catch (error) {
reject (error);
}
});
this .processQueue ();
});
}
private async processQueue ( ) {
if (this .processing || this .requestQueue .length === 0 ) return ;
this .processing = true ;
while (this .requestQueue .length > 0 ) {
const request = this .requestQueue .shift ()!;
await request ();
await new Promise (resolve => setTimeout (resolve, this .requestInterval ));
}
this .processing = false ;
}
}
const rateLimitedClient = new RateLimitedClient ();
const result = await rateLimitedClient.enqueue (() =>
client.chat .completions .create ({
model : 'anthropic/claude-3.5-sonnet' ,
messages : [{ role : 'user' , content : 'Hello' }],
})
);
Vision Models
Image Understanding async function analyzeImage (imageUrl : string , question : string ) {
const completion = await client.chat .completions .create ({
model : 'openai/gpt-4-vision-preview' ,
messages : [
{
role : 'user' ,
content : [
{ type : 'text' , text : question },
{ type : 'image_url' , image_url : { url : imageUrl } },
],
},
],
max_tokens : 1000 ,
});
return completion.choices [0 ].message .content ;
}
const result = await analyzeImage (
'https://example.com/image.jpg' ,
'What objects are in this image?'
);
Multi-Image Analysis async function compareImages (imageUrls : string [] ) {
const completion = await client.chat .completions .create ({
model : 'openai/gpt-4-vision-preview' ,
messages : [
{
role : 'user' ,
content : [
{ type : 'text' , text : 'Compare these images and describe the differences:' },
...imageUrls.map (url => ({
type : 'image_url' as const ,
image_url : { url },
})),
],
},
],
});
return completion.choices [0 ].message .content ;
}
Error Handling and Monitoring
Comprehensive Error Handler interface ErrorResponse {
error : {
message : string ;
type : string ;
code : string ;
};
}
async function robustCompletion (prompt : string ) {
try {
const completion = await client.chat .completions .create ({
model : 'anthropic/claude-3.5-sonnet' ,
messages : [{ role : 'user' , content : prompt }],
});
return completion.choices [0 ].message .content ;
} catch (error : any ) {
if (error.status === 429 ) {
console .error ('Rate limit exceeded. Please wait.' );
throw new Error ('RATE_LIMIT_EXCEEDED' );
}
if (error.status === 401 ) {
console .error ('Invalid API key' );
throw new Error ('INVALID_API_KEY' );
}
if (error.status === 404 ) {
console .error ('Model not found' );
throw new Error ('MODEL_NOT_FOUND' );
}
if (error.status >= 500 ) {
console .error ('OpenRouter server error' );
throw new Error ('SERVER_ERROR' );
}
console .error ('Unknown error:' , error);
throw error;
}
}
Request/Response Logging class LoggingClient {
async chat (prompt : string , model : string ) {
const startTime = Date .now ();
console .log ('[Request]' , {
timestamp : new Date ().toISOString (),
model,
promptLength : prompt.length ,
});
try {
const completion = await client.chat .completions .create ({
model,
messages : [{ role : 'user' , content : prompt }],
});
const duration = Date .now () - startTime;
console .log ('[Response]' , {
timestamp : new Date ().toISOString (),
duration,
usage : completion.usage ,
finishReason : completion.choices [0 ].finish_reason ,
});
return completion;
} catch (error) {
console .error ('[Error]' , {
timestamp : new Date ().toISOString (),
duration : Date .now () - startTime,
error,
});
throw error;
}
}
}
Best Practices
Model Selection :
Use fast models (Haiku, Flash) for simple tasks
Use flagship models (Sonnet, GPT-4) for complex reasoning
Consider context size requirements
Test multiple models for your use case
Cost Optimization :
Estimate costs before requests
Use cheaper models when possible
Implement token limits
Cache common responses
Batch similar requests
Streaming :
Always use streaming for user-facing apps
Handle connection interruptions
Show progress indicators
Buffer partial responses
Error Handling :
Implement retry logic with exponential backoff
Use model fallbacks for reliability
Log all errors for debugging
Handle rate limits gracefully
Prompt Engineering :
Use system prompts for consistency
Implement few-shot learning for specific tasks
Use chain-of-thought for complex reasoning
Keep prompts concise to reduce costs
Rate Limiting :
Respect API rate limits
Implement request queuing
Use exponential backoff
Monitor usage metrics
Security :
Never expose API keys in client code
Use environment variables
Implement server-side proxies
Validate user inputs
Monitoring :
Track token usage
Monitor response times
Log errors and failures
Analyze model performance
Common Pitfalls ❌ Exposing API keys in frontend :
const client = new OpenAI ({
baseURL : 'https://openrouter.ai/api/v1' ,
apiKey : 'sk-or-v1-...' ,
});
✅ Correct - Server-side proxy :
app.post ('/api/chat' , async (req, res) => {
const { prompt } = req.body ;
const completion = await client.chat .completions .create ({
model : 'anthropic/claude-3.5-sonnet' ,
messages : [{ role : 'user' , content : prompt }],
});
res.json (completion);
});
❌ Not handling streaming errors :
for await (const chunk of stream) {
console .log (chunk.choices [0 ].delta .content );
}
✅ Correct - with error handling :
try {
for await (const chunk of stream) {
const content = chunk.choices [0 ]?.delta ?.content || '' ;
process.stdout .write (content);
}
} catch (error) {
console .error ('Stream error:' , error);
}
const promises = prompts.map (prompt => chat (prompt));
await Promise .all (promises);
✅ Correct - with rate limiting :
const results = [];
for (let i = 0 ; i < prompts.length ; i += 5 ) {
const batch = prompts.slice (i, i + 5 );
const batchResults = await Promise .all (batch.map (chat));
results.push (...batchResults);
await new Promise (r => setTimeout (r, 1000 ));
}
Performance Optimization
Caching Responses const responseCache = new Map <string , string >();
async function cachedChat (prompt : string , model : string ) {
const cacheKey = `${model} :${prompt} ` ;
if (responseCache.has (cacheKey)) {
console .log ('Cache hit' );
return responseCache.get (cacheKey)!;
}
const completion = await client.chat .completions .create ({
model,
messages : [{ role : 'user' , content : prompt }],
});
const response = completion.choices [0 ].message .content || '' ;
responseCache.set (cacheKey, response);
return response;
}
Parallel Processing async function parallelChat (prompts : string [], model : string ) {
const results = await Promise .all (
prompts.map (prompt =>
client.chat .completions .create ({
model,
messages : [{ role : 'user' , content : prompt }],
})
)
);
return results.map (r => r.choices [0 ].message .content );
}
Resources
Related Skills
MCP Servers : Integration with Model Context Protocol (when built)
TypeScript API Integration : Type-safe OpenRouter clients
Python API Integration : Python SDK usage patterns
Summary
OpenRouter provides unified access to 200+ LLMs
OpenAI-compatible API for easy migration
Cost optimization through model selection and token management
Streaming for responsive user experiences
Function calling for tool integration
Vision models for image understanding
Fallback strategies for reliability
Rate limiting and error handling essential
Perfect for multi-model apps, cost-sensitive deployments, avoiding vendor lock-in