Skip to main content

Account Sessions

Account sessions provide secure, scoped tokens for client-side embedded components. Sessions are tied to a specific account and can be restricted to specific components.

Create a Session

const session = await dialstack.accountSessions.create({
account: 'acct_01h2xcejqtf2nbrexx3vqjhp41',
});

console.log(session.client_secret); // 'cs_live_...'
console.log(session.expires_at); // '2025-01-15T13:00:00Z'

Parameters

ParameterTypeRequiredDescription
accountstringYesAccount ID to scope the session to
componentsobjectNoComponent permissions

Response

interface AccountSessionCreateResponse {
client_secret: string;
expires_at: string;
}

Component Permissions

Control which embedded components the session can access:

const session = await dialstack.accountSessions.create({
account: 'acct_01h2xcejqtf2nbrexx3vqjhp41',
components: {
call_logs: { enabled: true },
voicemails: { enabled: true },
},
});

Available Components

ComponentDescription
call_logsAccess to call history
voicemailsAccess to voicemails

Restricting Access

// Only allow voicemails
const session = await dialstack.accountSessions.create({
account: accountId,
components: {
call_logs: { enabled: false },
voicemails: { enabled: true },
},
});

If a disabled component is used, it will show an error state.

Session Lifecycle

Expiration

Sessions expire after 1 hour by default. The expires_at field indicates when the session becomes invalid.

Client-Side Handling

Pass the full session response to enable automatic refresh:

// Server
app.post('/api/dialstack/session', async (req, res) => {
const session = await dialstack.accountSessions.create({
account: req.body.accountId,
});

// Return both fields
res.json({
client_secret: session.client_secret,
expires_at: session.expires_at,
});
});
// Client (React)
<DialstackComponentsProvider
dialstack={dialstack}
clientSecret={{
client_secret: session.client_secret,
expires_at: session.expires_at,
}}
>

Manual Refresh

If the session expires and you only passed the client_secret string:

// Client-side
async function refreshSession() {
const response = await fetch('/api/dialstack/session', {
method: 'POST',
body: JSON.stringify({ accountId }),
});
const session = await response.json();
setClientSecret(session.client_secret);
}

Security

API Key Required

Sessions can only be created with an API key (sk_live_*). This prevents clients from creating their own sessions.

// This works (server-side with API key)
const dialstack = new DialStack(process.env.DIALSTACK_API_KEY);
const session = await dialstack.accountSessions.create({ account: accountId });

// Client-side tokens cannot create sessions
// (no accountSessions.create method available)

Account Isolation

Each session is scoped to a single account. The client_secret can only access data belonging to that account.

Token Security

  • Tokens cannot be used to create new sessions
  • Tokens are short-lived (1 hour)
  • Tokens have limited scope (only enabled components)

Examples

Express.js Session Endpoint

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

const app = express();
const dialstack = new DialStack(process.env.DIALSTACK_API_KEY);

app.use(express.json());

app.post('/api/dialstack/session', async (req, res) => {
try {
const { accountId } = req.body;

// Verify user has access to this account
const userId = req.user?.id; // From auth middleware
const hasAccess = await verifyAccountAccess(userId, accountId);

if (!hasAccess) {
return res.status(403).json({ error: 'Access denied' });
}

// Create session
const session = await dialstack.accountSessions.create({
account: accountId,
components: {
call_logs: { enabled: true },
voicemails: { enabled: true },
},
});

res.json(session);
} catch (error) {
console.error('Session creation failed:', error);
res.status(500).json({ error: 'Failed to create session' });
}
});

Next.js API Route

// pages/api/dialstack/session.ts
import type { NextApiRequest, NextApiResponse } from 'next';
import { DialStack } from '@dialstack/sdk/server';
import { getServerSession } from 'next-auth';

const dialstack = new DialStack(process.env.DIALSTACK_API_KEY!);

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}

// Check authentication
const authSession = await getServerSession(req, res);
if (!authSession) {
return res.status(401).json({ error: 'Unauthorized' });
}

const { accountId } = req.body;

// Verify user owns this account
const userAccount = await db.accounts.findFirst({
where: {
dialstackAccountId: accountId,
userId: authSession.user.id,
},
});

if (!userAccount) {
return res.status(403).json({ error: 'Access denied' });
}

// Create session
const session = await dialstack.accountSessions.create({
account: accountId,
});

res.json(session);
}

Component-Specific Sessions

// Only voicemails for this user
async function getVoicemailSession(accountId: string) {
return dialstack.accountSessions.create({
account: accountId,
components: {
call_logs: { enabled: false },
voicemails: { enabled: true },
},
});
}

// Only call logs for analytics dashboard
async function getAnalyticsSession(accountId: string) {
return dialstack.accountSessions.create({
account: accountId,
components: {
call_logs: { enabled: true },
voicemails: { enabled: false },
},
});
}

Deprecated: sessions

The sessions property is deprecated. Use accountSessions instead:

// Deprecated
const session = await dialstack.sessions.create({ account: accountId });

// Use this instead
const session = await dialstack.accountSessions.create({ account: accountId });

Next Steps