> ## Documentation Index
> Fetch the complete documentation index at: https://docs.molin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom actions API

> Define HTTP endpoints your AI can call mid-chat to issue coupons, look up orders, book callbacks, and take other real actions for your customers.

The custom actions API allows you to define custom actions that can be triggered by users when they chat with your AI.

## Examples

Examples of custom actions include:

* Sending an email to the user with a discount code when they request one.
* Sending a message to a Slack channel when the user requests a callback.
* Providing product recommendations from your own database or inventory system.
* Collecting feedback from users and storing it in your own database.
* Collecting leads and storing them in your CRM system.

## How it works

1. You need to define a custom action in the [molin.ai](https://molin.ai) dashboard. You can define the name, description, and parameters that the action requires (e.g. email address, phone number, etc).
2. Your team needs to implement an API endpoint. This endpoint should accept the parameters defined in the dashboard and perform the action (e.g. generate a coupon and email it to the user).
3. You should enable the action from the dashboard and test it in the chat preview.

## How to create a custom action

1. Go to the [Actions page](https://molin.ai/app/actions) and click on the **New custom action** button.
2. Fill in a **name** and **description**. The **name** should describe succinctly what the action does. The **description** should provide more details about the action. Both the **name** and the **description** will be given to our AI so that it knows *when* to call the action. *See the example screenshot below*
3. Define the parameters that the action requires. For example, if the action is to email the user a coupon, you might need the user's email address. You must define correctly the type of each parameter (e.g. string, number, or boolean).
4. Choose the HTTP method (**POST** or **GET**) and define the endpoint URL where the action will be triggered. This URL should be accessible from the internet and should accept the parameters defined in the previous step. The endpoint should return plain text or JSON.

<Note>
  The entire response body from your endpoint will be given to the AI so it can respond to the user. Although the AI will only use the body to formulate its own answer, assume that the body *can* be
  shown to the user.
</Note>

![Example custom action](https://imagedelivery.net/JWssb2diw2B-JHR2ojV3Ow/41c41340-b779-44a0-b671-fe7079160400/fit=scale-down,q=75,dpr=1)

![Example chat](https://imagedelivery.net/JWssb2diw2B-JHR2ojV3Ow/393fd33a-c3a6-4a8e-3d15-02bdce802d00/fit=scale-down,q=75,dpr=1)

## How to create your endpoint

You can use any stack to create an HTTP web server that conforms to the following requirements.

<Note>Only HTTPS endpoints are supported.</Note>

### Requirements

#### Request

The request uses the HTTP method you chose when defining the action, **POST** by default. You can read the `x-molin-` headers to get additional information about the widget and conversation.

For a **POST** action, the parameters defined in the dashboard are sent as a JSON body:

```
POST https://your-endpoint.com/your-action
Content-Type: application/json
x-molin-custom-actions-version: 2024-11-01
x-molin-widget-id: widget-id
x-molin-conversation-id: conversation-id

{
  "your_defined_param": "some value from user input"
}
```

For a **GET** action, parameters are sent as query params instead, and no body is sent:

```
GET https://your-endpoint.com/your-action?your_defined_param=some+value+from+user+input
x-molin-custom-actions-version: 2024-11-01
x-molin-widget-id: widget-id
x-molin-conversation-id: conversation-id
```

##### URL path placeholders

If your endpoint expects a value as part of the URL path rather than a query param or body field, wrap a parameter name in curly braces in the endpoint URL, e.g. `https://your-endpoint.com/products/{productId}/availability`. Any parameter matching a `{paramName}` placeholder fills that path segment instead of being sent as a query param or body field; the remaining parameters are still sent normally for the chosen HTTP method. This works for both GET and POST actions.

<Note>
  Every placeholder in the endpoint URL must have a matching parameter defined in the dashboard, otherwise the action fails instead of calling your endpoint with an unresolved placeholder still in the
  URL.
</Note>

#### Response

The response should be plain text or JSON. The entire body will be given to the AI so it can respond to the user.

```
Content-Type: text/plain or application/json

any plain text or JSON
```

<Note>The response will be trimmed down to 8000 characters before being given to the AI. Make sure you don't exceed this length limit.</Note>

### Example

```
POST https://molin.your-shop.com/actions/generate-coupon-code
Content-Type: application/json
x-molin-custom-actions-version: 2024-11-01
x-molin-widget-id: widget123
x-molin-conversation-id: fce602af-39f2-4717-b2e0-698357b4f109

{
  "email": "john@testington.com"
}
```

```
Content-Type: text/plain

Success. Generated coupon code: LUCKY53215
```

## Response format recommendations

While the AI can understand JSON and XML, we recommend that you format your response as human readable plain text or markdown.

<Note>The response will be trimmed down to 8000 characters before being given to the AI. Make sure you remove any unnecessary information to stay under the 8000 character limit.</Note>

For example, if your custom action returns the order history for your customer, we recommend the following format:

```
Order ID: SHOP123
Creation date: 2025-01-01
Items:
- 1 x Blue jumper
- 2 x Red socks
Total cost: 100 USD

Order ID: SHOP456
…
```

## Special UI card responses

Your custom action endpoint can return structured data that will be rendered as interactive UI cards in the chat. This provides a richer user experience for certain types of data like products and orders.

### Product Card

```json theme={null}
{
  "url": "https://shop.com/product/123",
  "name": "Product Name",
  "description": "Product description",
  "price": "$100"
}
```

### Order Card

```json theme={null}
{
  "order_id_label": "Order ID",
  "order_id_value": "RTX-789012",
  "timeline": {
    "step": [
      {
        "label": "Order Placed",
        "status": "completed"
      },
      {
        "label": "Processing",
        "status": "completed"
      },
      {
        "label": "Shipped",
        "status": "in_progress"
      }
    ]
  },
  "items": {
    "item": [
      {
        "name": "Premium Cotton T-Shirt",
        "quantity": "2",
        "price": "$29.99",
        "image": "https://placehold.co/400x300/orange/white/png"
      },
      {
        "name": "Leather Wallet",
        "quantity": "1",
        "price": "$45.00"
      }
    ]
  },
  "total_label": "Total",
  "total_amount": "$104.98",
  "customer_name": "John Doe",
  "shipping_label": "Shipping",
  "shipping_method": "FedEx Express",
  "payment_label": "Payment",
  "payment_method_label": "Method",
  "payment_method_value": "Credit Card",
  "payment_status_label": "Status",
  "payment_status_value": "Paid",
  "order_tracking_label": "Track Order",
  "order_tracking_url": "https://fedex.com/track/RTX-789012"
}
```

#### Order Card with XML

You can also return order data in XML format:

```xml theme={null}
<order>
  <order_id_label>Order ID</order_id_label>
  <order_id_value>RTX-789012</order_id_value>
  <timeline>
    <step>
      <label>Order Placed</label>
      <status>completed</status>
    </step>
    <step>
      <label>Shipped</label>
      <status>in_progress</status>
    </step>
  </timeline>
  <items>
    <item>
      <name>Premium Cotton T-Shirt</name>
      <quantity>2</quantity>
      <price>$29.99</price>
      <image>https://placehold.co/400x300/orange/white/png</image>
    </item>
  </items>
  <total_label>Total</total_label>
  <total_amount>$104.98</total_amount>
  <customer_name>John Doe</customer_name>
  <order_tracking_url>https://fedex.com/track/RTX-789012</order_tracking_url>
</order>
```

<Note>Timeline can have 1–5 steps. Status values must be one of: `completed`, `in_progress`, `pending`, or `failed`. Use `failed` for a step that encountered an error.</Note>

## Using a test endpoint for development

If you wish to test quickly, you can use [Beeceptor](https://beeceptor.com/), a free service that allows you to create a temporary endpoint that you can use to test your custom action.

You can use the following URL as your endpoint in your custom action:

```
https://custom-action-generate-coupon-code.free.beeceptor.com
```

You can view requests sent to it [here](https://app.beeceptor.com/console/custom-action-generate-coupon-code).

## Static IPs

All calls on behalf of custom actions sent to your server are made through the following IPs:

```
35.207.69.21
209.38.162.129
```

<Note>Make sure you allowlist all of them if your server has IP restrictions.</Note>
