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.
- Tally webhook to a Sume music job: verify, dedupe, return 200 fast
Tally signs with base64 HMAC-SHA256, waits 10 s and retries up to a day. Verify the signature, use eventId as the Idempotency-Key, then start the Sume job.
- Telegram sendAudio for a Sume track: URL 20 MB, upload 50 MB
Telegram can fetch a sendAudio file from a URL up to 20 MB, or accept an upload up to 50 MB. Pass the Sume artifact link first; upload only as a fallback.
Written by Sume