Skip to content

Modals (forms)

A modal is a pop-up window with a form. Use it to ask the user for text, choices or files.

Preview
Send us your feedback
What do you think of the bot?*
Tell us anything, in a few words.
I love it because...
Rating*
Pick a rating
modal.json
{
"type": 9,
"data": {
"custom_id": "feedback_modal",
"title": "Send us your feedback",
"components": [
{
"type": 18,
"label": "What do you think of the bot?",
"description": "Tell us anything, in a few words.",
"component": {
"type": 4,
"custom_id": "opinion",
"style": 2,
"placeholder": "I love it because...",
"max_length": 1000
}
},
{
"type": 18,
"label": "Rating",
"component": {
"type": 3,
"custom_id": "rating",
"placeholder": "Pick a rating",
"options": [
{
"label": "⭐⭐⭐⭐⭐ Excellent",
"value": "5"
},
{
"label": "⭐⭐⭐ Okay",
"value": "3"
},
{
"label": "⭐ Needs work",
"value": "1"
}
]
}
}
]
}
}
  1. The user runs a command or clicks a button.
  2. Your bot responds with the MODAL (9) response type. Opening the modal is the response, so it must be the first thing you do.
  3. The user fills in the form and clicks Submit.
  4. Your bot receives a MODAL_SUBMIT (5) interaction with the values, and responds (for example with a message).
Field Type Description
custom_id string required Identifies the modal when you receive the answer (1-100 characters).
title string required Window title (max 45 characters).
components array required Between 1 and 5 components: Label or Text Display.
Component How it’s used
Text Display Directly, to show explanatory text.
Label Wraps one input component and gives it a title and description.
Text Input Inside a Label.
String Select and auto-populated menus Inside a Label.
File Upload Inside a Label.
Radio Group, Checkbox Group and Checkbox Inside a Label.

Send the JSON above (the one starting with "type": 9) to:

POST /interactions/{interaction.id}/{interaction.token}/callback

When the user clicks Submit, you receive a MODAL_SUBMIT (5) interaction. Each Label arrives with its component and the entered value:

MODAL_SUBMIT interaction data
{
"custom_id": "feedback_modal",
"components": [
{
"type": 18,
"id": 1,
"component": { "type": 4, "id": 2, "custom_id": "opinion", "value": "I love it!" }
},
{
"type": 18,
"id": 3,
"component": { "type": 3, "id": 4, "custom_id": "rating", "values": ["5"] }
}
]
}
Component Where the value is
Text Input value (string)
Selects values (array of strings with the values or IDs)
File Upload values (attachment IDs; full data is in resolved.attachments)
Radio Group value (string, or null if nothing was picked)
Checkbox Group values (array of strings)
Checkbox value (true or false)

Loop over data.components, find the custom_id you want inside each component and read its value or values.

If you’re coming from embeds, read the migration guide.