Real-Time Updates

Pinecall provides a real-time update system that allows you to receive instant notifications about call events, agent actions, and other important activities. This helps you monitor your voice AI operations as they happen and build responsive applications.

Event Types

The platform emits various events that you can subscribe to:

EventDescription
call.startedEmitted when a call begins
call.endedEmitted when a call concludes
message.receivedEmitted when the system receives speech from a user
message.sentEmitted when the agent sends a response
recording.availableEmitted when a call recording is ready
transcription.completedEmitted when a call transcription is completed
agent.thinkingEmitted when the agent is processing information

Webhooks

Webhooks allow you to receive event notifications at specified HTTP endpoints. This enables you to build reactive systems that respond to Pinecall events in real-time.

register-webhook.js
import { Pinecall } from '@pinecall/sdk';

const pinecall = new Pinecall({
  apiKey: process.env.PINECALL_API_KEY
});

// Register a webhook endpoint
async function setupWebhook() {
  const webhook = await pinecall.webhooks.create({
    url: 'https://your-app.com/api/pinecall-webhooks',
    events: ['call.started', 'call.ended', 'message.received', 'message.sent'],
    secret: 'your-webhook-secret'  // Used to verify webhook signatures
  });
  
  console.log(`Webhook created with ID: ${webhook.id}`);
  return webhook;
}

Handling Webhook Events

When an event occurs, Pinecall will send a POST request to your webhook URL with event details in the request body.

webhook-handler.js
// Example Express.js webhook handler
const express = require('express');
const crypto = require('crypto');
const app = express();

app.use(express.json());

// Verify webhook signature
function verifySignature(req, secret) {
  const signature = req.headers['x-pinecall-signature'];
  const payload = JSON.stringify(req.body);
  const hmac = crypto.createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(hmac),
    Buffer.from(signature)
  );
}

app.post('/api/pinecall-webhooks', (req, res) => {
  const secret = process.env.WEBHOOK_SECRET;
  
  // Verify webhook signature
  if (!verifySignature(req, secret)) {
    return res.status(401).send('Invalid signature');
  }
  
  const event = req.body;
  
  // Handle different event types
  switch (event.type) {
    case 'call.started':
      console.log(`Call started: ${event.data.call_id}`);
      // Update your database, notify users, etc.
      break;
      
    case 'call.ended':
      console.log(`Call ended: ${event.data.call_id}, Duration: ${event.data.duration}s`);
      // Store call metrics, trigger follow-up processes, etc.
      break;
      
    case 'message.received':
      console.log(`Message from user: ${event.data.content}`);
      // Analyze user messages, trigger business logic, etc.
      break;
  }
  
  // Always respond with 200 OK to acknowledge receipt
  res.status(200).send('Event received');
});

app.listen(3000, () => {
  console.log('Webhook server running on port 3000');
});

WebSocket API

For applications requiring continuous real-time updates, Pinecall provides a WebSocket API that allows you to establish persistent connections and receive events as they happen.

websocket-client.js
import { Pinecall } from '@pinecall/sdk';

const pinecall = new Pinecall({
  apiKey: process.env.PINECALL_API_KEY
});

// Generate a WebSocket auth token
async function connectToWebSocket() {
  // Get a temporary token for WebSocket authentication
  const { token } = await pinecall.auth.createWebSocketToken();
  
  // Connect to the WebSocket API
  const socket = new WebSocket(`wss://api.pinecall.io/v1/ws?token=${token}`);
  
  // Connection opened
  socket.addEventListener('open', (event) => {
    console.log('Connected to Pinecall WebSocket API');
    
    // Subscribe to specific events
    socket.send(JSON.stringify({
      type: 'subscribe',
      events: ['call.started', 'call.ended', 'message.received', 'message.sent']
    }));
  });
  
  // Listen for messages
  socket.addEventListener('message', (event) => {
    const message = JSON.parse(event.data);
    
    switch (message.type) {
      case 'call.started':
        updateCallDisplay(message.data);
        break;
      case 'message.received':
        updateTranscript(message.data);
        break;
      // Handle other event types
    }
  });
  
  // Connection closed
  socket.addEventListener('close', (event) => {
    console.log('Disconnected from WebSocket API', event.code, event.reason);
  });
  
  // Handle errors
  socket.addEventListener('error', (error) => {
    console.error('WebSocket error:', error);
  });
  
  return socket;
}

// Helper functions for the example
function updateCallDisplay(data) {
  console.log('New call started:', data);
  // Update UI with new call information
}

function updateTranscript(data) {
  console.log('New message:', data);
  // Update conversation transcript in UI
}

Best Practices

  • Implement exponential backoff for reconnecting to WebSockets
  • Subscribe only to events you need to minimize data transfer
  • Always verify webhook signatures to ensure security
  • Implement idempotent event handling to prevent duplicate processing

Next Steps

Now that you understand Pinecall's real-time capabilities, you might want to explore: