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

1import {
2 AgentRouterClient,
3 DEFAULT_AGENTIC_API_BASE_URL,
4} from "@agentrouter/agentrouter";
5
6const client = new AgentRouterClient({
7 apiKey: process.env.AGENTIC_API_KEY,
8 baseUrl:
9 process.env.AGENTIC_API_BASE_URL ?? DEFAULT_AGENTIC_API_BASE_URL,
10 timeoutMs: 20_000,
11});

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

1

Discover the catalog

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

Inspect contract and routes

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

Recommend a route

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

Execute explicitly

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

Inspect wallet and usage

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

Catalog First

1const domains = await client.catalog.domains.list();
2const capabilities = await client.catalog.capabilities.list("email");
3const sendContract = await client.catalog.capabilities.contract("email", "send");
4const 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

1const recommendation = await client.capabilities.recommend({
2 domain: "email",
3 capability: "send",
4 input: {
5 optimizationPreferences: ["cost", "quality"],
6 sender: {
7 mode: "platform_managed",
8 replyTo: "ops@example.com",
9 },
10 },
11});
12
13const result = await client.capabilities.execute({
14 domain: "email",
15 capability: "send",
16 input: {
17 to: "maya@example.com",
18 subject: "Hello from AgentRouter",
19 html: "<p>Hello</p>",
20 },
21 provider: recommendation.recommendedProvider,
22 allowFallback: true,
23});

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.

1const quote = await client.capabilities.execute({
2 domain: "broadcast",
3 capability: "message-quote",
4 routeKey: "broadcast.message.quote.billboard.mpp",
5 input: {},
6 allowFallback: false,
7});
8
9const sendRecommendation = await client.capabilities.recommend({
10 domain: "broadcast",
11 capability: "message-send",
12 input: {
13 text: "Launch update goes here.",
14 optimizationPreferences: ["quality"],
15 },
16});

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.

1const routeContext = await client.catalog.routes.context(
2 "translation.text.rephrase.deepl.mpp",
3);
4
5const rewrite = await client.capabilities.execute({
6 domain: "translation",
7 capability: "text-rephrase",
8 routeKey: "translation.text.rephrase.deepl.mpp",
9 input: {
10 text: "Please make this product update friendlier.",
11 targetLanguage: "EN-US",
12 tone: "prefer_friendly",
13 },
14 allowFallback: false,
15});
16
17console.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.

1const routeContext = await client.catalog.routes.context(
2 "geo.time.convert.abstract-timezone.mpp",
3);
4
5const converted = await client.capabilities.execute({
6 domain: "geo",
7 capability: "time-convert",
8 routeKey: "geo.time.convert.abstract-timezone.mpp",
9 input: {
10 fromLocation: "Los Angeles, CA",
11 toLocation: "Tokyo, Japan",
12 datetime: "2026-05-08 09:30:00",
13 },
14 allowFallback: false,
15});
16
17console.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.

1const routeContext = await client.catalog.routes.context(
2 "models.chat.complete.deepseek.mpp",
3);
4
5const modelChat = await client.capabilities.execute({
6 domain: "models",
7 capability: "chat-complete",
8 routeKey: "models.chat.complete.deepseek.mpp",
9 input: {
10 model: "deepseek-v4-flash",
11 messages: [
12 {
13 role: "user",
14 content: "Say AgentRouter DeepSeek smoke OK.",
15 },
16 ],
17 },
18 allowFallback: false,
19});
20
21console.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.

1const textRecommendation = await client.capabilities.recommend({
2 domain: "text",
3 capability: "analyze",
4 input: {
5 provider: "diffbot-nl",
6 content: "AgentRouter routes text analysis through Diffbot NL.",
7 fields: "entities,sentiment,language",
8 optimizationPreferences: ["quality"],
9 },
10});
11
12const textContext = await client.catalog.routes.context(
13 "text.analyze.diffbot-nl.mpp",
14);
15
16console.log(textRecommendation.recommendedRouteKey);
17console.log(textRecommendation.canExecuteNow);
18console.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.

1const imageContext = await client.catalog.routes.context(
2 "media.image.generate.fal.mpp",
3);
4
5const heroImage = await client.capabilities.execute({
6 domain: "media",
7 capability: "image-generate",
8 routeKey: "media.image.generate.fal.mpp",
9 input: {
10 prompt: "Create a clean launch hero image for an AI developer tool",
11 aspectRatio: "16:9",
12 },
13 provider: "fal",
14 allowFallback: false,
15});
16
17console.log(imageContext.routeKey);
18console.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.

1const extractContext = await client.catalog.routes.context(
2 "web.extract.diffbot.mpp",
3);
4const personContext = await client.catalog.routes.context(
5 "enrichment.people.enrich.diffbot.mpp",
6);
7const companyContext = await client.catalog.routes.context(
8 "enrichment.company.enrich.diffbot.mpp",
9);
10
11const article = await client.capabilities.execute({
12 domain: "web",
13 capability: "extract",
14 routeKey: "web.extract.diffbot.mpp",
15 input: {
16 url: "https://www.example.com/article",
17 },
18 allowFallback: false,
19});
20
21const person = await client.capabilities.execute({
22 domain: "enrichment",
23 capability: "people-enrich",
24 routeKey: "enrichment.people.enrich.diffbot.mpp",
25 input: {
26 fullName: "Sam Altman",
27 companyName: "OpenAI",
28 },
29 allowFallback: false,
30});
31
32const company = await client.capabilities.execute({
33 domain: "enrichment",
34 capability: "company-enrich",
35 routeKey: "enrichment.company.enrich.diffbot.mpp",
36 input: {
37 companyName: "OpenAI",
38 domain: "openai.com",
39 },
40 allowFallback: false,
41});
42
43console.log(article.routeKey);
44console.log(person.person);
45console.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:

1const routeContext = await client.catalog.routes.context(
2 "travel.airport.operations.flightapi.mpp",
3);
4
5const airportOperations = await client.capabilities.execute({
6 domain: "travel",
7 capability: "airport-operations",
8 routeKey: "travel.airport.operations.flightapi.mpp",
9 input: {
10 iataCode: "JFK",
11 mode: "departures",
12 limit: 1,
13 },
14 provider: "flightapi",
15 allowFallback: false,
16});

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:

1client.email;
2client.enrichment;
3client.social;
4client.post;
5client.broadcast;
1const recommendation = await client.email.send.recommend({
2 optimizationPreferences: ["cost"],
3});
4
5const sent = await client.email.send.execute(
6 {
7 to: "maya@example.com",
8 subject: "Hello from AgentRouter",
9 html: "<p>Hello</p>",
10 },
11 {
12 provider: recommendation.recommendedProvider,
13 allowFallback: true,
14 },
15);

Response Model

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

1const recommendation = await client.capabilities.recommend({
2 domain: "email",
3 capability: "send",
4 input: {
5 optimizationPreferences: ["cost", "quality"],
6 },
7});
8
9console.log(recommendation.recommendedProvider);
10console.log(recommendation.domainKey);
11console.log(recommendation.capabilityId);
12console.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:

1const wallet = await client.raw.request<{
2 userId: string;
3 balanceCredits: number;
4}>({
5 path: "/wallet",
6 authMode: "apiKey",
7});

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

1const wallet = await client.wallet.get();
2const 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.