Skip to main content
Instructs the bot to leave the meeting immediately. This ends the recording and begins post-processing of the captured media.

Method Signature

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

Parameters

id
string
required
The unique identifier of the bot that should leave the call

Response

Returns void on success. The bot’s status will transition through several states:
  1. Current status (e.g., in_call_recording)
  2. recording_done - Recording has stopped
  3. call_ended - Bot has left the call
  4. done - All processing complete

Example

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

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

// Create and join a meeting
const bot = await client.bot.create({
  meeting_url: 'https://zoom.us/j/123456789'
});

// Wait for some time or condition...
await new Promise(resolve => setTimeout(resolve, 60000)); // 1 minute

// Make the bot leave
await client.bot.leaveCall({
  id: bot.id
});

console.log('Bot is leaving the call');

Example: Leave After Duration

async function recordForDuration(meetingUrl: string, durationMinutes: number) {
  // Create bot
  const bot = await client.bot.create({
    meeting_url: meetingUrl
  });
  
  console.log(`Bot ${bot.id} created, will record for ${durationMinutes} minutes`);
  
  // Wait for specified duration
  await new Promise(resolve => 
    setTimeout(resolve, durationMinutes * 60 * 1000)
  );
  
  // Leave the call
  await client.bot.leaveCall({ id: bot.id });
  console.log('Bot has left the call');
  
  return bot.id;
}

// Record for 30 minutes
const botId = await recordForDuration(
  'https://zoom.us/j/123456789',
  30
);

Example: Leave on Condition

async function monitorAndLeave(botId: string) {
  const checkInterval = setInterval(async () => {
    const bot = await client.bot.retrieve({ id: botId });
    
    // Check if bot should leave based on some condition
    if (bot.status === 'recording_permission_denied') {
      clearInterval(checkInterval);
      await client.bot.leaveCall({ id: botId });
      console.log('Bot leaving due to permission denial');
    }
  }, 10000); // Check every 10 seconds
}

Example: Leave All Active Bots

// Get all bots that are currently recording
const activeBots = await client.bot.list({
  status: 'in_call_recording'
});

// Make all bots leave
for (const bot of activeBots.results) {
  await client.bot.leaveCall({ id: bot.id });
  console.log(`Bot ${bot.id} is leaving`);
}

Example: Leave and Wait for Processing

async function leaveAndWaitForProcessing(botId: string) {
  // Make bot leave
  await client.bot.leaveCall({ id: botId });
  console.log('Bot is leaving...');
  
  // Poll until processing is complete
  while (true) {
    const bot = await client.bot.retrieve({ id: botId });
    console.log(`Current status: ${bot.status}`);
    
    if (bot.status === 'done') {
      console.log('Processing complete!');
      return bot;
    }
    
    if (bot.status === 'fatal') {
      throw new Error('Bot encountered a fatal error');
    }
    
    await new Promise(resolve => setTimeout(resolve, 5000));
  }
}

const processedBot = await leaveAndWaitForProcessing('bot_1234567890');
console.log('Media URLs:', processedBot.media);

Notes

  • The bot will leave gracefully, completing any in-progress operations
  • Recording data will be saved and processed after the bot leaves
  • Use this method instead of bot.deleteScheduledBot() for bots that are already in a call
  • The bot cannot rejoin the same meeting after leaving

Build docs developers (and LLMs) love