Slack Workflow webhook trigger: flatten a Sume result, no nested JSON
Slack's webhook-started workflows take up to 20 flat variables and 1 request per second. Flatten Sume's nested artifacts into plain text values before you post.

A Slack workflow that starts with a webhook accepts only flat variables, so a Sume job.completed body cannot be forwarded as it is. Its artifacts sit in a nested payload.artifacts[] array, and Slack documents that nested JSON is not currently possible in workflow variables. Put a small relay between the two, copy four plain text values, and keep the rate at one request per second.
What Slack documents
The facts below come from Slack's help page on webhook-started workflows.
| Topic | Slack says |
|---|---|
| Plan | Available on paid plans only |
| Variables | Up to 20 per workflow; types are channel ID, user ID, user email and text |
| Structure | Nested JSON in workflow variables is not currently possible |
| Rate | Webhook workflows are limited to one request per second |
| Secrecy | Anyone with the request URL can start the workflow, so keep it secret |
Flatten the Sume payload
A Sume job webhook has event, request_id, job_id, status (OK or ERROR) and a payload. For a completed job, payload.artifacts[] holds the artifacts with a url and a type. Slack variables are text, so pick the first artifact and copy its URL and type. Name the variables in the workflow exactly as the keys that you send.
import json, urllib.request
def flatten(event):
arts = (event.get("payload") or {}).get("artifacts") or []
first = arts[0] if arts else {}
return {
"job_id": event["job_id"],
"status": event["status"],
"kind": first.get("type", ""),
"media_url": first.get("url", ""),
}
def send_to_slack(trigger_url, event):
req = urllib.request.Request(
trigger_url,
data=json.dumps(flatten(event)).encode(),
headers={"Content-Type": "application/json"},
)
urllib.request.urlopen(req, timeout=10).read()Pace the relay, then answer Sume first
Sume gives your receiver 10 seconds per attempt and wants a 2xx once you have stored the event. Do not call Slack inside that window. Write the event to a queue, return 204, and let a worker drain the queue at one send per second or slower. If many jobs finish together, the queue absorbs the burst; Slack never sees more than its limit.
Failed jobs too
job.failed and job.canceled use status: "ERROR" and carry no artifacts. Let the workflow branch on status, so the channel gets a short failure notice and the link stays empty. Keep job_id in every message: it is the key that you need for Redeliver, for status reads and for support.
When not to use this
If you need buttons, threads, or file uploads, a Slack app is the better tool. A webhook-started workflow is a good fit for a one-way track-is-ready message. And because the trigger URL is a bearer secret, store it like an API key and rotate it if it leaks.
Sources
Related posts
More in Integrations
- Snapchat monetization advice: closed captions, 30 s, and Sume
Snapchat's monetization page says videos need 30 seconds for revenue and recommends closed captions. Burn captions with Sume video captions at $0.20 per job.
- Snapchat Spotlight Post button needs 5 seconds: probe and trim
Snapchat says the Post button for Spotlight appears when a video is at least 5 seconds. Probe a clip's duration with Sume, trim the dead lead-in, and re-check.
- Where Sume stores connector tokens: AES-256-GCM, never in status
Sume encrypts connector tokens and pending PKCE data with AES-256-GCM, fails closed without a key, and its status endpoint returns no credentials.
- Sume Slack connector: read and search only, no chat:write
The Sume Slack integration gives agents search and read tools over a user token. It requests no chat:write, reactions, canvas, list or file-upload scopes.
Written by Sume