SDK

Detailed TypeScript SDK guide for direct AgentRouter integrations
View as Markdown

The TypeScript SDK is the best integration surface when you are building directly on AgentRouter from a server, worker, CLI, or agent runtime.

It stays capability-first:

  1. list domains
  2. inspect capabilities
  3. inspect routes or contract
  4. recommend a route
  5. execute explicitly

Use the API Reference tab for endpoint-level HTTP detail. Use this page for SDK install guidance, integration patterns, and working examples.

Why Start With The SDK

Use the SDK when you want:

  • one explicit client object
  • typed catalog discovery
  • typed recommend and execute flows
  • one place for API key, session token, and timeout configuration
  • helper namespaces for email, enrichment, social, post, and broadcast
  • raw response access when you need domain-specific fields without losing normalized metadata

Use SKILL.md when another coding agent should read instructions and make HTTP calls itself.

Use CLI when a human operator, support engineer, or CI job should run the same capability-first flow from a terminal.

Use MCP when the runtime is MCP-compatible and you want hosted tool exposure.

Install

npm install @agentrouter/agentrouter

The same package also ships the agentrouter CLI. See CLI when you want terminal-first workflows on top of the same SDK semantics.

Create The Client

import {
AgentRouterClient,
DEFAULT_AGENTIC_API_BASE_URL,
} from "@agentrouter/agentrouter";
const client = new AgentRouterClient({
apiKey: process.env.AGENTIC_API_KEY,
baseUrl:
process.env.AGENTIC_API_BASE_URL ?? DEFAULT_AGENTIC_API_BASE_URL,
timeoutMs: 20_000,
});

Use this SDK from server-side runtimes only. Do not expose AGENTIC_API_KEY in browser code.

1

Discover the catalog

const domains = await client.catalog.domains.list();
const capabilities = await client.catalog.capabilities.list("email");
2

Inspect contract and routes

const contract = await client.catalog.capabilities.contract("email", "send");
const routes = await client.catalog.capabilities.routes("email", "send");
3

Recommend a route

const recommendation = await client.capabilities.recommend({
domain: "email",
capability: "send",
input: {
optimizationPreferences: ["cost", "quality"],
},
});
4

Execute explicitly

const result = await client.capabilities.execute({
domain: "email",
capability: "send",
input: {
to: "maya@example.com",
subject: "Hello from AgentRouter",
html: "<p>Hello</p>",
},
provider: recommendation.recommendedProvider,
allowFallback: true,
});
5

Inspect wallet and usage

const wallet = await client.wallet.get();
const usage = await client.usage.list({ limit: 20 });

Catalog First

const domains = await client.catalog.domains.list();
const capabilities = await client.catalog.capabilities.list("email");
const sendContract = await client.catalog.capabilities.contract("email", "send");
const sendRoutes = await client.catalog.capabilities.routes("email", "send");

The catalog is the source of truth for:

  • canonical capability IDs
  • capability contracts
  • capability route metadata
  • whether a domain supports intent routing

Generic Capability Methods

const recommendation = await client.capabilities.recommend({
domain: "email",
capability: "send",
input: {
optimizationPreferences: ["cost", "quality"],
sender: {
mode: "platform_managed",
replyTo: "ops@example.com",
},
},
});
const result = await client.capabilities.execute({
domain: "email",
capability: "send",
input: {
to: "maya@example.com",
subject: "Hello from AgentRouter",
html: "<p>Hello</p>",
},
provider: recommendation.recommendedProvider,
allowFallback: true,
});

The generic capability methods are the stable contract.

Broadcast Example: Quote First, Approve Send Separately

broadcast.message.quote is live. broadcast.message.send is mapped but intentionally gated because one live execute creates a real public post.

const quote = await client.capabilities.execute({
domain: "broadcast",
capability: "message-quote",
routeKey: "broadcast.message.quote.billboard.mpp",
input: {},
allowFallback: false,
});
const sendRecommendation = await client.capabilities.recommend({
domain: "broadcast",
capability: "message-send",
input: {
text: "Launch update goes here.",
optimizationPreferences: ["quality"],
},
});

Translation Example: DeepL Rephrase

translation.text.rephrase.deepl.mpp is live after the May 5, 2026 paid route-by-route retest. Use the generic capability methods and fetch route context before execution so your payload uses text, targetLanguage, and optional tone.

const routeContext = await client.catalog.routes.context(
"translation.text.rephrase.deepl.mpp",
);
const rewrite = await client.capabilities.execute({
domain: "translation",
capability: "text-rephrase",
routeKey: "translation.text.rephrase.deepl.mpp",
input: {
text: "Please make this product update friendlier.",
targetLanguage: "EN-US",
tone: "prefer_friendly",
},
allowFallback: false,
});
console.log(rewrite.rewrittenText);

Geo Example: Abstract Timezone Conversion

geo.time.current.abstract-timezone.mpp and geo.time.convert.abstract-timezone.mpp are live after the May 9, 2026 paid route-by-route smoke. Use generic capability methods and fetch route context before execution so your payload uses location for current time or fromLocation, toLocation, and optional datetime for conversion.

const routeContext = await client.catalog.routes.context(
"geo.time.convert.abstract-timezone.mpp",
);
const converted = await client.capabilities.execute({
domain: "geo",
capability: "time-convert",
routeKey: "geo.time.convert.abstract-timezone.mpp",
input: {
fromLocation: "Los Angeles, CA",
toLocation: "Tokyo, Japan",
datetime: "2026-05-08 09:30:00",
},
allowFallback: false,
});
console.log(converted.convertedTime);

Models Example: DeepSeek Chat Completion

models.chat.complete.deepseek.mpp, models.code.complete.deepseek.mpp, and models.list.deepseek.mpp are live through the generic capability surface after the May 5, 2026 production-mode smoke. Fetch route context before execution so your payload uses a supported model id such as deepseek-v4-flash.

const routeContext = await client.catalog.routes.context(
"models.chat.complete.deepseek.mpp",
);
const modelChat = await client.capabilities.execute({
domain: "models",
capability: "chat-complete",
routeKey: "models.chat.complete.deepseek.mpp",
input: {
model: "deepseek-v4-flash",
messages: [
{
role: "user",
content: "Say AgentRouter DeepSeek smoke OK.",
},
],
},
allowFallback: false,
});
console.log(modelChat.completionText);

Text Analysis Example: Recommend And Context Only

text.analyze.diffbot-nl.mpp is mapped and recommendable through Diffbot NL, but it is not live for execution yet. Direct Diffbot NL MPP wrapper checks on May 5, 2026 returned HTTP 429 before payment, so no AgentRouter credits were charged. Use recommend and route context until canExecuteNow is true and a paid route smoke succeeds.

const textRecommendation = await client.capabilities.recommend({
domain: "text",
capability: "analyze",
input: {
provider: "diffbot-nl",
content: "AgentRouter routes text analysis through Diffbot NL.",
fields: "entities,sentiment,language",
optimizationPreferences: ["quality"],
},
});
const textContext = await client.catalog.routes.context(
"text.analyze.diffbot-nl.mpp",
);
console.log(textRecommendation.recommendedRouteKey);
console.log(textRecommendation.canExecuteNow);
console.log(textContext.routeKey);

Media Example: fal Image Routes

fal image generation and image edit are live on MPP image routes. media.video.generate.fal.mpp remains gated after upstream paymentauth 524 timeouts reproduced outside AgentRouter, so use recommend and route context for video generation until paid smoke evidence exists.

const imageContext = await client.catalog.routes.context(
"media.image.generate.fal.mpp",
);
const heroImage = await client.capabilities.execute({
domain: "media",
capability: "image-generate",
routeKey: "media.image.generate.fal.mpp",
input: {
prompt: "Create a clean launch hero image for an AI developer tool",
aspectRatio: "16:9",
},
provider: "fal",
allowFallback: false,
});
console.log(imageContext.routeKey);
console.log(heroImage.primaryImageUrl);

Web And Enrichment Example: Diffbot Routes

web.extract.diffbot.mpp, enrichment.people.enrich.diffbot.mpp, and enrichment.company.enrich.diffbot.mpp are live after the May 5, 2026 route-by-route retest. Fetch route context before execution so the SDK payload matches the selected Diffbot route.

const extractContext = await client.catalog.routes.context(
"web.extract.diffbot.mpp",
);
const personContext = await client.catalog.routes.context(
"enrichment.people.enrich.diffbot.mpp",
);
const companyContext = await client.catalog.routes.context(
"enrichment.company.enrich.diffbot.mpp",
);
const article = await client.capabilities.execute({
domain: "web",
capability: "extract",
routeKey: "web.extract.diffbot.mpp",
input: {
url: "https://www.example.com/article",
},
allowFallback: false,
});
const person = await client.capabilities.execute({
domain: "enrichment",
capability: "people-enrich",
routeKey: "enrichment.people.enrich.diffbot.mpp",
input: {
fullName: "Sam Altman",
companyName: "OpenAI",
},
allowFallback: false,
});
const company = await client.capabilities.execute({
domain: "enrichment",
capability: "company-enrich",
routeKey: "enrichment.company.enrich.diffbot.mpp",
input: {
companyName: "OpenAI",
domain: "openai.com",
},
allowFallback: false,
});
console.log(article.routeKey);
console.log(person.person);
console.log(company.company);

Travel Example: Pin FlightAPI Airport Operations

When you need one concrete travel provider, fetch route context first and then pin the routeKey during execute:

const routeContext = await client.catalog.routes.context(
"travel.airport.operations.flightapi.mpp",
);
const airportOperations = await client.capabilities.execute({
domain: "travel",
capability: "airport-operations",
routeKey: "travel.airport.operations.flightapi.mpp",
input: {
iataCode: "JFK",
mode: "departures",
limit: 1,
},
provider: "flightapi",
allowFallback: false,
});

Use the route context to confirm route-specific fields before execution. FlightAPI airport operations passed a May 8, 2026 production smoke through travel.airport.operations.flightapi.mpp.

Domain Helpers And Examples

The SDK also exposes high-value helper namespaces:

client.email;
client.enrichment;
client.social;
client.post;
client.broadcast;
const recommendation = await client.email.send.recommend({
optimizationPreferences: ["cost"],
});
const sent = await client.email.send.execute(
{
to: "maya@example.com",
subject: "Hello from AgentRouter",
html: "<p>Hello</p>",
},
{
provider: recommendation.recommendedProvider,
allowFallback: true,
},
);

Response Model

Recommend, route, and execute responses preserve normalized fields and the raw backend payload:

const recommendation = await client.capabilities.recommend({
domain: "email",
capability: "send",
input: {
optimizationPreferences: ["cost", "quality"],
},
});
console.log(recommendation.recommendedProvider);
console.log(recommendation.domainKey);
console.log(recommendation.capabilityId);
console.log(recommendation.raw);

That lets you keep a stable integration while still inspecting domain-specific fields when needed.

Raw Requests And Auth

For endpoints that are not wrapped yet, you can fall back to the raw client:

const wallet = await client.raw.request<{
userId: string;
balanceCredits: number;
}>({
path: "/wallet",
authMode: "apiKey",
});

The SDK supports:

  • API key auth for normal server-side usage
  • session token auth for session-backed flows
  • userId passthrough for local development helpers
  • per-call timeoutMs overrides

Observe Wallet And Usage

const wallet = await client.wallet.get();
const usage = await client.usage.list({ limit: 20 });

The SDK keeps wallet and usage close to execution so developers can audit spend and route behavior without switching abstractions.

Compatibility Notes

  • Canonical capability IDs come from the catalog.
  • The canonical email inbox acquisition capability ID is inbox-acquire.
  • The backend still accepts the legacy alias inbox-buy.
  • The SDK exposes both client.email.inbox.acquire and client.email.inbox.buy, but both target the canonical capability under the hood.