---
name: watson-assistant-webhook-post-wa
title: Calling a service after processing a message for watsonx Assistant
description: Use a post-message webhook to call an external service after your assistant generates a response.
last-updated: 2025-07-10
---

> ## Documentation Index
> The table of contents for this documentation set is at https://cloud.ibm.com/docs/watson-assistant?format=markdown
> The index for all IBM Cloud docs is at: https://cloud.ibm.com/docs/llms.txt
> Use these files to discover more information as needed.

# Calling a service after processing a message for watsonx Assistant
{: #webhook-post-watson-assistant}

Use a post-message webhook to call an external service after your assistant generates a response.  
{: shortdesc}

You can use post-message webhooks for the following use cases:

 - Retrieve a response from an external source by using custom action IDs.
 - Translate the assistant's response to the user's language.
 - Reinsert personal data that was removed earlier for privacy.

## Learn more

For more information about related features and details, see the following resources:

 - [Making a call before processing a message](https://cloud.ibm.com/docs/watson-assistant?topic=watson-assistant-webhook-pre&format=markdown)
 - [Calling a service before processing a message for watsonx Assistant](https://cloud.ibm.com/docs/watson-assistant?topic=watson-assistant-webhook-pre-watson-assistant&format=markdown)
 - [Making a programmatic call from dialog](https://cloud.ibm.com/docs/watson-assistant?topic=watson-assistant-dialog-webhooks&format=markdown#dialog-webhooks)
 - [API reference](https://cloud.ibm.com/apidocs/assistant-v2#message)

## Before you begin

Your webhook service must meet these technical requirements:

 - Do not set up or test the webhook in a production environment.
 - The call must be a POST HTTP request.
 - The request and response must use JSON (Content-Type: application/json).
 - The response must return within 30 seconds.

## Procedure
{: #post-procedure-watson-assistant}

This section covers the procedure to define, test, and remove post-message webhooks for watsonx Assistant.

- [**Webhook configuration**](#post-webhook-config-watson-assistant)
- [**Configuring webhook error handling for postprocessing**](#post-error-handling-watson-assistant)
- [**Testing the webhook**](#post-testing-watson-assistant)
- [**Troubleshooting the webhook**](#post-troubleshoot-watson-assistant)
- [**Example request body**](#post-example-request-watson-assistant)
- [**Example 1**](#post-example-1-watson-assistant)
- [**Example 2**](#post-example-2-watson-assistant)
- [**Removing the webhook**](#post-remove-watson-assistant)

### Webhook configuration
{: #post-webhook-config-watson-assistant}

To add the webhook details, complete the following steps:

1. From the navigation panel, click **Environments** and open the environment where you want to configure the webhook.

1. Click the ![Environment settings icon](images/gear-icon-black.png) icon to open the environment settings.

1. Set the **Post-message webhook** switch to **Enabled**.

1. In the **Synchronous event**, select from one of the following options:

   - Continue processing user input without webhook update if there is an error.

   - Return an error to the client if the webhook call fails.

   For more information, see [Configuring webhook error handling for postprocessing](#post-error-handling-watson-assistant).

1.  In the **URL** field, add the URL for the external application to which you want to send HTTP POST request callouts.

    For example, maybe you store your assistant's responses in a separate content management system. When the assistant understands the input, the processed action returns a unique ID that corresponds to a response in your CMS. To call a service that retrieves a response from your CMS for a given unique ID, specify the URL for your service instance. For example, `https://example.com/get_answer`.

    You must specify a URL that uses the SSL protocol, so specify a URL that begins with `https`.

1.  To configure the authentication for post-message webhooks, click **Edit authentication**. For detailed instructions, see [Defining the authentication method for pre-message and post-message webhooks](https://cloud.ibm.com/docs/watson-assistant?topic=watson-assistant-define-webhook-auth&format=markdown). 

1. In the **Timeout** field, specify the time duration (in seconds) that you want the assistant to wait for a response from the webhook before it returns an error. The timeout duration cannot be shorter than 1 second or longer than 30 seconds.

1.  In the **Headers** section, click **Add header +** to add any headers that you want to pass to the service, one at a time.

    If the external application that you call returns a response, it might be able to send a response in different formats. The webhook requires that the response is formatted in JSON. The following table illustrates how to add a header to indicate that you want the resulting value to be returned is in JSON format.

    | Header name    | Header value       |
    |----------------|--------------------|
    | `Content-Type` | `application/json` |
    {: caption="Header example" caption-side="bottom"}

1. After you save the header value, the string is replaced by asterisks and can't be viewed again. 

1. Your webhook details are saved automatically.

### Configuring webhook error handling for postprocessing
{: #post-error-handling-watson-assistant}

You can decide whether an error returns in the postprocessing step if the webhook call fails. You have two options:

- **Continue processing user input without webhook update if there is an error**: The assistant ignores the errors and processes the message without the webhook result. If postprocessing is useful but not essential, consider this option.

- **Return an error to the client if the webhook call fails**: If postprocessing is critical after the assistant sends a response, select this option.

When you enable **Return an error to the client if the webhook call fails**, everything stops until the postprocessing step is completed successfully.{: important}

Regularly test the external process to identify potential failures. If necessary, adjust this setting to prevent disruptions in the response processing.

### Testing the webhook
{: #post-testing-watson-assistant}

Do extensive testing of your webhook before you enable it for an assistant that is used in a production environment.
{: important}

The webhook is triggered only when your assistant processes a message and a response is ready to be returned to the channel.

### Troubleshooting the webhook
{: #post-troubleshoot-watson-assistant}

The following error codes can help you track down the cause of issues you might encounter. If you have a web chat integration, for example, you know that your webhook has an issue if every test message you submit returns a message such as `There is an error with the message you just sent, but feel free to ask me something else`. If this message is displayed, use a REST API tool, such as cURL, to send a test `/message` API request, so you can see the error code and the full message that is returned.

| Error code and message | Description |
|------------|-------------|
| 422 Webhook responded with invalid JSON body | The webhook's HTTP response body could not be parsed as JSON. |
| 422 Webhook responded with `[500]` status code | A problem occurred with the external service that you called. The code failed or the external server refused the request. |
| 500 Processor Exception : `[connections to all backends failing]` | An error occurred in the webhook microservice. It could not connect to backend services. |
{: caption="Error code details" caption-side="bottom"}

### Example request body
{: #post-example-request-watson-assistant}

It is useful to know the format of the request post-message webhook body so that your external code can process it.

The payload contains the response body that your assistant returns for the version 2 of the `/message`, stateful and stateless, API call. The event name `message_processed` indicates that the post-message webhook generates the request. For more information about the message request body, see the [API reference](https://cloud.ibm.com/apidocs/assistant-v2#message){: external}.

The following sample shows how a simple request body is formatted:

```json
{
 "event": {
    "name": "message_processed"
},
"options": {},
"payload": {
    "output": {
        "intents": [
            {
                "intent": "General_Greetings",
                "confidence": 1
            }
        ],
        "entities": [],
        "generic": [
            {
                "response_type": "text",
                "text": "Hello. Good evening"
            }
        ]
    },
    "user_id": "test user",
    "context": {
        "global": {
            "system": {
                "user_id": "test user",
                "turn_count": 11
            },
            "session_id": "sxxx"
        },
        "skills": {
            "actions skill": {
                "user_defined": {
                    "var": "anthony"
                },
                "system": {
                    "state": "nnn"
                }
            }
        }
    }
}
```
{: codeblock}

### Example 1
{: #post-example-1-watson-assistant}

This example shows how to add `y'all` to the end of each response from the assistant.

In the post-message webhook configuration page, the following values are specified:

- **URL**: `https://your-webhook-url/`
- **Header name**: Content-Type
- **Header value**: application/json

The post-message webhook calls an IBM Cloud Functions web action name `add_southern_charm`.

The node.js code in the `add_southern_charm` web action looks as follows:

```javascript
function main(params) {
  console.log(JSON.stringify(params))
  if (params.payload.output.generic[0].text !== '') {
      //Get the length of the input text
        var length = params.payload.output.generic[0].text.length;
        //create a substring that removes the last character from the input string, which is typically punctuation.
        var revision = params.payload.output.generic[0].text.substring(0,length-1);
        const response = {
            body : {
                payload : {
                    output : {
                        generic : [
                              {
                                  //Replace the input text with your shortened revision and append y'all to it.
                                "response_type": "text",
                                "text": revision + ', ' + 'y\'all.'
                              }
                        ],
                    },
                },
            },
        };
        return response;
  }
  else {
    return { 
        body : params
    }
  }
}
```
{: codeblock}

### Example 2
{: #post-example-2-watson-assistant}

This example shows how to translate a message response back to the customer's language. It works only if you perform the steps in [Example 2](https://cloud.ibm.com/docs/watson-assistant?topic=watson-assistant-webhook-pre-watson-assistant&format=markdown#pre-example-2-watson-assistant) to define a pre-message webhook that translates the original message into English.

Define a sequence of web actions in IBM Cloud Functions. The first action in the sequence checks for the language of the original incoming text, which you stored in a context variable named `original_input` in the pre-message webhook code. The second action in the sequence translates the dialog response text from English into the original language that was used by the customer.

In the post-message webhook configuration page, the following values are specified:

- **URL**: `https://your-webhook-url/`
- **Header name**: Content-Type
- **Header value**: application/json

The node.js code for the first web action in your sequence looks as follows:

```javascript
let rp = require("request-promise");

function main(params) {
console.log(JSON.stringify(params))

if (params.payload.output.generic[0].text !== '') {
const options = { method: 'POST',
  url: 'https://api.us-south.language-translator.watson.cloud.ibm.com/instances/572b37be-09f4-4704-b693-3bc63869nnnn/v3/identify?version=2018-05-01',
  auth: {
           'username': 'apikey',
           'password': 'nnnn'
       },
  headers: {
    "Content-Type":"text/plain"
},
  body: [
          params.payload.context.skills['actions skill'].user_defined.original_input
  ],
  json: true,
};
     return rp(options)
    .then(res => {
      //Set the language property of the incoming message to the language that was identified by Watson Language Translator. 
        params.payload.context.skills['actions skill'].user_defined['language'] = res.languages[0].language;
        console.log(JSON.stringify(params))
        return params;
})
}
else {
    params.payload.context.skills['actions skill'].user_defined['language'] = 'none';
    return param
}
};
```
{: codeblock}

The second web action in the sequence looks as follows:

```javascript
let rp = require("request-promise");

function main(params) {
  console.log(JSON.stringify(params))
    if ((params.payload.context.skills["actions skill"].user_defined.language !== 'en') && (params.payload.context.skills["actions skill"].user_defined.language !== 'none')) {
    const options = { method: 'POST',
    url: 'https://api.us-south.language-translator.watson.cloud.ibm.com/instances/572b37be-09f4-4704-b693-3bc63869nnnn/v3/translate?version=2018-05-01',
    auth: {
            'username': 'apikey',
            'password': 'nnn'
        },
    body: { 
        text: [ 
            params.payload.output.generic[0].text
            ],
            target: params.payload.context.skills["actions skill"].user_defined.language
    },
    json: true 
    };
      return rp(options)
      .then(res => {
          params.payload.context.skills["actions skill"].user_defined["original_output"] = params.payload.output.generic[0].text;
          params.payload.output.generic[0].text = res.translations[0].translation;
          return {
            body : params
          }
  })
  }
  return { 
    body : params
  }
};
```
{: codeblock}

### Removing the webhook
{: #post-remove-watson-assistant}

If you do not want to process message responses with a webhook, complete the following steps:

1. In your assistant, go to **Environments** and open the environment where you want to remove the webhook.

1. Click the ![Environment settings icon](images/gear-icon-black.png) icon to open the environment settings.

1. On the **Environment settings** page, click **Post-message webhook**.

1. Do one of the following steps:

 - To stop calling a webhook to process every incoming message, set the **Post-message webhook** switch to **Disabled**.

 - To change the webhook that you want to call, click **Delete webhook**.