--- title: "Lookup Adaptor Actions Setup" slug: "lookup-adaptor-actions-setup" description: "App Actions allows companies to extend UI to add functionality that Gladly does not natively provide, including the ability to call into other systems." updated: 2026-03-12T23:45:37Z published: 2026-03-12T23:45:37Z canonical: "help.gladly.com/lookup-adaptor-actions-setup" --- > ## Documentation Index > Fetch the complete documentation index at: https://help.gladly.com/llms.txt > Use this file to discover all available pages before exploring further. # Lookup Adaptor Actions Setup > [!WARNING] > Actions require open Conversations > > Actions are only available in open Conversations. Once a Conversation is closed, Actions become unavailable. Imagine being able to add a button to a transaction card that allows an Agent to cancel an order or reactive a subscription: ![Order cancellation interface showing reason and notification options for customer.](https://cdn.us.document360.io/7047b671-c4f2-4df0-bb0a-b9b511fd2452/Images/Documentation/app_actions.webp?sv=2026-02-06&spr=https&st=2026-10-31T13%3A56%3A00Z&se=2026-10-31T14%3A56%3A00Z&sr=c&sp=r&sig=9YiyxONxiddcpxT73436UOUOCU6pB%2BKDJHPwKflp438%3D) Or create a discount code: ![Menu options including a highlighted discount code for Shopify retail services.](https://cdn.us.document360.io/7047b671-c4f2-4df0-bb0a-b9b511fd2452/Images/Documentation/discount_code.webp?sv=2026-02-06&spr=https&st=2026-10-31T13%3A56%3A00Z&se=2026-10-31T14%3A56%3A00Z&sr=c&sp=r&sig=9YiyxONxiddcpxT73436UOUOCU6pB%2BKDJHPwKflp438%3D) ## Introduction Gladly Actions can be applied to two targets: Customers and ORDER/SUBSCRIPTION type Transactions. When building a custom Lookup Adaptor, you may choose to send specific and unique Actions per Customer profile and transaction. Gladly will display the Actions that your Lookup Adaptor sends back. All Agents can perform any Action so long as it is returned by your Lookup Adaptor. Actions can only be performed if a Customer has already been linked (either manually or automatically). > [!NOTE] > Transaction-level Actions > > Actions at the transaction level are only available for ORDER and SUBSCRIPTION. ### High-Level Actions 1. Agent visits the linked Customer page, which triggers a detailed lookup to your Lookup Adaptor. 2. When Gladly receives the lookup response, we display any relevant actions alongside the order, subscription, or Plus menu. 3. Agent initiates an Action by selecting it in the order, subscription, or from the Plus menu. 4. Gladly fetches the action form and action submit endpoint from your Lookup Adaptor and displays it to the Agent. 5. Agent fills out and submits the form, which calls the submit Action endpoint specified in step four. 1. If either form validation fails or action submit fails, Gladly displays errors to the Agent. 2. If the action succeeds: 1. Gladly logs an audit event in the conversation feed. 2. Gladly refreshes the order or subscription data, which reflects updates from the action just performed. ## Configuring Actions via Detailed Lookup To configure Actions, your Customer lookup service should respond to the Detailed Lookup request by returning an array of actions per Profile and Transaction. Gladly uses the **name** of the Actions you define to display to Agents. ### Example Detailed Lookup Response With Actions Configured Sample Detailed Lookup request response with actions on the transaction **and** Customer Profile level. **POST** [https://your-lookup-adaptor-url.com](https://your-lookup-adaptor-url.com) ```plaintext {  "results": [    {      "externalCustomerId": "12345",      "actions": [        {          "name": "Discount Code (Shopify Retail)",          "formUrl": "/action?customer=12345"        }      ],      "emails": [        {          "original": "email@email.com"        }      ],      "phones": [        {          "original": "+16501234567",          "type": "MOBILE"        }      ],      "customAttributes": {        "points": "$100.00"      },      "name": "First Last",      "transactions": [        {          "type": "ORDER",          "orderId": "12345",          "actions": [            {              "name": "Cancel Refunded Order",              "formUrl": "/cancel?customer=12345&order=12345"            }          ]        }      ]    }  ] } ``` ![Order details showing a refund option and discount code for Shopify Retail.](https://cdn.us.document360.io/7047b671-c4f2-4df0-bb0a-b9b511fd2452/Images/Documentation/cancelrefundedorder.webp?sv=2026-02-06&spr=https&st=2026-10-31T13%3A56%3A00Z&se=2026-10-31T14%3A56%3A00Z&sr=c&sp=r&sig=9YiyxONxiddcpxT73436UOUOCU6pB%2BKDJHPwKflp438%3D) ## Action Fields | Field | Type | Required | Description | | --- | --- | --- | --- | | formUrl | URL | Yes | URL to use to fetch the actions form configuration. URL must be relative to the lookup service path defined in Settings > Apps. It uses the same authentication as your Lookup Adaptor. URL may include query parameters. URL must be in String format. | | name | String | Yes | Display name for action button. | ## Configuring the Form for a Specific Action > [!NOTE] > Shared with App Platform > > The Action form configuration format described below is also used by App Platform actions exposed via the Agent Desktop "+" menu. See [App Platform Actions](https://help.gladly.com/developer-tutorials/docs/app-platform-actions-in-agent-desktop) in Agent Desktop for details on configuring app platform action forms. When the Agent clicks the Action button, the details for the Action are retrieved. The expected response informs how the Action form display. At the bottom of the form, there are two buttons for confirming or cancelling. ## Example Response and Corresponding Form This call occurs when an agent presses an action button on your Lookup Adaptor. Let's use the cancel order action example above. **GET** [https://your-lookup-adaptor-url.com/cancel?customer=12345&order=12345](https://your-lookup-adaptor-url.com/cancel?customer=12345&order=12345) **Headers** - Gladly will send a header called Gladly-Agent-Id to your Lookup Adaptor in this request. This header’s value will correspond to the Gladly Agent ID that pressed the action button (requested the action form). In your Lookup Adaptor, you can use this header to adapt the content of the Action Form to the requesting Agent. For example, if different Agents have permission to create discount codes of different values or for different products - Note that Node.js (a popular JavaScript runtime environment) will represent this header key as gladly-agent-id (in lowercase) instead of its original Gladly-Agent-Id. - All Agents, regardless of permission in the Lookup Adaptor, will see the Action option in the Plus Menu. ```plaintext {  "actionUrl": "/actions/cancel?orderNumber=1390",  "title": "Cancel order #1391",  "submitButton": "Cancel Order",  "closeButton": "Close",  "sections": [    {      "type": "input",      "label": "Reason",      "attr": "reason",      "input": {        "type": "select",        "placeholder": "Please select a reason…",        "optional": false,        "options": [          {            "text": "Order mistake",            "value": "order-mistake"          },          {            "text": "Ships too late",            "value": "ships-late"          }        ]      },      "hint": "Cancelation reason is required"    },    {      "type": "input",      "attr": "reason",      "defaultValue": false,      "input": {        "type": "checkbox",        "text": "Send a notification to the customer"      }    }  ] } ``` ![Interface for canceling order #1391 with reason selection and notification options.](https://cdn.us.document360.io/7047b671-c4f2-4df0-bb0a-b9b511fd2452/Images/Documentation/cancel_ordernumber.webp?sv=2026-02-06&spr=https&st=2026-10-31T13%3A56%3A00Z&se=2026-10-31T14%3A56%3A00Z&sr=c&sp=r&sig=9YiyxONxiddcpxT73436UOUOCU6pB%2BKDJHPwKflp438%3D) ## Action Form Response Fields | Field | Type | Required | Description | | --- | --- | --- | --- | | title | String | Yes | Form title. Appears at the top of the form. | | actionUrl | URL | Yes | Endpoint to POST with form contents when form is submitted. URL is relative to the base lookup URL configured in Settings > Apps. Uses same auth mechanism as that configured in Settings > Apps as well. | | closeButton | String | No | Text for close button (to cancel the action) | | submitButton | String | No | Test for submit button (to complete the action) | | sections | Array | No | Input fields. See **Text Section** and **Input Section** documentation below | ### Text Section ```plaintext {  "type": "text",  "text": "This is a text section. It is nothing fancy, just some plain text" } ``` #### Text Section Fields | Field | Type | Required | Description | | --- | --- | --- | --- | | type | String | Yes | Always specify as `text` | | text | String | Yes | The text to display | ### Input Section **Input** section elements are elements that wrap a **text** | **select** | **checkbox**. ```plaintext {  "type": "input",  "attr": "notify",  "input": {    "text": "Send a notification to the customer.",    "type": "checkbox"  } } ``` #### Input Section Fields | Field | Type | Required | Description | | --- | --- | --- | --- | | type | String | Yes | Always specify as `input` | | label | String | Yes | The label to display next to the input field | | attr | String | Yes | Field name in the JSON repsonse. Must be unique across all form fields. | | defaultValue | Boolean | No | Initial value for the field. This value will update whenever the agent edits the field, and will be passed as the value corresponding to the key named in the `name` field in the JSON response. | | input | String | Yes | Input element. One of `text` or `select` or `checkbox`. | | hint | String | No | Optional hint string that appears beneath the input. | ### Text Input These elements are simple single-line text inputs. For example, to make a discount code of **SALE20**: ```plaintext {  "type": "text",  "placeholder": "e.g. SALE20",  "optional": false } ``` #### Text Input Fields | Field | Type | Required | Description | | --- | --- | --- | --- | | type | String | Yes | Always `text` | | placeholder | String | No | String that appears in the input when it has no value | | optional | Boolean | No | Whether the text input must have some content filled out. The form will display an error before submission if there is no content. Default is `false`. | ### Checkbox Input This element renders a checkbox. ![Checkbox option to send a notification to the customer for updates or alerts.](https://cdn.us.document360.io/7047b671-c4f2-4df0-bb0a-b9b511fd2452/Images/Documentation/send_notification.png?sv=2026-02-06&spr=https&st=2026-10-31T13%3A56%3A00Z&se=2026-10-31T14%3A56%3A00Z&sr=c&sp=r&sig=9YiyxONxiddcpxT73436UOUOCU6pB%2BKDJHPwKflp438%3D) ```plaintext {  "text": "Send a notification to the customer",  "type": "checkbox" } ``` #### Checkbox Input Fields | Field | Type | Required | Description | | --- | --- | --- | --- | | type | String | Yes | Always `checkbox` | | text | String | Yes | Label for the checkbox | ### Select Input These elements render a dropdown menu where an Agent can choose a single option. In the future, there will be multiple options. ```plaintext {  "type": "select",  "placeholder": "Please select a reason…",  "options": [    {      "text": "Order mistake",      "value": "order-mistake"    },    {      "text": "Payment declined",      "value": "declined"    }  ],  "optional": false } ``` #### Select Input Fields | Field | Type | Required | Description | | --- | --- | --- | --- | | type | String | Yes | Always `select` | | options | Array | Yes | Array of `select-option` elements | | placeholder | String | No | String that appears in the input when it has no value | | optional | Boolean | No | Whether the select input must have some content filled out. The form will display an error before submission if there is no content. Default is `false`. | **Select Option Fields** These elements comprise the options presented in the **select-input** dropdown menu. ![Dropdown menu displaying reasons for order issues like payment decline and fraud.](https://cdn.us.document360.io/7047b671-c4f2-4df0-bb0a-b9b511fd2452/Images/Documentation/select_options_fields.png?sv=2026-02-06&spr=https&st=2026-10-31T13%3A56%3A00Z&se=2026-10-31T14%3A56%3A00Z&sr=c&sp=r&sig=9YiyxONxiddcpxT73436UOUOCU6pB%2BKDJHPwKflp438%3D) ```plaintext {  "text": "Order mistake",  "value": "order-mistake" } ``` | Field | Type | Required | Description | | --- | --- | --- | --- | | text | String | Yes | Text that appears in menu item | | value | String | No | Value that is submitted as `select-option` value in the JSON response. If not provided, `text` field value will be used | ## Submitting the Form When the confirm button is clicked in the form, an HTTP POST request is made to the **url** specified in the form with the elements the agent entered into the form. **POST** [https://your-lookup-adaptor.com/actions/cancel?orderNumber=1390](https://your-lookup-adaptor.com/actions/cancel?orderNumber=1390) **Headers** - Gladly will send a header called Gladly-Agent-Id in this request to your Lookup Adaptor. This header’s value will correspond to the Gladly Agent ID that submitted the action form on your Lookup Adaptor. In your Lookup Adaptor, you can use this header to audit who performs actions and guard access to performing certain actions to particular Agents. - Note that Node.js (a popular JavaScript runtime environment) will represent this header key as gladly-agent-id (in lowercase) instead of its original Gladly-Agent-Id. ```plaintext {  "actionUrl": "/actions/cancel?orderNumber=%231390",  "notify": true,  "reason": "declined" } ``` The request payload will have the values specified in the form inputs. ## Form Errors When the form is submitted, there are 3 possible types of errors. - Validation - Agent entered invalid data - Permanent - Order is no longer valid to be returned - Other - For example, a network timeout ### Validation Errors Validation errors occur when the Agent needs to correct data in the form. The form will be updated with the error text and re-displayed for the Agent to correct the information. To show a validation error, the service should respond to the form submission with **400 Bad Request** response, and a payload that looks like the following. ```plaintext // 400 Response - errors displayed in the form {  "errors": [    {      "attr": "value",      "detail": "expected String to be a BigDecimal"    }  ] } ``` ### Error Response Fields | Field | Type | Required | Description | | --- | --- | --- | --- | | errors | Array | yes | Array of `error` objects | ### Error Object Fields | Field | Type | Required | Description | | --- | --- | --- | --- | | attr | String | no | The form attribute to assocaite with the error. Must match the `attr` of one of the form inputs. If no matching `attr` is provided, the error will not be displayed. | | detail | String | Yes | Descriptive text about the error. | ## Permanent Errors Permanent errors occur when Agents attempt an Action that is not possible. These errors appear as a red toast notification. ![Message indicating order cancellation is not possible for fulfilled orders.](https://cdn.us.document360.io/7047b671-c4f2-4df0-bb0a-b9b511fd2452/Images/Documentation/permanent_errors.png?sv=2026-02-06&spr=https&st=2026-10-31T13%3A56%3A00Z&se=2026-10-31T14%3A56%3A00Z&sr=c&sp=r&sig=9YiyxONxiddcpxT73436UOUOCU6pB%2BKDJHPwKflp438%3D) For example, if the Agent attempts to cancel an order that has already shipped, this is a permanent error. When this type of response is returned: - The form closes. - The Agent sees an error message. - The detailed lookup refreshes to determine what actions remain available. To show a permanent error, the service should respond to the form submission with a **406 Status Not Accepted** status and a payload that looks like the following. ```plaintext // 406 - Permanent failure, do not allow agents to take action again {  "errors": [    {      "detail": "Cannot cancel a paid and fulfilled order"    }  ] } ``` ## Other Errors These can include: - Network timeouts - Gladly does not receive a response from the service in 15 seconds - **500 Internal Server Error** where the service is not responding properly - **429 Too Many Requests** where the service is overwhelmed - All other HTTP codes are not enumerated above. In these cases, Gladly will keep the form open, and the Agent can retry submitting the Action. ## Form Success Any **20X** response to form submission will be considered an indication of success. When this type of response returns: - The form closes. - A record of the action performed adds to the conversation history. - The detailed lookup refreshes to determine what actions should remain available. - If the response body contains JSON in the following format, it will render in the success notification. ```plaintext // 200 - Success {  "message": "Order Refunded"  "detail": "Order #1391 was refunded $25.00." } ``` ### Success Object Fields A default actions Conversation Timeline update is shown if "detail" or "message" is missing. Both must be configured to avoid the default action message. ![Notification indicating successful action with details for developers to include messages.](https://cdn.us.document360.io/7047b671-c4f2-4df0-bb0a-b9b511fd2452/Images/Documentation/custom-app-contact-developer-1-1024x397.webp?sv=2026-02-06&spr=https&st=2026-10-31T13%3A56%3A00Z&se=2026-10-31T14%3A56%3A00Z&sr=c&sp=r&sig=9YiyxONxiddcpxT73436UOUOCU6pB%2BKDJHPwKflp438%3D) | Field | Type | Required | Description | | --- | --- | --- | --- | | message | String | Yes | Bolded summary message to show in the action record. | | detail | String | Yes | Detailed message to show in the action record.URLs automatically turn into a clickable link in the UI. Format text like **bold** and underline using HTML in the string using. Additional formatting like bold/underline to a URL will no longer be clickable. | ![Activity log showing Alice's order refund of $25 for order #1391.](https://cdn.us.document360.io/7047b671-c4f2-4df0-bb0a-b9b511fd2452/Images/Documentation/order-refunded.png?sv=2026-02-06&spr=https&st=2026-10-31T13%3A56%3A00Z&se=2026-10-31T14%3A56%3A00Z&sr=c&sp=r&sig=9YiyxONxiddcpxT73436UOUOCU6pB%2BKDJHPwKflp438%3D)