Node.js / TypeScript SDK
Installation
Section titled “Installation”npm install tokenrouterQuick Start
Section titled “Quick Start”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!'});Configuration
Section titled “Configuration”const client = new Tokenrouter({ apiKey: 'tr_...', environment: 'production', // or 'local' timeout: 60000, // milliseconds});Making Requests
Section titled “Making Requests”Basic Request
Section titled “Basic Request”const response = await client.responses.create({ model: 'auto:balance', input: 'What is TypeScript?'});With Options
Section titled “With Options”const response = await client.responses.create({ model: 'gpt-4o:quality', input: 'Explain async/await', temperature: 0.7, max_output_tokens: 1000});Streaming
Section titled “Streaming”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); }}Routing Rules
Section titled “Routing Rules”Manage custom routing logic to control how requests are routed.
Create Routing Rule
Section titled “Create Routing Rule”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}`);List Routing Rules
Section titled “List Routing Rules”const rules = await client.routingRules.list();
rules.data.forEach(rule => { console.log(`${rule.name} (Priority: ${rule.priority})`);});Get Routing Rule
Section titled “Get Routing Rule”const rule = await client.routingRules.retrieve(123);console.log(rule.data);Update Routing Rule
Section titled “Update Routing Rule”await client.routingRules.update(123, { priority: 150, is_enabled: false});Delete Routing Rule
Section titled “Delete Routing Rule”await client.routingRules.delete(123);Match Conditions
Section titled “Match Conditions”// Input contains text (case-insensitive)match_json: { contains: 'code review' }
// Match metadatamatch_json: { metadata_equals: { task: 'documentation' } }
// Match routing modematch_json: { mode: 'balanced' }
// Multiple conditions (all must match)match_json: { task: 'coding', mode: 'quality'}Actions
Section titled “Actions”// Force specific provideraction_json: { set_provider: 'anthropic' }
// Force specific modelaction_json: { set_model: 'gpt-4o' }
// Override routing modeaction_json: { set_mode: 'cost' }
// Add warningaction_json: { add_warning: { message: 'Using beta routing' }}
// Combine actionsaction_json: { set_provider: 'openai', set_model: 'gpt-4o', set_mode: 'quality'}Firewall Rules
Section titled “Firewall Rules”Protect your application by filtering sensitive content in requests and responses.
Create Firewall Rule
Section titled “Create Firewall Rule”// Block credit card numbersconst 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 Sensitive Data
Section titled “Mask Sensitive Data”// Mask email addresses in responsesconst 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 on Content
Section titled “Warn on Content”// Warn when profanity detectedconst rule = await client.firewallRules.create({ name: 'Warn on Profanity', priority: 50, is_enabled: true, scope: 'response', type: 'substring', pattern: 'inappropriate', action: 'warn'});List Firewall Rules
Section titled “List Firewall Rules”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}`);});Get Firewall Rule
Section titled “Get Firewall Rule”const rule = await client.firewallRules.retrieve(123);console.log(rule.data);Update Firewall Rule
Section titled “Update Firewall Rule”// Disable temporarilyawait client.firewallRules.update(123, { is_enabled: false});
// Change actionawait client.firewallRules.update(123, { action: 'warn'});Delete Firewall Rule
Section titled “Delete Firewall Rule”await client.firewallRules.delete(123);Rule Scopes
Section titled “Rule Scopes”prompt- Apply to user input before sending to LLMresponse- Apply to LLM output before returning to user
Rule Types
Section titled “Rule Types”substring- Case-insensitive text matchingregex- Regular expression matching (PCRE-compatible)
Actions
Section titled “Actions”block- Reject request/response with 422 errormask- Replace matched content with replacement textwarn- Allow but add warning to metadata
Common Patterns
Section titled “Common Patterns”// Social Security Numberspattern: '\\d{3}-\\d{2}-\\d{4}'
// Phone Numberspattern: '\\+?1?\\s?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}'
// Email Addressespattern: '[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}'Error Handling
Section titled “Error Handling”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); }}Handle Firewall Blocks
Section titled “Handle Firewall Blocks”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); }}TypeScript Types
Section titled “TypeScript Types”All request and response types are fully typed:
import type { ResponseCreateParams, ResponseObject, RoutingRule, RoutingRuleCreateParams, FirewallRule, FirewallRuleCreateParams} from 'tokenrouter';Advanced Usage
Section titled “Advanced Usage”Conditional Routing
Section titled “Conditional Routing”// Create multiple rules for different scenariosawait 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' }});Multi-Layer Protection
Section titled “Multi-Layer Protection”// Layer 1: Block PII in promptsawait 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 responsesawait 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 keywordsawait client.firewallRules.create({ name: 'Warn on Sensitive Terms', priority: 80, is_enabled: true, scope: 'response', type: 'substring', pattern: 'confidential', action: 'warn'});