Get Transcripts

Learn how to fetch transcripts using the REST API and receive live transcript updates via WebSocket.

Overview
There are two ways to get transcripts: REST API for fetching complete transcripts and WebSocket for real-time updates.

REST API

Use GET /transcripts/{platform}/{native_meeting_id} to fetch all transcript segments for a meeting. Best for:

  • Loading historical transcripts
  • Bootstraping before WebSocket connection
  • One-time transcript retrieval

WebSocket

Subscribe to meetings and receive transcript.mutable and transcript.finalized events. Best for:

  • Real-time transcript updates during active meetings
  • Live transcription display
  • Streaming transcript processing
Fetch Transcripts via REST API
Get all transcript segments for a meeting using the REST API
JavaScript/TypeScript Example
// Fetch transcripts for a meeting
async function getTranscripts(platform, nativeMeetingId) {
  const response = await fetch(
    `https://your-api-url/transcripts/${platform}/${nativeMeetingId}`,
    {
      headers: {
        'X-API-Key': 'your-api-key',
        'Content-Type': 'application/json'
      }
    }
  );
  
  if (!response.ok) {
    throw new Error(`Failed to fetch transcripts: ${response.statusText}`);
  }
  
  const data = await response.json();
  
  // data.segments contains all transcript segments
  console.log(`Found ${data.segments.length} transcript segments`);
  
  // Each segment has:
  // - text: The transcribed text
  // - speaker: Speaker name
  // - start/end: Relative timestamps (seconds from meeting start)
  // - absolute_start_time/absolute_end_time: ISO timestamps
  // - language: Detected language code
  // - created_at: When the segment was created
  
  return data.segments;
}

// Usage
const segments = await getTranscripts('google_meet', 'abc-defg-hij');

// Display transcripts
segments.forEach(segment => {
  console.log(`[${segment.speaker}] ${segment.text}`);
});
Receive Live Transcripts via WebSocket
Subscribe to meetings and receive transcript events in real-time

For detailed WebSocket implementation, see the Live Transcripts cookbook.

Quick Example

// Connect and subscribe
const ws = new WebSocket('wss://your-api-url/ws?api_key=your-api-key');

ws.onopen = () => {
  ws.send(JSON.stringify({
    action: 'subscribe',
    meetings: [{ platform: 'google_meet', native_id: 'abc-defg-hij' }]
  }));
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  
  if (message.type === 'transcript.mutable') {
    // Live segments that may be updated
    message.payload.segments.forEach(segment => {
      console.log(`[LIVE] [${segment.speaker}] ${segment.text}`);
    });
  } else if (message.type === 'transcript.finalized') {
    // Final segments that won't change
    message.payload.segments.forEach(segment => {
      console.log(`[FINAL] [${segment.speaker}] ${segment.text}`);
    });
  }
};
Best Practice: Bootstrap Pattern
Combine REST and WebSocket for the best experience

For active meetings, use a bootstrap pattern:

  1. Bootstrap: Fetch existing transcripts via REST API first
  2. Connect: Establish WebSocket connection and subscribe
  3. Merge: Use absolute_start_time as unique ID to merge REST and WebSocket segments
  4. Update: Replace mutable segments with finalized ones as they arrive

Example Implementation

// 1. Bootstrap from REST
const bootstrapSegments = await getTranscripts(platform, nativeId);
const transcriptMap = new Map();

// Store segments by absolute_start_time (unique ID)
bootstrapSegments.forEach(seg => {
  transcriptMap.set(seg.absolute_start_time, seg);
});

// 2. Connect WebSocket
const ws = new WebSocket('wss://your-api-url/ws?api_key=your-api-key');
ws.onopen = () => {
  ws.send(JSON.stringify({
    action: 'subscribe',
    meetings: [{ platform, native_id: nativeId }]
  }));
};

// 3. Handle updates
ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  
  if (message.type === 'transcript.mutable' || message.type === 'transcript.finalized') {
    message.payload.segments.forEach(seg => {
      const key = seg.absolute_start_time;
      const existing = transcriptMap.get(key);
      
      // Update if new or if this version is newer
      if (!existing || new Date(seg.updated_at) > new Date(existing.updated_at)) {
        transcriptMap.set(key, seg);
        updateUI(Array.from(transcriptMap.values()).sort((a, b) => 
          new Date(a.absolute_start_time) - new Date(b.absolute_start_time)
        ));
      }
    });
  }
};