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:
| Token | Gets | Use for |
|---|---|---|
Platform API key (sk_live_...) | Full platform access across all your accounts | Backend-to-backend: provisioning, management, activity logging |
| Session token (JWT) | One account's scope, 1-hour TTL | Frontend components (see Embedded) |
| User token (JWT) | One user's scope within an account | Softphone + 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.yamlto 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
- Quickstart — the shortest path to a first API call.
- Architecture overview — the mental model.
- Webhook Events — every event shape.
- WebSocket API — real-time media protocol.