Webhook payload parsing for Slack blocks on queue SLA breach

I’ve been trying to wire up a webhook in Genesys Cloud to push alerts to Slack whenever a queue breaches its service level. We’re using this for WFM adherence tracking, so it’s pretty critical that the notification actually renders correctly in the channel.

The webhook fires fine. I can see the events coming through in the logs. The problem is the JSON structure I’m sending to Slack’s incoming webhook endpoint. It keeps failing validation with a 400 Bad Request.

Here’s the payload I’m constructing in the webhook action. I’m trying to use Slack’s block kit format.

{
 "channel": "#wfm-alerts",
 "blocks": [
 {
 "type": "section",
 "text": {
 "type": "mrkdwn",
 "text": ":warning: Queue SLA Breach\nQueue: ${queue.name}\nCurrent SLA: ${metrics.sla.value}"
 }
 }
 ]
}

The error response from Slack is pretty vague.

{"error": "invalid_blocks"}

I’m using the queue.name and metrics.sla.value from the Genesys Cloud event payload. I know the event data is correct because I’ve logged it to a file and the values look good. But when it hits Slack, it chokes.

Is there something specific about how Genesys Cloud webhooks handle nested objects or special characters in the substitution? I’ve tried escaping the newlines with \n and even \r\n but no luck. The documentation for the webhook action doesn’t really cover the Slack block kit specifics.

Does anyone have a working example of a Slack block payload from a Genesys Cloud webhook? I feel like I’m missing a simple syntax error here.

Slack’s block kit is notoriously strict. If you’re sending a flat JSON object instead of an array under blocks, it’ll bomb out with a 400. Also, make sure you’re setting the content type to application/json in the webhook configuration.

Here’s the minimal payload structure that actually works. Note the blocks array is mandatory.

{
 "text": "Queue SLA Breach: {{queueName}}",
 "blocks": [
 {
 "type": "section",
 "text": {
 "type": "mrkdwn",
 "text": "*{{queueName}}* is breaching SLA.\nCurrent wait: {{currentWaitTime}}s"
 }
 },
 {
 "type": "actions",
 "elements": [
 {
 "type": "button",
 "text": {
 "type": "plain_text",
 "text": "View Queue",
 "emoji": true
 },
 "url": "https://{{orgName}}.mygenesys.cloud/admin/queues/{{queueId}}"
 }
 ]
 }
 ]
}

If you’re using the Genesys Cloud UI to build the webhook, map the variables carefully. The queueName and currentWaitTime need to come from the event payload. Check the “Test Webhook” button in the admin console. It shows you the exact JSON that will be sent. If that test fails, Slack will reject it.

One gotcha: Slack blocks have a character limit on text elements. If queueName is long, truncate it or put the full name in the text fallback field instead of the block text.