npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@signalwire/sdk

v3.7.1

Published

SignalWire AI Agents SDK for TypeScript/Node.js

Readme

SignalWire SDK for TypeScript

Build AI voice agents, control live calls over WebSocket, and manage every SignalWire resource over REST, all from one package.


export {}; // treat each example as a module (top-level await)
declare global {
  const callId: string;
  const signingKey: string;
  const signatureHeader: string;
  const fullUrl: string;
  const rawBodyString: string;
  const requestParams: Record<string, string>;
}

What's in this SDK

| Capability | What it does | Quick link | |-----------|-------------|------------| | AI Agents | Build voice agents that handle calls on their own. The platform runs the AI pipeline, and your code defines the persona, tools, and call flow. | Agent Guide | | RELAY Client | Control live calls and SMS/MMS in real time over WebSocket: answer, play, record, collect DTMF, conference, transfer, and more | RELAY docs | | REST Client | Manage SignalWire resources over HTTP: phone numbers, SIP endpoints, Fabric AI agents, video rooms, messaging, and the other REST API namespaces | REST docs |

Install the SDK from npm:

npm install @signalwire/sdk

The package installs its own documentation. npx sw-tsdocs prints a map of the SDK for the installed version, with the docs and examples on disk, and npx sw-tsdocs api <name> reads signatures and JSDoc from the installed declarations. If you're a coding agent working with the SDK, start there:

npx sw-tsdocs                 # the map: what the SDK does and where to start
npx sw-tsdocs agents          # one topic: concepts, files to read, examples, API
npx sw-tsdocs api AgentBase   # a signature, JSDoc and members

AI Agents

Each agent is a self-contained microservice that generates SWML (SignalWire Markup Language) and handles SWAIG (SignalWire AI Gateway) tool calls. The SignalWire platform runs the entire AI pipeline (STT, LLM, TTS), and your agent defines the behavior.

import { AgentBase, FunctionResult } from '@signalwire/sdk';

const agent = new AgentBase({
  name: 'my-agent',
  route: '/agent',
});

agent.addLanguage({ name: 'English', code: 'en-US', voice: 'inworld.Mark' });
agent.promptAddSection('Role', { body: 'You are a helpful assistant.' });

agent.defineTool({
  name: 'get_time',
  description: 'Get the current time',
  parameters: {},
  handler: () => new FunctionResult(`The time is ${new Date().toLocaleTimeString()}`),
});

agent.run(); // Starts HTTP server on port 3000

In a clone of this repository, swaig-test checks an agent without running a server. These commands list the example agent's tools, print its SWML, and call its get_time tool:

npx tsx src/cli/swaig-test.ts examples/simple-agent.ts --list-tools
npx tsx src/cli/swaig-test.ts examples/simple-agent.ts --dump-swml
npx tsx src/cli/swaig-test.ts examples/simple-agent.ts --exec get_time

Agent Features

An agent built on AgentBase gets these features:

  • Prompt Object Model (POM): structured prompt composition with promptAddSection()
  • SWAIG tools: functions defined with defineTool() that the AI calls mid-conversation. A tool's result is context for the model, and its actions can control the call.
  • Skills system: capabilities added in one line, such as await agent.addSkill(new DateTimeSkill())
  • Contexts and steps: structured multi-step workflows with navigation control
  • DataMap tools: tools that run on SignalWire's servers, calling REST APIs without your own webhook
  • Dynamic configuration: a per-request copy of the agent, configured for each call, for multi-tenant deployments
  • Call flow control: pre-answer, post-answer, and post-AI verb insertion
  • Prefab agents: ready-to-use archetypes (InfoGatherer, Survey, FAQ, Receptionist, Concierge)
  • Multi-agent hosting: multiple agents on a single server with AgentServer
  • SIP routing: SIP calls routed to agents by username
  • Session state: global data for the call, and post-prompt summaries when it ends
  • Security: auto-generated basic auth, per-call tool tokens, webhook signature validation, and TLS support
  • Serverless: automatic detection of Lambda, CGI, Google Cloud Functions, and Azure Functions

Agent Examples

The examples/ directory contains more than 50 working examples. These show the main features:

| Example | What it demonstrates | |---------|---------------------| | simple-agent.ts | POM prompts, SWAIG tools, multilingual support, LLM tuning | | contexts-steps.ts | Multi-step workflow with context switching and step navigation | | datamap-tools.ts | Server-side API tools without webhooks | | skills-demo.ts | Loading built-in skills (datetime, math) | | call-flow.ts | Call flow verbs, debug events, FunctionResult actions | | session-state.ts | onSummary, global data, post-prompt summaries | | multi-agent.ts | Multiple agents on one server | | serverless-lambda.ts | AWS Lambda deployment | | dynamic-config.ts | Per-request dynamic configuration, multi-tenant routing |

See examples/README.md for the full list organized by category.


RELAY Client

Real-time call control and messaging over WebSocket. The RELAY client connects to SignalWire via the Blade protocol and gives you imperative, async control over live phone calls and SMS/MMS.

The RELAY client connects with SIGNALWIRE_PROJECT_ID, SIGNALWIRE_API_TOKEN and SIGNALWIRE_SPACE from the environment. This client answers each call on the default context, plays a greeting, and hangs up:

import { RelayClient, Call } from '@signalwire/sdk';

const client = new RelayClient({
  contexts: ['default'],
});

client.onCall(async (call: Call) => {
  await call.answer();
  const action = await call.play([{ type: 'tts', text: 'Welcome to SignalWire!' }]);
  await action.wait();
  await call.hangup();
});

client.run();

The RELAY client provides:

  • Calling methods for play, record, collect, detect, tap, stream, AI, conferencing, and more
  • SMS/MMS messaging with delivery tracking
  • Action objects with wait(), stop(), pause(), resume()
  • Auto-reconnect with exponential backoff

See the RELAY documentation for the full guide, API reference, and examples.


REST Client

Typed HTTP client for managing SignalWire resources and controlling calls over HTTP. It sends standard fetch requests, with no WebSocket.

This client creates a Fabric AI agent, plays text on a live call, searches for phone numbers and searches Datasphere documents:

import { RestClient } from '@signalwire/sdk';

const client = new RestClient({
  project: '...',
  token: '...',
  host: 'example.signalwire.com',
});

await client.fabric.aiAgents.create({ name: 'Support Bot', prompt: { text: 'You are helpful.' } });
await client.calling.play(callId, [{ type: 'tts', params: { text: 'Hello!' } }]);
await client.phoneNumbers.search({ areacode: '512' });
await client.datasphere.documents.search('billing policy');

The REST client provides:

  • Namespaced API surfaces: Fabric, Calling, Video, Datasphere, Phone Numbers, SIP, Queues, Recordings, and more
  • Node's built-in fetch, with no HTTP client dependency
  • Plain object returns: the raw JSON, with no wrapper objects

See the REST documentation for the full guide, API reference, and examples.


Webhook Verification

Your Signing Key verifies that an inbound webhook (a status callback, a messaging callback, or a SWML or SWAIG request) came from SignalWire. validateRequest replaces the Compatibility API's RestClient.validateRequest() and validateRequestWithBody(). It's a top-level export of @signalwire/sdk, so you don't need the separate @signalwire/compatibility-api package.

This fragment checks a form-encoded webhook, then a JSON one:

import { validateRequest } from '@signalwire/sdk';

// Parsed form params, from a cXML (Compatibility API) webhook.
const ok = validateRequest(signingKey, signatureHeader, fullUrl, requestParams);

// The raw request body, for JSON and SWML webhooks, or a cXML body that
// carries bodySHA256.
const okBody = validateRequest(signingKey, signatureHeader, fullUrl, rawBodyString);

validateRequest folds both Compatibility API methods into one call: pass a parsed params object / Map / array of tuples for form-encoded webhooks, or the raw body string to additionally verify the bodySHA256 the platform includes for JSON/SWML payloads. It returns true on a match, false otherwise, and throws if the Signing Key is missing.

validateWebhookSignature(signingKey, signature, url, rawBody) is the lower-level check of one signature over a raw body.

SignalWire also sends an HMAC-SHA256 signature in the X-SignalWire-Sha256-Signature header on JSON and SWML webhooks. It signs the same message, the URL followed by the raw body, and you can check it with validateWebhookSignatureSha256(signingKey, signature, url, rawBody). An agent's built-in validation, and webhookValidationMiddleware, check that header first when it's present and fall back to X-SignalWire-Signature.


Installation

One package covers agents, RELAY and REST. It requires Node.js 22 or later:

npm install @signalwire/sdk

Documentation

The reference documentation is at developer.signalwire.com/sdks/agents-sdk.

The docs/ directory has these guides. They're installed with the package, with the examples: npx sw-tsdocs path prints where.

Getting Started

Core Features

Skills and Extensions

Deployment

Reference

Environment Variables

| Variable | Used by | Description | |----------|---------|-------------| | SIGNALWIRE_PROJECT_ID | RELAY, REST | Project identifier | | SIGNALWIRE_API_TOKEN | RELAY, REST | API token | | SIGNALWIRE_SPACE | RELAY, REST | Space hostname (e.g. example.signalwire.com) | | SIGNALWIRE_REST_BASE_URL | REST | Override the REST base URL with a full http(s):// URL (local mock / private space / proxy). Precedence: host option > SIGNALWIRE_REST_BASE_URL > SIGNALWIRE_SPACE. | | SIGNALWIRE_REST_CA_FILE | REST | Path to a PEM CA bundle to trust for HTTPS REST requests (private/self-signed certificates). | | SIGNALWIRE_RELAY_HOST | RELAY | Override the RELAY WebSocket host (advanced/testing). Precedence: host option > SIGNALWIRE_RELAY_HOST > SIGNALWIRE_SPACE > built-in default. | | SIGNALWIRE_RELAY_SCHEME | RELAY | Override the RELAY WebSocket scheme (ws/wss; default wss). Precedence: scheme option > SIGNALWIRE_RELAY_SCHEME > wss; any value other than ws/wss falls back to wss. | | SWML_BASIC_AUTH_USER | Agents | Basic auth username (default: auto-generated) | | SWML_BASIC_AUTH_PASSWORD | Agents | Basic auth password (default: auto-generated) | | SWML_PROXY_URL_BASE | Agents | Base URL when behind a reverse proxy | | SWML_SSL_ENABLED | Agents | Enable HTTPS (true, 1, yes) | | SWML_SSL_CERT_PATH | Agents | Path to SSL certificate | | SWML_SSL_KEY_PATH | Agents | Path to SSL private key | | SIGNALWIRE_LOG_LEVEL | All | Logging level (debug, info, warn, error) | | SIGNALWIRE_LOG_MODE | All | Set to off to suppress all logging |

Testing

The scripts under scripts/ lint, format and test the SDK. They install their dependencies on first run and work from any directory:

# Run the test suite (optional filter passed through to vitest)
bash scripts/run-tests.sh
bash scripts/run-tests.sh AgentBase

# Format the tree (or --check to verify without writing)
bash scripts/run-format.sh
bash scripts/run-format.sh --check

# Lint (tsc + eslint; --fix to autofix)
bash scripts/run-lint.sh

These npm scripts build the SDK and watch for changes:

# Build
npm run build

# Dev mode (watch + rebuild)
npm run dev

# Watch-mode tests
npm run test:watch

License

MIT. See LICENSE for details.