Asynchronously run your action blocks

Beta: This feature is in testing and may change as improvements are made.

With the async action feature, workflow builder action blocks can run asynchronously. This frees up time to perform complex operations without blocking the automation flow or faking successes, helping to prevent duplications and unnecessary retries. As a result, users have a smoother experience and resources are allocated more efficiently.

Concepts

Until now, action blocks were expected to return a quick, synchronous response. However, some actions (e.g., calling external APIs) take longer than the current response window allows. To avoid timeout errors, developers often immediately return a “success” response before the action logic has run.

This flow hides the block's true outcome from users, but the automation moves on as if it succeeded. If the developer waits too long to respond, they may face timeouts, retries, and duplications.

Async actions solve this by allowing developers to report the result when the action succeeds or fails. The automation then pauses and waits for this confirmation before continuing. This prevents duplication, avoids unnecessary retries, and gives users more visibility into what’s happening.

Asynchronous vs custom actions

Asynchronous action blocks work similarly to traditional custom actions- once the action is triggered, the monday apps server will send a POST request to the run URL configured in the custom block. After receiving the request, your app still must respond with a status of 200.

Unlike custom actions, asynchronous action blocks send a 200 response just to acknowledge that the action was triggered. The automation then pauses and waits for the app to perform the action. Once completed, the app sends another POST request to a new route to indicate success or failure.

The table below outlines the key similarities and differences between asynchronous action blocks and custom actions:

Asynchronous action blocks Custom actions
  • Allows you to build any actions not supported by built-in blocks
  • Receives a POST request at the configured run URL once triggered
  • Responds immediately with 200 status to acknowledge that the action was triggered
  • Automation waits for the result before continuing
  • Sends POST request to a new route to indicate success or failure
  • Allows you to build any actions not supported by built-in blocks
  • Receives a POST request at the configured run URL once triggered
  • Automation runs immediately after initial response
  • Responds after the action is completed with 200 status

Error handling

The response to the new route uses severity codes to indicate success or failure, following the existing error handling contract. HTTP status codes are not used since the action is completed in a request, not in the response.

To report an issue without triggering side effects (e.g., logging a message in the activity log), you can use severity code 2000 along with a runtime error description.

Implementation

Follow these steps to create an async action block:

  1. Open your app in the Developer Center.
  2. Create a new action block.
  3. In the Basic Details section, check Mark block as async.

Reference

Sample POST request body from monday server

{ 
  "payload": { 
    "blockKind": "action",
    "inboundFieldValues": {
      "boardId": 1234567890, 
      "columnId": "text",
      "itemId": 9876543210
    },
     "inputFields": { // input fields are based on the input fields configuration of your action and depend on the field type
        "boardId": 1234567890,
        "itemId": 9876543210,
        "columnId": "text"
      },
      "recipeId": 123456, //unique ID of the recipe for your app. if multiple accounts are using the same recipe, the same recipe ID will be sent
      "integrationId": 123456 //unique ID of the integration recipe added to your board
  }, 
  "runtimeMetadata": {
    "actionUuid": "a6676dzce11zd50b25c4871417e1zez1", // uuid that represents the execution of the action
    "triggerUuid": "z607d55cc428bb438ba02cbbcde6a25e" // uuid that represents the execution of the entire automation (same as run id in the activity log)
  }
}

Sample POST request after the action is triggered

HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "received",
  "message": "Action has been triggered.",
  "actionUuid": "a6676dzce11zd50b25c4871417e1zez1"
}

Sample POST request to report result

POST /your-endpoint-url HTTP/1.1
Host: your-api-server.com
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
{
  "success": true,
  "outputFields": {}
}
{
  "success": false,
  "severityCode": 4000,
  "runtimeErrorDescription": "This is the activity log description of 4000",
  "notificationErrorTitle": "This is the notification title of 4000",
  "notificationErrorDescription": "This is the notification description of 4000"
}