Discord.js v14 Interaction Replies: Ephemeral, Defer and Follow-Up
Use ephemeral replies for private responses and deferReply for work longer than Discord's acknowledgement window, then edit or follow up in discord.js v14.
02 Sept 2026, 07:41 UTC

Pick the reply pattern before you write the handler
If a slash command can answer immediately, reply once with interaction.reply(). Add ephemeral: true when the response should be private to the invoking user only. If the work may take longer than Discord's initial acknowledgement window, call interaction.deferReply() first, then finish with interaction.editReply() or interaction.followUp(). Skipping the deferral risks the client showing "Interaction failed".
This description reflects model knowledge of discord.js v14 and requires current verification against the live Discord API and library docs. Behavior can change between releases.
How discord.js v14 models an interaction reply
An interaction is the request Discord sends when a user runs a slash command or uses a component. The response is tied to the interaction token supplied with the event, not to Gateway Intents. Receiving the event still requires the bot to be present in the guild and the command to be registered.
Model knowledge indicates each interaction allows exactly one initial response. After interaction.reply() or interaction.deferReply() is used, further responses must be edits to that initial message or additional follow-up messages. Calling reply() a second time on the same interaction is expected to throw an error.
Ephemeral replies are delivered only to the invoking user in the UI and are not part of the channel's public message history. They cannot be referenced or mentioned by other users.
Worked example: private quick reply and deferred slow reply
The example assumes discord.js v14 is installed, a test guild exists, and two slash commands quick and slow are registered to the application.
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.on('interactionCreate', async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'quick') {
await interaction.reply({
content: 'Quick result: done.',
ephemeral: true,
});
return;
}
if (interaction.commandName === 'slow') {
await interaction.deferReply({ ephemeral: true });
// Simulate a long-running task
await new Promise((resolve) => setTimeout(resolve, 4000));
await interaction.editReply({
content: 'Slow result: finished after deferral.',
});
return;
}
});
client.login(process.env.DISCORD_TOKEN);Run with Node.js in a project directory where discord.js v14 is installed. Set DISCORD_TOKEN in the environment before running.
Required setup:
- Bot token with permission to receive interactions.
GUILDSintent for guild-based slash commands. DM interactions have different intent requirements.- Slash commands
quickandslowregistered to the test guild or globally.
Expected checks to perform manually:
- Invoke
/quickin a public channel. A second account in the same channel should not see the reply whenephemeral: trueis used. - Invoke
/slow. With an immediate defer, the client should not show "Interaction failed" and the placeholder should be replaced by the edit after the delay. - Do not call
interaction.reply()afterdeferReply(); useeditReply()orfollowUp()instead.
Risks:
- Without an initial reply or defer within Discord's acknowledgement window, the interaction is invalidated.
deferReply({ ephemeral: true })reserves an ephemeral slot but sends no visible content untileditReply()orfollowUp()is called.- Ephemeral messages behave differently from normal messages in persistence and mentionability.
Limits and common mistakes
| Behavior | Correct approach | Common mistake |
|---|---|---|
| Initial reply limit | Call reply() or deferReply() once per interaction. | Calling reply() twice on the same interaction. |
| Slow processing | Defer first, then editReply() or followUp(). | Waiting past the acknowledgement window before any response. |
| Private messages | Pass ephemeral: true to reply() or deferReply(). | Assuming other users can see or mention an ephemeral message. |
| Correction after sending | Use editReply() to change content or deleteReply() to remove it. | Trying to send a second initial reply to fix an error. |
Limitations to note:
- The duration of the acknowledgement window and the lifetime of the interaction token are defined by Discord and may change. Verify current values in official documentation.
- Follow-up messages are allowed after the initial reply, but their availability window is token-dependent and not specified here.
- Ephemeral visibility is client-side; it does not create a retrievable channel message.
Practical verification checklist
- Install discord.js v14 in the project and inspect the type definitions for
Interaction,BaseInteractionandCommandInteractioninnode_modules. - Deploy the
quickandslowcommands to a test guild. - Run the script with a valid token and invoke
/quickfrom one account, then check visibility from a second account. - Invoke
/slowand observe that the deferred placeholder appears and is updated without an interaction failure notice.
Verify all behavior against the current discord.js v14 release notes and Discord API documentation before production use.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.