Skip to content

Node.js / TypeScript SDK

Terminal window
npm install tokenrouter
import Tokenrouter from 'tokenrouter';
const client = new Tokenrouter({
apiKey: process.env.TOKENROUTER_API_KEY
});
const response = await client.responses.create({
model: 'auto:balance',
input: 'Hello, world!'
});
const client = new Tokenrouter({
apiKey: 'tr_...',
environment: 'production', // or 'local'
timeout: 60000, // milliseconds
});
const response = await client.responses.create({
model: 'auto:balance',
input: 'What is TypeScript?'
});
const response = await client.responses.create({
model: 'gpt-4o:quality',
input: 'Explain async/await',
temperature: 0.7,
max_output_tokens: 1000
});
const stream = await client.responses.create({
model: 'auto:balance',
input: 'Write a story',
stream: true
});
for await (const chunk of stream) {
if (chunk.event === 'content.delta') {
process.stdout.write(chunk.delta.text);
}
}

Manage custom routing logic to control how requests are routed.

const rule = await client.routingRules.create({
name: 'Coding Tasks → OpenAI',
priority: 100,
is_enabled: true,
match_json: {
task: 'coding'
},
action_json: {
set_provider: 'openai',
set_model: 'gpt-4o'
}
});
console.log(`Created rule: ${rule.data.id}`);
const rules = await client.routingRules.list();
rules.data.forEach(rule => {
console.log(`${rule.name} (Priority: ${rule.priority})`);
});
const rule = await client.routingRules.retrieve(123);
console.log(rule.data);
await client.routingRules.update(123, {
priority: 150,
is_enabled: false
});
await client.routingRules.delete(123);
// Input contains text (case-insensitive)
match_json: { contains: 'code review' }
// Match metadata
match_json: { metadata_equals: { task: 'documentation' } }
// Match routing mode
match_json: { mode: 'balanced' }
// Multiple conditions (all must match)
match_json: {
task: 'coding',
mode: 'quality'
}
// Force specific provider
action_json: { set_provider: 'anthropic' }
// Force specific model
action_json: { set_model: 'gpt-4o' }
// Override routing mode
action_json: { set_mode: 'cost' }
// Add warning
action_json: {
add_warning: { message: 'Using beta routing' }
}
// Combine actions
action_json: {
set_provider: 'openai',
set_model: 'gpt-4o',
set_mode: 'quality'
}

Protect your application by filtering sensitive content in requests and responses.

// Block credit card numbers
const rule = await client.firewallRules.create({
name: 'Block Credit Cards',
priority: 100,
is_enabled: true,
scope: 'prompt',
type: 'regex',
pattern: '\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}',
action: 'block'
});
// Mask email addresses in responses
const rule = await client.firewallRules.create({
name: 'Mask Email Addresses',
priority: 80,
is_enabled: true,
scope: 'response',
type: 'regex',
pattern: '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}',
action: 'mask',
replacement: '[EMAIL_REDACTED]'
});
// Warn when profanity detected
const rule = await client.firewallRules.create({
name: 'Warn on Profanity',
priority: 50,
is_enabled: true,
scope: 'response',
type: 'substring',
pattern: 'inappropriate',
action: 'warn'
});
const rules = await client.firewallRules.list();
rules.data.forEach(rule => {
console.log(`${rule.name} (${rule.action})`);
console.log(` Scope: ${rule.scope}`);
console.log(` Pattern: ${rule.pattern}`);
});
const rule = await client.firewallRules.retrieve(123);
console.log(rule.data);
// Disable temporarily
await client.firewallRules.update(123, {
is_enabled: false
});
// Change action
await client.firewallRules.update(123, {
action: 'warn'
});
await client.firewallRules.delete(123);
  • prompt - Apply to user input before sending to LLM
  • response - Apply to LLM output before returning to user
  • substring - Case-insensitive text matching
  • regex - Regular expression matching (PCRE-compatible)
  • block - Reject request/response with 422 error
  • mask - Replace matched content with replacement text
  • warn - Allow but add warning to metadata
// Social Security Numbers
pattern: '\\d{3}-\\d{2}-\\d{4}'
// Phone Numbers
pattern: '\\+?1?\\s?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}'
// Email Addresses
pattern: '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}'
// API Keys (OpenAI format)
pattern: 'sk-[a-zA-Z0-9]{32,}'
// Credit Cards (any format)
pattern: '\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}'
try {
const response = await client.responses.create({...});
} catch (error) {
if (error instanceof Tokenrouter.APIError) {
console.error('API Error:', error.message);
console.error('Status:', error.status);
console.error('Type:', error.type);
}
}
try {
const response = await client.responses.create({
model: 'auto:balance',
input: 'My credit card is 4532-1234-5678-9010'
});
} catch (error) {
if (error instanceof Tokenrouter.APIError && error.status === 422) {
console.error('Request blocked by firewall');
console.error('Reason:', error.message);
}
}

All request and response types are fully typed:

import type {
ResponseCreateParams,
ResponseObject,
RoutingRule,
RoutingRuleCreateParams,
FirewallRule,
FirewallRuleCreateParams
} from 'tokenrouter';
// Create multiple rules for different scenarios
await client.routingRules.create({
name: 'Complex Analysis → GPT-4',
priority: 100,
is_enabled: true,
match_json: {
contains: ['analyze', 'complex'],
mode: 'quality'
},
action_json: {
set_provider: 'openai',
set_model: 'gpt-4o'
}
});
await client.routingRules.create({
name: 'Simple Tasks → Cost Mode',
priority: 50,
is_enabled: true,
match_json: {
contains: ['summarize', 'list']
},
action_json: {
set_mode: 'cost'
}
});
// Layer 1: Block PII in prompts
await client.firewallRules.create({
name: 'Block PII in Input',
priority: 100,
is_enabled: true,
scope: 'prompt',
type: 'regex',
pattern: '\\d{3}-\\d{2}-\\d{4}|\\d{16}',
action: 'block'
});
// Layer 2: Mask emails in responses
await client.firewallRules.create({
name: 'Mask Emails in Output',
priority: 90,
is_enabled: true,
scope: 'response',
type: 'regex',
pattern: '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}',
action: 'mask',
replacement: '[REDACTED]'
});
// Layer 3: Warn on sensitive keywords
await client.firewallRules.create({
name: 'Warn on Sensitive Terms',
priority: 80,
is_enabled: true,
scope: 'response',
type: 'substring',
pattern: 'confidential',
action: 'warn'
});