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:
- Bootstrap: Fetch existing transcripts via REST API first
- Connect: Establish WebSocket connection and subscribe
- Merge: Use
absolute_start_timeas unique ID to merge REST and WebSocket segments - 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)
));
}
});
}
};Related Documentation