API reference

Documentation

Send texts, place calls, and list your numbers with a few lines of code. One REST API and TypeScript SDK for everything your business says to its customers — no telecom complexity to learn.

bash
npm install @signalroute/sdk

Overview

Introduction

SignalRoute is a single REST API and TypeScript SDK for business texting and calling. Send messages, place calls, and list the numbers on your account — all without touching the underlying telecom plumbing.

Predictable

Consistent JSON across every endpoint, with stable resource ids you can store and look up.

Typed

A first-class TypeScript SDK with full autocomplete for every request and response.

Plain HTTP

Every SDK call maps to one REST endpoint, so curl and your own client work just as well.

Base URL for all requests: https://api.signalroute.com

Get started

Quickstart

Install the SDK, drop in your API key, and send your first text. You'll be live in under a minute.
  1. 1Create an API key in the dashboard under Settings → API keys.
  2. 2Install the SDK with your package manager.
  3. 3Send a text from a number on your account.
bash
npm install @signalroute/sdk
send.ts
import { SignalRoute } from "@signalroute/sdk";

const signal = new SignalRoute(process.env.SIGNALROUTE_API_KEY!);

const message = await signal.messages.send({
  from: "+14045550142",        // your SignalRoute number
  to: "+15551234567",          // who you're texting
  message: "On our way!",
});

console.log(message.id);

Security

Authentication

SignalRoute authenticates every request with an API key sent as a bearer token in the Authorization header. Create and revoke keys in the dashboard under Settings → API keys.

Treat your secret key like a password. Never expose it in client-side code or commit it to a repo — store it in an environment variable.

http
Authorization: Bearer sk_live_7Qp2xR9aD3kFv8...
.env
# .env
SIGNALROUTE_API_KEY=sk_live_7Qp2xR9aD3kFv8...

Messaging

Send a text

Send a message with POST /v1/messages. The body takes from (your SignalRoute number in E.164 or its id), to, and message. It returns the created message.

TypeScript SDK

send-text.ts
import { SignalRoute } from "@signalroute/sdk";

const signal = new SignalRoute(process.env.SIGNALROUTE_API_KEY!);

const message = await signal.messages.send({
  from: "+14045550142",        // a number on your account, or its id
  to: "+15551234567",          // who you're texting
  message: "On our way!",
});

console.log(message.status);

cURL

bash
curl https://api.signalroute.com/v1/messages \
  -H "Authorization: Bearer $SIGNALROUTE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "+14045550142",
    "to": "+15551234567",
    "message": "On our way!"
  }'

Response

json
{
  "id": "msg_01HZX8QF3M7C2N",
  "from": "+14045550142",
  "to": "+15551234567",
  "message": "On our way!",
  "status": "queued",
  "created_at": "2026-05-30T18:24:11Z"
}

Messaging

List messages

Fetch your most recent messages with GET /v1/messages. Pass limit to control how many come back.

TypeScript SDK

list-messages.ts
import { SignalRoute } from "@signalroute/sdk";

const signal = new SignalRoute(process.env.SIGNALROUTE_API_KEY!);

const messages = await signal.messages.list({ limit: 50 });

for (const message of messages) {
  console.log(message.to, message.status);
}

cURL

bash
curl "https://api.signalroute.com/v1/messages?limit=50" \
  -H "Authorization: Bearer $SIGNALROUTE_API_KEY"

Voice

Make a call

Place an outbound call with POST /v1/calls. Include an optional say string and SignalRoute speaks it aloud when the recipient picks up.

TypeScript SDK

place-call.ts
import { SignalRoute } from "@signalroute/sdk";

const signal = new SignalRoute(process.env.SIGNALROUTE_API_KEY!);

const call = await signal.calls.create({
  from: "+14045550142",
  to: "+15551234567",
  say: "Hi, this is a reminder about your appointment tomorrow at 10am.",
});

console.log(call.id);

cURL

bash
curl https://api.signalroute.com/v1/calls \
  -H "Authorization: Bearer $SIGNALROUTE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "+14045550142",
    "to": "+15551234567",
    "say": "Hi, this is a reminder about your appointment tomorrow at 10am."
  }'

Voice

List calls

Fetch your most recent calls with GET /v1/calls. Pass limit to control how many come back.

TypeScript SDK

list-calls.ts
import { SignalRoute } from "@signalroute/sdk";

const signal = new SignalRoute(process.env.SIGNALROUTE_API_KEY!);

const calls = await signal.calls.list({ limit: 50 });

for (const call of calls) {
  console.log(call.to, call.status);
}

cURL

bash
curl "https://api.signalroute.com/v1/calls?limit=50" \
  -H "Authorization: Bearer $SIGNALROUTE_API_KEY"

Numbers

List numbers

List every number on your account with GET /v1/numbers. Use the returned numbers as the from value when sending texts or placing calls.

TypeScript SDK

list-numbers.ts
import { SignalRoute } from "@signalroute/sdk";

const signal = new SignalRoute(process.env.SIGNALROUTE_API_KEY!);

const numbers = await signal.numbers.list();

for (const number of numbers) {
  console.log(number.phoneNumber);
}

cURL

bash
curl https://api.signalroute.com/v1/numbers \
  -H "Authorization: Bearer $SIGNALROUTE_API_KEY"

Reference

Errors

SignalRoute uses conventional HTTP status codes. Every error returns a JSON body with an error object containing a machine-readable code and a human-readable message.
json
{
  "error": {
    "code": "from_number_not_found",
    "message": "The number +14045550142 is not on your account."
  }
}
Error codes
  • 401invalid_api_keyThe API key is missing, wrong, or revoked.
  • 400invalid_requestA required field is missing or malformed.
  • 400from_number_not_foundThe from-number isn't on your account.

Need a hand? Talk to our team or create an account to get your API key.