Skip to main content
RevDesk ships two official packages so you don’t have to hand-roll HTTP calls or wire up browser audio:

@revdesk/sdk

Typed REST client for the v1 API — calls, SMS, phone numbers, caller IDs, caller trust, usage, and sub-entities. Types are generated from the OpenAPI spec, so they never drift from the API.

@revdesk/webrtc

Browser-calling client. Place and receive calls in the browser through the RevDesk voice network, with one branded surface for both connection paths.

@revdesk/sdk

Install

npm install @revdesk/sdk
# or: bun add @revdesk/sdk

Quickstart

import { RevDesk } from "@revdesk/sdk";

const revdesk = new RevDesk({ apiKey: process.env.REVDESK_API_KEY! });

// List phone numbers
const { data: numbers } = await revdesk.phoneNumbers.list({ limit: 25 });

// Place an outbound call
await revdesk.calls.dial({ from_number: "+15551230000", to_number: "+15554560000" });

// Send an SMS
await revdesk.sms.send({ from_number: "+15551230000", to_number: "+15554560000", body: "Hi!" });

Pagination

Cursor-paginated endpoints expose listAll(), an async iterator that walks every page for you:
for await (const number of revdesk.phoneNumbers.listAll()) {
  console.log(number.phone_number);
}
listAll() is available on phoneNumbers, subEntities, and callerTrust.reputation.numbers.

Idempotency

Mutating calls accept an idempotencyKey so a retried request is processed once:
import { generateIdempotencyKey } from "@revdesk/sdk";

await revdesk.sms.send(
  { from_number: "+15551230000", to_number: "+15554560000", body: "Hi!" },
  { idempotencyKey: generateIdempotencyKey() },
);

Errors

Every non-2xx response throws a typed RevDeskError:
import { RevDeskError } from "@revdesk/sdk";

try {
  await revdesk.calls.dial({ from_number: "+1555…", to_number: "+1555…" });
} catch (err) {
  if (err instanceof RevDeskError) {
    console.error(err.code, err.status, err.message);
    if (err.isRetryable) {
      /* rate-limited or 5xx — safe to retry */
    }
  }
}
See Errors for the full RevDeskError shape.

@revdesk/webrtc

Install

npm install @revdesk/webrtc
# or: bun add @revdesk/webrtc
Issue the call token server-side with @revdesk/sdk, then hand it to the browser client. Both clients emit the same callUpdate / error / ended events, so your UI doesn’t change when you switch paths. See Choosing a calling path for the differences.

Browser-direct — RevDeskRTC

import { RevDeskRTC } from "@revdesk/webrtc";

// token from revdesk.webrtc.getToken({ from_number, to_number })
const call = new RevDeskRTC({ token });
call.on("callUpdate", ({ state }) => console.log(state));
await call.connect();
call.dial({ to: "+15554560000", from: "+15551230000" });

Relay — RevDeskRoom

import { RevDeskRoom } from "@revdesk/webrtc";

// from revdesk.webrtc.getRoomToken({ from_number, to_number })
const { token, room_url, call_id } = await revdesk.webrtc.getRoomToken({ from_number, to_number });
const call = new RevDeskRoom({ token, roomUrl: room_url, callId: call_id });
call.on("callUpdate", ({ state }) => console.log(state));
await call.join();
Calls fail through the error event with a typed RevDeskCallError (code is one of connection_failed, connection_timeout, call_rejected, …).