--- title: "Ask to select a single answer from a list" description: "Use an input request to ask a multiple-choice question and allow a single answer." url: "https://docs.adyen.com/point-of-sale/shopper-engagement/shopper-input/menu" source_url: "https://docs.adyen.com/point-of-sale/shopper-engagement/shopper-input/menu.md" canonical: "https://docs.adyen.com/point-of-sale/shopper-engagement/shopper-input/menu" last_modified: "2025-03-14T16:17:00+01:00" language: "en" --- # Ask to select a single answer from a list Use an input request to ask a multiple-choice question and allow a single answer. [View source](/point-of-sale/shopper-engagement/shopper-input/menu.md) ##### Multiple-answer option To allow users to select more than one option, you can use a [multiple-answer question](/point-of-sale/shopper-engagement/shopper-input/multi-menu). Here we describe how you can use an input request to ask the shopper or your staff to select a menu option, such as an answer to a multiple choice question. You can use this, for example, to create a customer survey. You can show a header (your question), an optional second header (for example, an instruction), and up to 15 scrollable option buttons. Each option button can contain one or two text lines. ## Requirements Before you begin, take into account the following requirement. | Requirement | Description | | -------------------- | -------------------------------------------------------------------------------- | | **Integration type** | A [Terminal API integration](/point-of-sale/get-started) with payment terminals. | ## How it works When you use a **MenuButtons** `InputRequest`, the terminal prompts the shopper to answer a multiple-choice question that allows them to select only one option. The terminal continues to show your input request until one of these events occurs: * The user has provided input. * The maximum input time expires. You can set this time in the request. * On the terminal, **Cancel** **![](/images/e/b/5/8/6/eb5864c171bd3eac47d4a415a1f7e5dc0b075c28-cancel2x.png)** is selected. * The terminal receives a [request to cancel collecting input](/point-of-sale/shopper-engagement/shopper-input/cancel-input) or any other request from the POS app. ### Examples The following illustrations show a menu screen on a small portrait, a portrait, and landscape display. ![](/images/d/d/0/2/7/dd0275c877737b592b687acfaa8ea517b373d409-screen-engetmenuportrait-small.png) ![](/images/d/0/9/e/3/d09e3afa5ad46d86c1537f1b14635359da7c29ac-screen-engetmenuportrait.png) ![](/images/f/9/f/d/b/f9fdb11f4a5040fa3369312157283a0837802915-screenengetmenulandscape.png) The following illustrations show a menu screen with a second header line on a portrait, small portrait, and landscape display. ![](/images/1/7/f/5/6/17f56f49a2edb0c02dccd8f859e46fa4ccd65494-screenenmenusecondarytextportrait-small.png) ![](/images/e/d/6/a/5/ed6a510f618ec744d3052f2459c4a93057ab8f85-screen-enmenusecondarytextportrait.png) ![](/images/c/2/a/e/7/c2ae744cbe97012e55eda2f28c1f56225d9a3b93-screen-enmenusecondarytextlandscape.png) And finally these illustrations show a menu screen where the option buttons have a second line of text. ![](/images/9/f/5/c/0/9f5c0957755e1fad9bdad92fde175280609f6c18-screen-enmenumultilinebuttonportrait.png) ![](/images/4/9/1/c/1/491c1be23436cf966ee7d8b7f65cc34ceca77617-screen-enmenumultilinebuttonportrait-small.png) ![](/images/e/0/d/1/2/e0d1258c77fa6e84a26d0a3566b8a8eb97b4a572-screen-enmenumultilinebuttonlandscape.png) ## Make a single-answer MenuButtons input request We support two **MenuButtons** input requests: * Multiple choice—single answer: ensures no more than one answer is selected. * [Multiple choice—multiple answers](/point-of-sale/shopper-engagement/shopper-input/multi-menu): allows selecting more than one answer. To use the payment terminal to show a menu that allows the user to select only one option: 1. Make a [Terminal API](/point-of-sale/design-your-integration/terminal-api) input request, specifying: * The standard [`SaleToPOIRequest.MessageHeader` ](/point-of-sale/design-your-integration/terminal-api#request-message-header)object, with `MessageClass` set to **Device** and `MessageCategory` set to **Input**. | Parameter | Required | Description | | ----------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ProtocolVersion` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | **3.0** | | `MessageClass` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | **Device** | | `MessageCategory` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | **Input** | | `MessageType` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | **Request** | | `ServiceID` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your unique ID for this request, consisting of 1-10 alphanumeric characters. Must be unique within the last 48 hours for the terminal (`POIID`) being used. | | `SaleID` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your unique ID for the system where you send this request from. | | `POIID` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The unique ID of the terminal to send this request to. Format: *\[device model]-\[serial number]*. | - The [InputRequest.DisplayOutput](https://docs.adyen.com/api-explorer/terminal-api/latest/post/input#request-DisplayOutput) object to define what is shown on the terminal: | Parameter | Description | | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Device` | **CustomerDisplay** | | `InfoQualify` | **Display** | | `OutputContent.OutputFormat` | **Text** | | `OutputContent.PredefinedContent.ReferenceID` | **MenuButtons** | | `OutputContent.OutputText` | An array of one or two `Text` fields to specify the header. The second text field is optional; you can omit it from the request. For example, you can use the first text field to specify the question or menu name, and the second text field to add an instruction. | - The [InputRequest.DisplayOutput.MenuEntry](https://docs.adyen.com/api-explorer/terminal-api/latest/post/input#request-DisplayOutput-MenuEntry) array of up to 15 items representing the options to choose from. The terminal shows these items as a scrollable list of buttons that the user can tap to select. Each item in the array has: | Parameter | Description | | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `OutputFormat` | **Text** | | `OutputText` | An array of one or two `Text` fields to specify the answer or menu button. The first text field will show in bold. The second text field is optional; you can omit it from the request. For example, you could write a short-form answer in the first field, and the long-form answer in the second field. | - The [InputRequest.InputData](https://docs.adyen.com/api-explorer/terminal-api/latest/post/input#request-InputData) object to handle the user input: | Parameter | Description | | -------------- | ----------------------------------------------------------------------------------------- | | `Device` | **CustomerInput** | | `InfoQualify` | **Input** | | `InputCommand` | **GetMenuEntry** | | `MaxInputTime` | (Integer) Time-out in seconds. This is the time that the user gets to finish their input. | The following example asks the shopper to respond to a survey question. There is a second header below the question, and the answer options have only one line. #### JSON ```json { "SaleToPOIRequest":{ "MessageHeader":{ "ProtocolVersion":"3.0", "MessageClass":"Device", "MessageCategory":"Input", "MessageType":"Request", "ServiceID":"0207111104", "SaleID":"POSSystemID12345", "POIID":"V400m-324688179" }, "InputRequest":{ "DisplayOutput":{ "Device":"CustomerDisplay", "InfoQualify":"Display", "OutputContent":{ "OutputFormat":"Text", "PredefinedContent":{ "ReferenceID":"MenuButtons" }, "OutputText":[ { "Text":"How was your visit?" }, { "Text":"Please tap one of the options below:" } ] }, "MenuEntry":[ { "OutputFormat":"Text", "OutputText":[ { "Text":"Excellent" } ] }, { "OutputFormat":"Text", "OutputText":[ { "Text":"Good" } ] }, { "OutputFormat":"Text", "OutputText":[ { "Text":"Not so good" } ] }, { "OutputFormat":"Text", "OutputText":[ { "Text":"Bad" } ] } ] }, "InputData":{ "Device":"CustomerInput", "InfoQualify":"Input", "InputCommand":"GetMenuEntry", "MaxInputTime":120 } } } } ``` #### Java ```java SaleToPOIRequest saleToPOIRequest = new SaleToPOIRequest(); MessageHeader messageHeader = new MessageHeader(); saleToPOIRequest.setMessageHeader(messageHeader); InputRequest inputRequest = new InputRequest(); DisplayOutput displayOutput = new DisplayOutput(); displayOutput.setDevice( DeviceType.CUSTOMER_DISPLAY ); displayOutput.setInfoQualify( InfoQualifyType.DISPLAY ); OutputContent outputContent = new OutputContent(); outputContent.setOutputFormat( OutputFormatType.TEXT ); PredefinedContent predefinedContent = new PredefinedContent(); predefinedContent.setReferenceID("MenuButtons"); outputContent.setPredefinedContent(predefinedContent); OutputText headerLine1 = new OutputText(); headerLine1.setText("How was your visit?"); OutputText headerLine2 = new OutputText(); headerLine2.setText("Please tap one of the options below:"); outputContent.getOutputText().add(headerLine1); outputContent.getOutputText().add(headerLine2); displayOutput.setOutputContent(outputContent); MenuEntry menuEntry1 = new MenuEntry(); menuEntry1.setOutputFormat( OutputFormatType.TEXT ); OutputText option1Line1 = new OutputText(); option1Line1.setText("Excellent"); menuEntry1.getOutputText().add(option1Line1); displayOutput.getMenuEntry().add(menuEntry1); MenuEntry menuEntry2 = new MenuEntry(); menuEntry2.setOutputFormat( OutputFormatType.TEXT ); OutputText option2Line1 = new OutputText(); option2Line1.setText("Good"); menuEntry2.getOutputText().add(option2Line1); displayOutput.getMenuEntry().add(menuEntry2); MenuEntry menuEntry3 = new MenuEntry(); menuEntry3.setOutputFormat( OutputFormatType.TEXT ); OutputText option3Line1 = new OutputText(); option3Line1.setText("Not so good"); menuEntry3.getOutputText().add(option3Line1); displayOutput.getMenuEntry().add(menuEntry3); MenuEntry menuEntry4 = new MenuEntry(); menuEntry4.setOutputFormat( OutputFormatType.TEXT ); OutputText option4Line1 = new OutputText(); option4Line1.setText("Bad"); menuEntry4.getOutputText().add(option4Line1); displayOutput.getMenuEntry().add(menuEntry4); inputRequest.setDisplayOutput(displayOutput); InputData inputData = new InputData(); inputData.setDevice( DeviceType.CUSTOMER_INPUT ); inputData.setInfoQualify( InfoQualifyType.INPUT ); inputData.setInputCommand( InputCommandType.GET_MENU_ENTRY ); inputData.setMaxInputTime( BigInteger.valueOf(120) ); inputRequest.setInputData(inputData); saleToPOIRequest.setInputRequest(inputRequest); terminalAPIRequest.setSaleToPOIRequest(saleToPOIRequest); ``` 2. Wait for the user to supply the requested input. The input is not validated against a format. If input is received from the terminal, the input response includes an [InputResult](https://docs.adyen.com/api-explorer/terminal-api/latest/post/input#responses-200-InputResult) object with: * `Input.MenuEntryNumber`: An array that indicates the option that the user selected. For example, if the third option is selected, the third item in the array is `1` and all other array items are `0`. **Example response when the shopper selected an option** ```json { "SaleToPOIResponse": { "InputResponse": { "InputResult": { "Device": "CustomerInput", "InfoQualify": "Input", "Response": { "Result": "Success" }, "Input": { "MenuEntryNumber": [ 0, 0, 1, 0, 0 ], "InputCommand": "GetMenuEntry" } }, "OutputResult": { "Device": "CustomerDisplay", "InfoQualify": "Display", "Response": { "Result": "Success" } } }, "MessageHeader": { "ProtocolVersion": "3.0", "SaleID": "POSSystemID12345", "MessageClass": "Device", "MessageCategory": "Input", "ServiceID": "0207111104", "POIID": "V400m-324688179", "MessageType": "Response" } } } ``` * If the input request times out, the `InputResult.Response` has `AdditionalResponse`: **message=Screen%20timeout**, `Result`: **Failure**, and `ErrorCondition`: **Cancel**. * If you make a payment request while the input request is waiting for input on the terminal, the payment request overrides the input request. The `InputResult.Response` has `AdditionalResponse`: **message=A%20higher%20priority%20request%20has%20been%20received**, `Result`: **Failure**, and `ErrorCondition`: **Busy**. * If the user declined to respond (selected the **Cancel** key **![](/images/e/b/5/8/6/eb5864c171bd3eac47d4a415a1f7e5dc0b075c28-cancel2x.png)**), the `InputResult.Input.MenuEntryNumber` field is empty. The `InputResult.Response` has `Result`: **Failure** and `ErrorCondition`: **Cancel**. 3. Pass the relevant data from `InputResult.Input` to your system for validation and further use. ## See also * [Multiple choice - single answer](/point-of-sale/shopper-engagement/shopper-input/multi-menu) * [Cancel an input request](/point-of-sale/shopper-engagement/shopper-input/cancel-input) * [Ask for another type of input](/point-of-sale/shopper-engagement/shopper-input/select-input-request) * [Create a session](/point-of-sale/shopper-engagement/create-session)