Back to Documentation
SDK Reference

TypeScript SDK

The official TypeScript client for SkillRouter. Full type safety, tree-shakable, and works in Node.js, Deno, and edge runtimes.

View on GitHub

Installation

Install the SDK using your preferred package manager. Requires Node.js 18+ or a compatible runtime.

npm i @skillrouter/sdk

Or with other package managers:yarn add @skillrouter/sdk / pnpm add @skillrouter/sdk

Quick Start

Initialize the client and start discovering skills with full type inference out of the box.

import { SkillRouter } from "@skillrouter/sdk";

// Initialize the client
const client = new SkillRouter({ apiKey: "sr_your_api_key" });

// Discover the best skill for a task
const result = await client.discover("Send a welcome email to new users");
console.log(result.skill.name);   // "sendgrid-send-email"
console.log(result.confidence);    // 0.97

// Execute the skill
const response = await client.execute(result.skill.id, {
  to: "user@example.com",
  subject: "Welcome!",
  body: "Thanks for signing up.",
});
console.log(response.status); // "success"

Client Initialization

The client constructor accepts a typed configuration object. All options except apiKey are optional.

import { SkillRouter } from "@skillrouter/sdk";

const client = new SkillRouter({
  apiKey: "sr_your_api_key",                      // Required
  baseUrl: "https://api.skillrouter.dev",          // Optional
  timeout: 30_000,                                 // Optional, ms
  maxRetries: 3,                                   // Optional
});

// Or read the API key from SKILLROUTER_API_KEY env var
const client = new SkillRouter();

Full Type Safety

Every method, parameter, and response is fully typed. Use generics to get precise types for skill execution results.

import type { Skill, DiscoverResult, ExecuteResponse } from "@skillrouter/sdk";

// Typed discovery results
const result: DiscoverResult = await client.discover("Send an email");

// Generic execute for typed responses
interface PaymentResult {
  paymentId: string;
  status: "succeeded" | "pending" | "failed";
  amount: number;
}

const response = await client.execute<PaymentResult>(
  "stripe-checkout",
  { amount: 2999, currency: "usd" }
);

// response.data is fully typed as PaymentResult
console.log(response.data.paymentId);   // string
console.log(response.data.status);       // "succeeded" | "pending" | "failed"

// Skill type includes all metadata
const skills: Skill[] = (await client.listSkills()).items;
skills.forEach((s) => {
  s.id;          // string
  s.name;        // string
  s.provider;    // string
  s.category;    // SkillCategory
});

Core Methods

discover(query, options?)

Finds the best matching skill for a natural language query using semantic matching.

const result = await client.discover("Process a credit card payment", {
  category: "payments",    // Optional filter
  topK: 3,                 // Return top 3 matches
  threshold: 0.8,          // Minimum confidence
});

console.log(result.skill.id);       // "stripe-checkout"
console.log(result.confidence);      // 0.95

// Multiple matches
result.matches.forEach((match) => {
  console.log(`${match.skill.name}: ${match.confidence}`);
});

execute<T>(skillId, params)

Executes a skill with the given parameters. Supports generics for typed responses.

const response = await client.execute("stripe-checkout", {
  amount: 2999,
  currency: "usd",
  customerEmail: "buyer@example.com",
});

console.log(response.status);       // "success"
console.log(response.data);         // { paymentId: "pi_abc123", ... }
console.log(response.latencyMs);    // 230

listSkills(options?)

Returns a paginated list of available skills with optional filters.

const skills = await client.listSkills({
  category: "payments",
  provider: "stripe",
  page: 1,
  perPage: 20,
});

skills.items.forEach((skill) => {
  console.log(`${skill.id}: ${skill.name}`);
});

console.log(`Total: ${skills.total}`);

Error Handling

The SDK throws typed error classes that you can catch and narrow using instanceof.

import {
  SkillRouterError,        // Base error class
  AuthenticationError,     // Invalid or missing API key
  RateLimitError,          // Rate limit exceeded
  SkillNotFoundError,      // Skill ID does not exist
  ExecutionError,          // Skill execution failed
  ValidationError,         // Invalid parameters
} from "@skillrouter/sdk";

try {
  const response = await client.execute("stripe-checkout", {
    amount: 2999,
  });
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error("Check your API key");
  } else if (error instanceof RateLimitError) {
    console.error(`Rate limited. Retry after ${error.retryAfter}ms`);
  } else if (error instanceof ValidationError) {
    // Typed validation errors
    error.errors.forEach((e) => {
      console.error(`${e.field}: ${e.message}`);
    });
  } else if (error instanceof ExecutionError) {
    console.error(`Execution failed: ${error.message}`);
  } else if (error instanceof SkillRouterError) {
    console.error(`Unexpected error: ${error.message}`);
  }
}

Tip: All error classes extend SkillRouterError, which itself extends Error. Each error includes a code property for programmatic handling.