Skip to main content

Direct API

Raw power, 100% control. Talk directly to the REST and WebSocket APIs, handle events yourself, build exactly the experience you want — no components, no portal, no assumptions.

This is the tier when off-the-shelf components don't fit: AI call centers, bespoke dispatcher consoles, unusual call-routing logic, or any time you want to be close to the metal.

Authentication modes

Three token types, each with a different audience:

TokenGetsUse for
Platform API key (sk_live_...)Full platform access across all your accountsBackend-to-backend: provisioning, management, activity logging
Session token (JWT)One account's scope, 1-hour TTLFrontend components (see Embedded)
User token (JWT)One user's scope within an accountSoftphone + user-facing apps (WebRTC signalling, per-user call history)

All three use Authorization: Bearer <token>. Platform keys additionally require the DialStack-Account header when scoping to a specific customer; session and user tokens carry the account in their JWT claims.

Full flow: Authentication guide.

Example: Click-to-call with activity logging

This example demonstrates how to build a complete backend workflow for outbound sales or dispatching. It shows how to provision a new customer, trigger an outbound call via the API, and log the resulting call duration and status to your own database using a webhook handler — all in ~30 lines of code.

1. Provision a customer and user

import { DialStack } from '@dialstack/sdk';

const ds = new DialStack(process.env.DIALSTACK_KEY);

const account = await ds.accounts.create({ email: 'contact@joneschiro.com' });
const user = await ds.users.create({ name: 'Dr. Alice Smith' }, { dialstackAccount: account.id });

2. Trigger click-to-call

Alice's endpoints ring first; when she answers, DialStack dials the prospect and bridges the audio.

const call = await ds.calls.create(
{ from: user.id, to: '+16175551234' },
{ dialstackAccount: account.id }
);
// → { id: 'cdr_...', status: 'initiated', ... }

3. Handle call.end webhooks

Configure your platform's webhook_url once. DialStack delivers events for all accounts to that URL.

app.post('/webhooks/dialstack', express.raw({ type: 'application/json' }), (req, res) => {
verifySignature(req); // see webhook-events guide
const event = JSON.parse(req.body);

if (event.type === 'call.end') {
db.calls.upsert({
id: event.data.call_id,
duration: event.data.duration_seconds,
status: event.data.status,
});
}

res.status(200).end();
});

See Activity Logging for the full four-event pattern (call.end, voicemail.new, recording.available, *.transcription.complete).

Advanced example: dial plan with AI overflow

Everything you see in the landing hero is a single ds.dialPlans.create call. Real routing — business-hours schedule, team ring, AI receptionist fallback — expressed as a node graph:

await ds.dialPlans.create(
{
name: 'Main number',
entry_node: 'hours',
nodes: [
{
id: 'hours',
type: 'schedule',
config: { schedule_id: 'sch_business_hours', open: 'ring_team', closed: 'ai_reception' },
},
{ id: 'ring_team', type: 'ring_all_users', config: { timeout: 25, next: 'ai_reception' } },
{ id: 'ai_reception', type: 'internal_dial', config: { target_id: 'va_ai_receptionist' } },
],
},
{ dialstackAccount: account.id }
);

Full node surface: Dial Plans. AI agent setup: AI Scheduling.

Real-time and streaming

  • Webhooks — platform-scoped, fire-and-forget, for backend pipelines. See Webhook Events.
  • SSE (Server-Sent Events) — account-scoped, account-ID stream for frontends (Screen Pop, live dashboards). See Real-Time Events.
  • WebSocket audio streaming — bidirectional media for Voice Apps and one-way media for call listeners (transcription, monitoring). See Voice Apps and BYO VoiceAI.

API reference

Every operation has curl and SDK samples at /api. The reference is generated from the same OpenAPI spec the SDK is generated from — what you see there is what the platform does.

  • Full endpoint catalog, grouped into: Accounts & Users / Calls / Routing / AI & Voice Apps / Devices & Hardware / Platform.
  • Download the spec at /api/openapi.yaml to generate your own client in any language.

When to pick this

  • You're building a unique voice experience (AI call center, bespoke dispatcher console, live agent copilot).
  • You need fine-grained control over call routing, media streaming, or event handling.
  • You have engineering capacity and want no abstraction between your code and the platform.

When to pick something else

  • If you need a full phone-system portal without front-end work → White Label.
  • If you want voice features inside your existing UI but don't need custom flows → Embedded.

See also