Skip to main content
The Sessions API enables creation and management of ephemeral orchestration sessions. Use sessions to coordinate multi-agent workflows with automatic cleanup and time-to-live (TTL) management.

Overview

Access the Sessions API through the sessions property:
import { PrivateConnect } from '@privateconnect/sdk';

const pc = new PrivateConnect({ apiKey: 'your-api-key' });

const session = await pc.sessions.create('deployment-workflow', {
  ttlMinutes: 30,
});

Methods

create()

Create an orchestration session.
create(
  name: string, 
  options?: { 
    ttlMinutes?: number; 
    metadata?: Record<string, unknown> 
  }
): Promise<Session>
name
string
required
Human-readable session name
options
object
Optional session configuration
Session
Session
Created session object
Session creation automatically broadcasts a session:created event to all online agents on the orchestration channel.

Example

const session = await pc.sessions.create('deployment-workflow');

console.log(`Session created: ${session.id}`);
console.log(`Expires at: ${session.expiresAt}`);

end()

End an orchestration session.
end(sessionId: string): Promise<void>
sessionId
string
required
Session ID to end
Session end automatically broadcasts a session:ended event to all online agents on the orchestration channel.

Example

const session = await pc.sessions.create('deployment-workflow');

try {
  // Perform workflow tasks
  console.log('Starting deployment...');
  await performDeployment();
  console.log('Deployment complete');
} finally {
  // Always end the session
  await pc.sessions.end(session.id);
  console.log('Session ended');
}

getActive()

Get all active sessions (not expired).
getActive(): Session[]
Session[]
Session[]
Array of active sessions. Automatically filters out expired sessions.

Example

const active = pc.sessions.getActive();

console.log(`${active.length} active sessions:`);

active.forEach(session => {
  console.log(`  ${session.name} (${session.id})`);
  console.log(`    Created: ${session.createdAt}`);
  console.log(`    Expires: ${session.expiresAt}`);
  
  if (session.metadata) {
    console.log(`    Metadata:`, session.metadata);
  }
});

Complete Examples

Deployment Workflow

import { PrivateConnect } from '@privateconnect/sdk';

const pc = new PrivateConnect({ 
  apiKey: process.env.PRIVATECONNECT_API_KEY!,
  agentId: 'orchestrator'
});

async function deployApplication(version: string) {
  // Create session
  const session = await pc.sessions.create('deployment', {
    ttlMinutes: 30,
    metadata: {
      version,
      environment: 'production',
      timestamp: new Date().toISOString(),
    },
  });

  console.log(`Deployment session started: ${session.id}`);

  try {
    // Find deployment agents
    const deployers = await pc.agents.findByCapability('deploy');
    
    if (deployers.length === 0) {
      throw new Error('No deployment agents available');
    }

    // Send deployment request
    await pc.agents.sendMessage(
      deployers[0].id,
      {
        sessionId: session.id,
        action: 'deploy',
        version,
      },
      { channel: 'deployments' }
    );

    console.log('Deployment request sent');

    // Wait for completion (simplified)
    await new Promise(resolve => setTimeout(resolve, 10000));

    console.log('Deployment complete');
  } catch (error) {
    console.error('Deployment failed:', error);
    throw error;
  } finally {
    // Always end the session
    await pc.sessions.end(session.id);
    console.log('Session ended');
  }
}

await deployApplication('1.2.3');

Multi-Agent Coordination

import { PrivateConnect } from '@privateconnect/sdk';

const pc = new PrivateConnect({ 
  apiKey: process.env.PRIVATECONNECT_API_KEY!,
  agentId: 'coordinator'
});

async function coordinateDataPipeline() {
  // Create session for the pipeline
  const session = await pc.sessions.create('data-pipeline', {
    ttlMinutes: 60,
    metadata: {
      pipeline: 'daily-etl',
      stages: ['extract', 'transform', 'load'],
    },
  });

  console.log(`Pipeline session: ${session.id}`);

  try {
    // Stage 1: Extract
    const extractors = await pc.agents.findByCapability('extract');
    await pc.agents.sendMessage(
      extractors[0].id,
      {
        sessionId: session.id,
        stage: 'extract',
        source: 's3://data-lake/raw/',
      },
      { channel: 'pipeline' }
    );

    // Wait for extraction to complete
    await waitForStage(session.id, 'extract');

    // Stage 2: Transform
    const transformers = await pc.agents.findByCapability('transform');
    await pc.agents.sendMessage(
      transformers[0].id,
      {
        sessionId: session.id,
        stage: 'transform',
        rules: ['normalize', 'dedupe', 'enrich'],
      },
      { channel: 'pipeline' }
    );

    await waitForStage(session.id, 'transform');

    // Stage 3: Load
    const loaders = await pc.agents.findByCapability('load');
    await pc.agents.sendMessage(
      loaders[0].id,
      {
        sessionId: session.id,
        stage: 'load',
        destination: 'warehouse',
      },
      { channel: 'pipeline' }
    );

    await waitForStage(session.id, 'load');

    console.log('Pipeline complete');
  } catch (error) {
    console.error('Pipeline failed:', error);
    throw error;
  } finally {
    await pc.sessions.end(session.id);
  }
}

async function waitForStage(sessionId: string, stage: string) {
  console.log(`Waiting for ${stage} stage...`);
  
  while (true) {
    await new Promise(resolve => setTimeout(resolve, 5000));
    
    const messages = await pc.agents.getMessages({
      channel: 'pipeline',
      unreadOnly: true,
    });
    
    const completion = messages.find(
      m => m.payload.sessionId === sessionId && 
           m.payload.stage === stage &&
           m.payload.status === 'complete'
    );
    
    if (completion) {
      await pc.agents.markRead([completion.id]);
      console.log(`${stage} stage complete`);
      break;
    }
  }
}

await coordinateDataPipeline();

Session Monitoring

import { PrivateConnect } from '@privateconnect/sdk';

const pc = new PrivateConnect({ 
  apiKey: process.env.PRIVATECONNECT_API_KEY!,
  agentId: 'monitor'
});

// Monitor sessions and send alerts
setInterval(async () => {
  const active = pc.sessions.getActive();
  
  console.log(`Active sessions: ${active.length}`);
  
  for (const session of active) {
    const expiresAt = new Date(session.expiresAt);
    const now = new Date();
    const minutesRemaining = (expiresAt.getTime() - now.getTime()) / 60000;
    
    // Alert if session is expiring soon
    if (minutesRemaining < 5) {
      await pc.agents.broadcast(
        {
          type: 'session:expiring',
          sessionId: session.id,
          sessionName: session.name,
          minutesRemaining: Math.floor(minutesRemaining),
        },
        { channel: 'alerts' }
      );
      
      console.log(`⚠️  Session "${session.name}" expires in ${Math.floor(minutesRemaining)} minutes`);
    }
  }
}, 60000); // Check every minute

Listening for Session Events

import { PrivateConnect } from '@privateconnect/sdk';

const pc = new PrivateConnect({ 
  apiKey: process.env.PRIVATECONNECT_API_KEY!,
  agentId: 'listener'
});

// Poll for session events
setInterval(async () => {
  const messages = await pc.agents.getMessages({
    channel: 'orchestration',
    unreadOnly: true,
  });
  
  for (const msg of messages) {
    const { type, session, sessionId } = msg.payload;
    
    if (type === 'session:created') {
      console.log(`New session created: ${session.name}`);
      console.log(`  ID: ${session.id}`);
      console.log(`  Created by: ${session.createdBy}`);
      console.log(`  Expires: ${session.expiresAt}`);
      
      if (session.metadata) {
        console.log(`  Metadata:`, session.metadata);
      }
    } else if (type === 'session:ended') {
      console.log(`Session ended: ${sessionId}`);
      console.log(`  Ended by: ${msg.payload.endedBy}`);
      console.log(`  Ended at: ${msg.payload.endedAt}`);
    }
  }
  
  // Mark all as read
  if (messages.length > 0) {
    await pc.agents.markRead(messages.map(m => m.id));
  }
}, 5000); // Check every 5 seconds

Best Practices

Always End Sessions

Use try/finally to ensure sessions are always ended:
const session = await pc.sessions.create('workflow');

try {
  // Workflow logic
} finally {
  await pc.sessions.end(session.id);
}

Set Appropriate TTL

Choose TTL based on expected workflow duration:
// Short task (5 minutes)
await pc.sessions.create('quick-sync', { ttlMinutes: 5 });

// Medium task (30 minutes)
await pc.sessions.create('deployment', { ttlMinutes: 30 });

// Long task (2 hours)
await pc.sessions.create('data-migration', { ttlMinutes: 120 });

Use Metadata for Context

Store relevant workflow information in metadata:
await pc.sessions.create('deployment', {
  metadata: {
    environment: 'production',
    version: '1.2.3',
    initiatedBy: 'alice',
    gitCommit: 'abc123',
    services: ['api', 'worker'],
  },
});

Include Session ID in Messages

Always include the session ID in agent messages:
await pc.agents.sendMessage(agentId, {
  sessionId: session.id,
  action: 'deploy',
  // ... other payload
});

Next Steps

Agents API

Coordinate agents within sessions

Services API

Access services during workflows

Build docs developers (and LLMs) love