Rich embeds
Give bot messages a title, artwork and useful details in channels, DMs and private replies.
Examples use the bot client from Your first bot.
Build your first embed
Use EmbedBuilder in JavaScript/TypeScript or Embed in Python. Plain embed objects work too. An embed can be the whole message, so you can leave out content. Add this queue command to the full command list you register.
Rich embed helpers require SDK 0.3.0 or newer. In a server channel, a missing Embed Links grant suppresses the embeds while keeping the message stored.
import { EmbedBuilder } from '@riscord/bot';
bot.command('queue', interaction => {
const card = new EmbedBuilder()
.setTitle('Your queue')
.setDescription('Something good is up next.')
.setColor('#a693ff')
.addFields({ name: 'Tracks', value: '3', inline: true })
.setFooter({ text: 'Pick a track and settle in.' });
return interaction.reply({ embeds: [card], private: true });
});Use the same card in messages and DMs
Use a different stable delivery ID for each business operation. Reply embeds stay private when the interaction is private. DMs keep the same recipient consent and message-request rules as text messages.
const card = { title: 'All set', description: 'Your export is ready.', color: 0xa693ff };
await bot.send(channelId, { embeds: [card], clientId: 'export-channel-123' });
const dm = await bot.openDM(userId);
await bot.sendDM(dm.id, { embeds: [card], clientId: 'export-dm-123' });Images, thumbnails and author details
Embeds support image and thumbnail URLs, an author name/icon, a footer and an RFC3339 timestamp. Links and artwork URLs must use HTTP(S), without credentials or whitespace. Author/footer icons use the JSON field icon_url in both SDKs.
For uploaded artwork, resolve the returned /uploads/... path against your Riscord origin before putting it inside an embed. Ordinary imageUrl and fileUrl message fields accept the relative upload path directly. Bot JSON sends do not support attachment:// references.
import { readFile } from 'node:fs/promises';
const bytes = await readFile('./cover.png');
const uploadedImage = await bot.upload(new Blob([bytes], { type: 'image/png' }), 'cover.png');
const imageUrl = new URL(uploadedImage.url, bot.baseUrl).href;
const card = new EmbedBuilder()
.setTitle('Your export')
.setImage(imageUrl)
.setTimestamp(new Date());
await bot.send(channelId, { embeds: [card] });Keep embeds readable
The API validates these limits, strips unknown properties and uses the shared safe media presentation. Use embeds:[] to clear embeds on an edit; omitted embeds stay unchanged.
| Part | Limit |
|---|---|
| Embeds per message | 10 |
| Combined text across all embeds | 6,000 characters |
| Title or author name | 256 characters |
| Description | 4,096 characters |
| Footer | 2,048 characters |
| Fields per embed | 25 |
| Field name / value | 256 / 1,024 characters |
| Color | 24-bit RGB integer |