---
title: "Resume a Conversation | Micdrop"
description: "Pick up a saved conversation where the user left off, after the WebSocket drops mid-call, the user closes the tab, or the session is paused on purpose."
url: "https://micdrop.dev/docs/server/resume-conversation"
---

*   [Getting Started](/docs/getting-started)
*   [Client (Browser)](/docs/client)
    
    *   [Installation](/docs/client/installation)
    *   [React Hooks](/docs/client/react-hooks)
    *   [Start/Stop Call](/docs/client/start-stop-call)
    *   [Pause/Resume Call](/docs/client/pause-resume-call)
    *   [Mute/Unmute Call](/docs/client/mute-unmute-call)
    *   [Call State](/docs/client/call-state)
    *   [Display Conversation Messages](/docs/client/display-conversation-messages)
    *   [Handling Tool Calls](/docs/client/handling-tool-calls)
    *   [Device Management](/docs/client/devices-management)
    *   [Voice Activity Detection (VAD)](/docs/client/vad)
    *   [Turn Detection](/docs/client/turn-detection)
    *   [Reducing Latency](/docs/client/latency)
    *   [Error Handling](/docs/client/error-handling)
    *   Utility Classes
        
        *   [Mic](/docs/client/utility-classes/mic)
        *   [MicdropClient](/docs/client/utility-classes/micdrop-client)
        *   [MicRecorder](/docs/client/utility-classes/mic-recorder)
        *   [Speaker](/docs/client/utility-classes/speaker)
        
    
*   [Client (React Native)](/docs/react-native)
    
    *   [Installation](/docs/react-native/installation)
    *   [Hooks and Call State](/docs/react-native/hooks)
    *   [Audio Output and Devices](/docs/react-native/audio-output)
    *   [Voice Activity Detection (VAD)](/docs/react-native/vad)
    *   [Turn Detection](/docs/react-native/turn-detection)
    *   [Using Another Audio Library](/docs/react-native/custom-audio)
    
*   [Server (Node.js)](/docs/server)
    
    *   [Installation](/docs/server/installation)
    *   [With Fastify](/docs/server/with-fastify)
    *   [With NestJS](/docs/server/with-nestjs)
    *   [Auth and Parameters](/docs/server/auth-and-parameters)
    *   [First Message](/docs/server/first-message)
    *   [Dictation and Text-Only Calls](/docs/server/dictation)
    *   [Partial Messages](/docs/server/partial-messages)
    *   [Save Messages](/docs/server/save-messages)
    *   [Resume a Conversation](/docs/server/resume-conversation)
    *   [Recording Audio](/docs/server/recording-audio)
    *   [Error Handling](/docs/server/error-handling)
    *   [Tools](/docs/server/tools)
    *   [Extract Value from Answer](/docs/server/extract)
    *   [Auto End Call](/docs/server/auto-end-call)
    *   [Semantic Turn Detection](/docs/server/semantic-turn-detection)
    *   [Noise Filtering](/docs/server/noise-filtering)
    *   [Micdrop Protocol](/docs/server/protocol)
    
*   [AI Integrations](/docs/ai-integration)
    
    *   Provided Integrations
        
        *   [AI SDK](/docs/ai-integration/provided-integrations/ai-sdk)
        *   [Cartesia](/docs/ai-integration/provided-integrations/cartesia)
        *   [ElevenLabs](/docs/ai-integration/provided-integrations/elevenlabs)
        *   [Gladia](/docs/ai-integration/provided-integrations/gladia)
        *   [Gradium](/docs/ai-integration/provided-integrations/gradium)
        *   [Kokoro](/docs/ai-integration/provided-integrations/kokoro)
        *   [Mistral](/docs/ai-integration/provided-integrations/mistral)
        *   [OpenAI](/docs/ai-integration/provided-integrations/openai)
        *   [Piper](/docs/ai-integration/provided-integrations/piper)
        *   [Pocket TTS](/docs/ai-integration/provided-integrations/pocket-tts)
        *   [Qwen3-TTS](/docs/ai-integration/provided-integrations/qwen-tts)
        *   [Whisper](/docs/ai-integration/provided-integrations/whisper)
        
    *   Custom Integrations
        
        *   [Agent (LLM)](/docs/ai-integration/custom-integrations/custom-agent)
        *   [Speech-to-Text (STT)](/docs/ai-integration/custom-integrations/custom-stt)
        *   [Text-to-Speech (TTS)](/docs/ai-integration/custom-integrations/custom-tts)
        
    *   Fallback Strategies
        
        *   [FallbackAgent](/docs/ai-integration/fallback-strategies/agent-fallback)
        *   [FallbackSTT](/docs/ai-integration/fallback-strategies/stt-fallback)
        *   [FallbackTTS](/docs/ai-integration/fallback-strategies/tts-fallback)
        
    *   [Local Models](/docs/ai-integration/local-models)
        
        *   [Local LLM](/docs/ai-integration/local-models/agent)
        *   [Local STT](/docs/ai-integration/local-models/speech-to-text)
        *   [Local TTS](/docs/ai-integration/local-models/text-to-speech)
        *   [Latency and Memory](/docs/ai-integration/local-models/performance)
        *   [Explorations](/docs/ai-integration/local-models/explorations)
            
            *   [MiniCPM5-2B](/docs/ai-integration/local-models/explorations/minicpm)
            *   [Mistral 7B](/docs/ai-integration/local-models/explorations/mistral-7b)
            *   [Voxtral Mini 3B](/docs/ai-integration/local-models/explorations/voxtral-stt)
            *   [Voxtral TTS 4B](/docs/ai-integration/local-models/explorations/voxtral-tts)
            *   [AuK and AuK-Flash](/docs/ai-integration/local-models/explorations/auk)
            
        
    *   [IA Vocale Souveraine 🇫🇷🇪🇺](/docs/ai-integration/sovereign-voice-ai)
    
*   [Migration](/docs/migration)
    
    *   [Upgrade to v3](/docs/migration/v3)
    

[Micdrop](/) › [Documentation](/docs/getting-started) › [Server (Node.js)](/docs/server)

# Resume a Conversation

Pick up a saved conversation where the user left off. Useful when the WebSocket drops mid-call, the user closes the tab, or the session is intentionally paused and resumed later.

The idea is to rehydrate the `Agent` with the messages it had at the end of the previous call, before plugging in the live listeners and starting the new `MicdropServer`. The LLM then has the same context it had before, and the assistant can continue from where it stopped.

## Replay Messages Before Wiring Listeners

Use `agent.addMessage(role, content)` (or `addUserMessage` / `addAssistantMessage`) to rebuild the conversation. Do this **before** attaching the `Message` listener you use to persist new messages, so replayed history isn’t saved a second time.

```
import { MicdropServer } from '@micdrop/server'
// Fetch what you stored on the previous callconst history = await db.conversations.findBy({ sessionId })
const agent = new OpenaiAgent({  apiKey: process.env.OPENAI_API_KEY,  systemPrompt: 'You are a helpful assistant',})
// 1. Rehydrate first — addMessage emits "Message", so do it before subscribingfor (const message of history) {  agent.addMessage(message.role, message.content)}
// 2. Then subscribe to persist only new messagesagent.on('Message', async (message) => {  await db.conversations.create({    sessionId,    role: message.role,    content: message.content,  })})
new MicdropServer(socket, { agent, stt, tts })
```

See [Save Messages](/docs/server/save-messages) for the matching save-side pattern.

## Skip the First Message on Resumption

When resuming, you usually don’t want the assistant to greet the user again. Omit both `firstMessage` and `generateFirstMessage`, and instead inject a short system instruction telling the model to pick up the thread:

```
const isResuming = history.length > 0
for (const message of history) {  agent.addMessage(message.role, message.content)}
if (isResuming) {  agent.addMessage(    'system',    'The conversation was interrupted. Continue naturally from the last exchange without greeting the user again.'  )}
new MicdropServer(socket, {  agent,  stt,  tts,  // Only generate a greeting when there is no history  ...(isResuming ? {} : { generateFirstMessage: true }),})
```

See [First Message](/docs/server/first-message) for the non-resumption flow.

## Re-speak the Last Assistant Question

If the last stored message is from the assistant, the user probably never heard the end of it (the socket dropped while it was speaking, or they reloaded the page right after). Re-speak it through the TTS so the user knows what they were just asked, without asking the agent to regenerate anything:

```
const server = new MicdropServer(socket, { agent, stt, tts })
const last = history[history.length - 1]if (last?.role === 'assistant') {  // Replays the existing assistant message via TTS. The agent's conversation  // already contains it (added above), so no new "Message" event fires and no  // duplicate row is created.  server.speak(last.content)}
```

[Previous← Save Messages](/docs/server/save-messages)[NextRecording Audio →](/docs/server/recording-audio)

On this page

*   [Replay Messages Before Wiring Listeners](#replay-messages-before-wiring-listeners)
*   [Skip the First Message on Resumption](#skip-the-first-message-on-resumption)
*   [Re-speak the Last Assistant Question](#re-speak-the-last-assistant-question)
