openrouterteam/agent-skills/typescript-sdk

Claude Code and agent skill by openrouterteam/agent-skills

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Complete reference for integrating with 300+ AI models through the OpenRouter TypeScript SDK using the callModel pattern

Install

npx vskill@latest install openrouterteam/agent-skills/typescript-sdk

SKILL.md

OpenRouter TypeScript SDK

A comprehensive TypeScript SDK for interacting with OpenRouter's unified API, providing access to 300+ AI models through a single, type-safe interface. This skill enables AI agents to leverage the callModel pattern for text generation, tool usage, streaming, and multi-turn conversations.


Installation

bash
npm install @openrouter/sdk

Setup

Get your API key from openrouter.ai/settings/keys, then initialize:

typescript
import OpenRouter from '@openrouter/sdk';
const client = new OpenRouter({
apiKey: process.env.OPENROUTER_API_KEY
});

Authentication

The SDK supports two authentication methods: API keys for server-side applications and OAuth PKCE flow for user-facing applications.

API Key Authentication

The primary authentication method uses API keys from your OpenRouter account.

Obtaining an API Key
  1. Visit openrouter.ai/settings/keys
  2. Create a new API key
  3. Store securely in an environment variable
Environment Setup
bash
export OPENROUTER_API_KEY=sk-or-v1-your-key-here
Client Initialization
typescript
import OpenRouter from '@openrouter/sdk';
const client = new OpenRouter({
apiKey: process.env.OPENROUTER_API_KEY
});

The client automatically uses this key for all subsequent requests:

typescript
// API key is automatically included
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Hello!'
});
Get Current Key Metadata

Retrieve information about the currently configured API key:

typescript
const keyInfo = await client.apiKeys.getCurrentKeyMetadata();
console.log('Key name:', keyInfo.name);
console.log('Created:', keyInfo.createdAt);
API Key Management

Programmatically manage API keys:

typescript
// List all keys
const keys = await client.apiKeys.list();
// Create a new key
const newKey = await client.apiKeys.create({
name: 'Production API Key'
});
// Get a specific key by hash
const key = await client.apiKeys.get({
hash: 'sk-or-v1-...'
});
// Update a key
await client.apiKeys.update({
hash: 'sk-or-v1-...',
requestBody: {
name: 'Updated Key Name'
}
});
// Delete a key
await client.apiKeys.delete({
hash: 'sk-or-v1-...'
});
OAuth Authentication (PKCE Flow)

For user-facing applications where users should control their own API keys, OpenRouter supports OAuth with PKCE (Proof Key for Code Exchange). This flow allows users to generate API keys through a browser authorization flow without your application handling their credentials.

createAuthCode

Generate an authorization code and URL to start the OAuth flow:

typescript
const authResponse = await client.oAuth.createAuthCode({
callbackUrl: 'https://myapp.com/auth/callback'
});
// authResponse contains:
// - authorizationUrl: URL to redirect the user to
// - code: The authorization code for later exchange
console.log('Redirect user to:', authResponse.authorizationUrl);

Parameters:

ParameterTypeRequiredDescription
callbackUrlstringYesYour application's callback URL after user authorization

Browser Redirect:

typescript
// In a browser environment
window.location.href = authResponse.authorizationUrl;
// Or in a server-rendered app, return a redirect response
res.redirect(authResponse.authorizationUrl);
exchangeAuthCodeForAPIKey

After the user authorizes your application, they are redirected back to your callback URL with an authorization code. Exchange this code for an API key:

typescript
// In your callback handler
const code = req.query.code; // From the redirect URL
const apiKeyResponse = await client.oAuth.exchangeAuthCodeForAPIKey({
code: code
});
// apiKeyResponse contains:
// - key: The user's API key
// - Additional metadata about the key
const userApiKey = apiKeyResponse.key;
// Store securely for this user's future requests
await saveUserApiKey(userId, userApiKey);

Parameters:

ParameterTypeRequiredDescription
codestringYesThe authorization code from the OAuth redirect
Complete OAuth Flow Example
typescript
import OpenRouter from '@openrouter/sdk';
import express from 'express';
const app = express();
const client = new OpenRouter({
apiKey: process.env.OPENROUTER_API_KEY // Your app's key for OAuth operations
});
// Step 1: Initiate OAuth flow
app.get('/auth/start', async (req, res) => {
const authResponse = await client.oAuth.createAuthCode({
callbackUrl: 'https://myapp.com/auth/callback'
});
// Store any state needed for the callback
req.session.oauthState = { /* ... */ };
// Redirect user to OpenRouter authorization page
res.redirect(authResponse.authorizationUrl);
});
// Step 2: Handle callback and exchange code
app.get('/auth/callback', async (req, res) => {
const { code } = req.query;
if (!code) {
return res.status(400).send('Authorization code missing');
}
try {
const apiKeyResponse = await client.oAuth.exchangeAuthCodeForAPIKey({
code: code as string
});
// Store the user's API key securely
await saveUserApiKey(req.session.userId, apiKeyResponse.key);
res.redirect('/dashboard?auth=success');
} catch (error) {
console.error('OAuth exchange failed:', error);
res.redirect('/auth/error');
}
});
// Step 3: Use the user's API key for their requests
app.post('/api/chat', async (req, res) => {
const userApiKey = await getUserApiKey(req.session.userId);
// Create a client with the user's key
const userClient = new OpenRouter({
apiKey: userApiKey
});
const result = userClient.callModel({
model: 'openai/gpt-5-nano',
input: req.body.message
});
const text = await result.getText();
res.json({ response: text });
});
Security Best Practices
  1. Environment Variables: Store API keys in environment variables, never in code
  2. Key Rotation: Rotate keys periodically using the key management API
  3. Environment Separation: Use different keys for development, staging, and production
  4. OAuth for Users: Use the OAuth PKCE flow for user-facing apps to avoid handling user credentials
  5. Secure Storage: Store user API keys encrypted in your database
  6. Minimal Scope: Create keys with only the permissions needed

Core Concepts: callModel

The callModel function is the primary interface for text generation. It provides a unified, type-safe way to interact with any supported model.

Basic Usage
typescript
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Explain quantum computing in one sentence.',
});
const text = await result.getText();
Key Benefits
  • Type-safe parameters with full IDE autocomplete
  • Auto-generated from OpenAPI specs - automatically updates with new models
  • Multiple consumption patterns - text, streaming, structured data
  • Automatic tool execution with multi-turn support

Input Formats

The SDK accepts flexible input types for the input parameter:

String Input

A simple string becomes a user message:

typescript
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Hello, how are you?'
});
Message Arrays

For multi-turn conversations:

typescript
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: [
{ role: 'user', content: 'What is the capital of France?' },
{ role: 'assistant', content: 'The capital of France is Paris.' },
{ role: 'user', content: 'What is its population?' }
]
});
Multimodal Content

Including images and text:

typescript
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: [
{
role: 'user',
content: [
{ type: 'text', text: 'What is in this image?' },
{ type: 'image_url', image_url: { url: 'https://example.com/image.png' } }
]
}
]
});
System Instructions

Use the instructions parameter for system-level guidance:

typescript
const result = client.callModel({
model: 'openai/gpt-5-nano',
instructions: 'You are a helpful coding assistant. Be concise.',
input: 'How do I reverse a string in Python?'
});

Response Methods

The result object provides multiple methods for consuming the response:

MethodPurpose
getText()Get complete text after all tools complete
getResponse()Full response object with token usage
getTextStream()Stream text deltas as they arrive
getReasoningStream()Stream reasoning tokens (for o1/reasoning models)
getToolCallsStream()Stream tool calls as they complete
getText()
typescript
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Write a haiku about coding'
});
const text = await result.getText();
console.log(text);
getResponse()
typescript
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Hello!'
});
const response = await result.getResponse();
console.log('Text:', response.text);
console.log('Token usage:', response.usage);
getTextStream()
typescript
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Write a short story'
});
for await (const delta of result.getTextStream()) {
process.stdout.write(delta);
}

Tool System

Create strongly-typed tools using Zod schemas for automatic validation and type inference.

Defining Tools
typescript
import { tool } from '@openrouter/sdk';
import { z } from 'zod';
const weatherTool = tool({
name: 'get_weather',
description: 'Get current weather for a location',
inputSchema: z.object({
location: z.string().describe('City name'),
units: z.enum(['celsius', 'fahrenheit']).optional().default('celsius')
}),
outputSchema: z.object({
temperature: z.number(),
conditions: z.string(),
humidity: z.number()
}),
execute: async (params) => {
// Implement weather fetching logic
return {
temperature: 22,
conditions: 'Sunny',
humidity: 45
};
}
});
Using Tools with callModel
typescript
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'What is the weather in Paris?',
tools: [weatherTool]
});
const text = await result.getText();
// The SDK automatically executes the tool and continues the conversation
Tool Types
Regular Tools

Standard execute functions that return a result:

typescript
const calculatorTool = tool({
name: 'calculate',
description: 'Perform mathematical calculations',
inputSchema: z.object({
expression: z.string()
}),
execute: async ({ expression }) => {
return { result: eval(expression) };
}
});
Generator Tools

Yield progress events using eventSchema:

typescript
const searchTool = tool({
name: 'web_search',
description: 'Search the web',
inputSchema: z.object({ query: z.string() }),
eventSchema: z.object({
type: z.literal('progress'),
message: z.string()
}),
outputSchema: z.object({ results: z.array(z.string()) }),
execute: async function* ({ query }) {
yield { type: 'progress', message: 'Searching...' };
yield { type: 'progress', message: 'Processing results...' };
return { results: ['Result 1', 'Result 2'] };
}
});
Manual Tools

Set execute: false to handle tool calls yourself:

typescript
const manualTool = tool({
name: 'user_confirmation',
description: 'Request user confirmation',
inputSchema: z.object({ message: z.string() }),
execute: false
});

Multi-Turn Conversations with Stop Conditions

Control automatic tool execution with stop conditions:

typescript
import { stepCountIs, maxCost, hasToolCall } from '@openrouter/sdk';

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
27
Repository forks
10
7-day trend score
17

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 27 Apr 2026, 6 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/openrouterteam/agent-skills/typescript-sdk/badge)](https://verified-skill.com/skills/openrouterteam/agent-skills/typescript-sdk)

Something wrong with this skill or its page? Tell us.