Skip to main content
Stops the bot from recording while keeping it in the meeting. The bot remains connected and can still perform other actions like outputting audio.

Method Signature

bot.stopRecording(params: BaseBotParams): Promise<void>

Parameters

id
string
required
The unique identifier of the bot that should stop recording

Response

Returns void on success. The bot’s status will transition from in_call_recording to in_call_not_recording.

Example

import { Recall } from '@recall.ai/sdk';

const client = new Recall({
  apiKey: 'your-api-key',
  region: 'us-west-2'
});

// Stop recording
await client.bot.stopRecording({
  id: 'bot_1234567890'
});

console.log('Bot has stopped recording but remains in the call');

Example: Pause and Resume Recording

async function pauseRecording(botId: string, pauseDurationSeconds: number) {
  console.log('Pausing recording...');
  
  // Stop recording
  await client.bot.stopRecording({ id: botId });
  console.log(`Recording paused for ${pauseDurationSeconds} seconds`);
  
  // Note: There's no built-in resume method
  // You would need to create a new bot to resume recording
  await new Promise(resolve => 
    setTimeout(resolve, pauseDurationSeconds * 1000)
  );
  
  console.log('Pause duration complete');
}

await pauseRecording('bot_1234567890', 60);

Example: Stop Recording on Condition

async function monitorAndStopRecording(botId: string) {
  const checkInterval = setInterval(async () => {
    const transcript = await client.bot.getTranscript({ id: botId });
    
    // Check if someone said to stop recording
    const recentWords = transcript.words.slice(-20);
    const recentText = recentWords.map(w => w.text).join(' ').toLowerCase();
    
    if (recentText.includes('stop recording')) {
      console.log('Stop recording command detected');
      await client.bot.stopRecording({ id: botId });
      clearInterval(checkInterval);
    }
  }, 10000); // Check every 10 seconds
}

await monitorAndStopRecording('bot_1234567890');

Example: Timed Recording Session

async function recordForDuration(botId: string, durationMinutes: number) {
  const bot = await client.bot.retrieve({ id: botId });
  
  if (bot.status !== 'in_call_recording') {
    console.error('Bot is not currently recording');
    return;
  }
  
  console.log(`Recording for ${durationMinutes} minutes...`);
  
  // Set timeout to stop recording
  setTimeout(async () => {
    await client.bot.stopRecording({ id: botId });
    console.log('Recording stopped after scheduled duration');
  }, durationMinutes * 60 * 1000);
}

await recordForDuration('bot_1234567890', 30);

Example: Stop Recording and Announce

import { readFileSync } from 'fs';

async function stopRecordingWithAnnouncement(botId: string) {
  // Stop recording
  await client.bot.stopRecording({ id: botId });
  console.log('Recording stopped');
  
  // Wait a moment
  await new Promise(resolve => setTimeout(resolve, 1000));
  
  // Play announcement
  const audioBuffer = readFileSync('./recording-stopped.wav');
  const b64Audio = audioBuffer.toString('base64');
  
  await client.bot.outputAudio({
    id: botId,
    kind: 'audio',
    b64_data: b64Audio
  });
  
  console.log('Announcement played');
}

await stopRecordingWithAnnouncement('bot_1234567890');

Example: Stop Recording vs Leave Call

async function stopRecordingOrLeave(botId: string, shouldLeave: boolean) {
  const bot = await client.bot.retrieve({ id: botId });
  
  if (bot.status !== 'in_call_recording') {
    console.log('Bot is not currently recording');
    return;
  }
  
  if (shouldLeave) {
    console.log('Stopping recording and leaving call...');
    await client.bot.leaveCall({ id: botId });
  } else {
    console.log('Stopping recording but staying in call...');
    await client.bot.stopRecording({ id: botId });
  }
}

// Stop recording but stay in call
await stopRecordingOrLeave('bot_1234567890', false);

// Stop recording and leave
await stopRecordingOrLeave('bot_1234567890', true);

Example: With Status Verification

async function safeStopRecording(botId: string): Promise<boolean> {
  try {
    // Check current status
    const bot = await client.bot.retrieve({ id: botId });
    
    if (bot.status !== 'in_call_recording') {
      console.log(`Cannot stop recording: bot status is ${bot.status}`);
      return false;
    }
    
    // Stop recording
    await client.bot.stopRecording({ id: botId });
    
    // Verify status changed
    await new Promise(resolve => setTimeout(resolve, 2000));
    const updatedBot = await client.bot.retrieve({ id: botId });
    
    if (updatedBot.status === 'in_call_not_recording') {
      console.log('Recording stopped successfully');
      return true;
    } else {
      console.warn(`Unexpected status after stop: ${updatedBot.status}`);
      return false;
    }
  } catch (error) {
    console.error('Error stopping recording:', error.message);
    return false;
  }
}

const success = await safeStopRecording('bot_1234567890');

Notes

  • The bot must be actively recording (in_call_recording status) to stop recording
  • After stopping, the bot remains in the call with status in_call_not_recording
  • The bot can still perform other actions like outputting audio
  • To completely end the bot’s participation, use bot.leaveCall() instead
  • Media files up to the stop point will be saved and processed
  • There is no built-in method to resume recording - you would need to create a new bot

Build docs developers (and LLMs) love