Slack image block with a Sume URL: PNG or JPEG, alt text required
Slack's image block takes a public image_url up to 3000 characters and lists png, jpg, jpeg and gif. Generate a png with Sume, then post it with alt_text.

Post an image block with image_url set to the Sume data[0].url and a required alt_text. Slack's image block reference says alt_text is required (at most 2000 characters), image_url is a public URL of at most 3000 characters, and the supported file types are png, jpg, jpeg and gif. WebP is not listed, so request output_format png or jpeg from the Sume image API.
The block can show in modals, messages and home tabs, and title is optional plain text, also up to 2000 characters.
A bot that generates and posts
This Python script generates one image and posts it to a Slack incoming webhook. It stops when either secret is empty, and it posts only on a 200.
import json, os, urllib.request
KEY = os.environ.get("SUME_API_KEY", "")
HOOK = os.environ.get("SLACK_WEBHOOK_URL", "")
if not KEY or not HOOK:
raise SystemExit("SUME_API_KEY and SLACK_WEBHOOK_URL are required")
def post(url, body, headers):
req = urllib.request.Request(url, json.dumps(body).encode(), headers)
with urllib.request.urlopen(req, timeout=60) as r:
return r.status, r.read()
prompt = "flat illustration of a rocket launch, no text"
status, raw = post("https://api.sume.com/v1/images",
{"model": "openai/gpt-image-2.5", "prompt": prompt, "quality": "low",
"output_format": "png"},
{"Authorization": "Bearer " + KEY, "Content-Type": "application/json"})
if status != 200:
raise SystemExit(f"status {status}")
url = json.loads(raw)["data"][0]["url"]
block = {"blocks": [{"type": "image", "image_url": url, "alt_text": prompt}]}
print(post(HOOK, block, {"Content-Type": "application/json"})[0])What should alt_text say?
Use a description of what the picture shows, not the prompt copied blindly. The prompt above is short enough to double as alt text, but a longer prompt that lists style and camera terms reads badly in a screen reader. The field is required anyway, so a blank string is not an option.
If the call returns 202, the image is not ready: the job envelope has status_url and result_url. The script exits in that case; a real bot should poll as the jobs guide says and never resend the create request. A 502 is a terminal failure with an error envelope.
The URL in the block is public, so anyone in the channel, or anyone who gets the link, can open it. Keep confidential product images out of shared channels. Each 200 response carries usage.cost, the USD billed for that image, so a bot that posts daily can log the spend next to the message.
To change the picture for a thread, post a new block instead of editing the old one, and keep the old Sume URL in your own log. For a scheduled post, generate the image first and check the status code before you send anything to Slack, so a failed generation never produces a message with a broken or missing picture.
Sources
Related posts
More in Integrations
- Slack connector stopped working after an hour? Reconnect in Sume
When Slack returns no token expiry, Sume assumes one hour. After that an admin must connect again, because v1 has no automatic token renewal for integrations.
- Slack MCP has no dynamic registration: how Sume connects anyway
Slack's MCP server needs a registered Slack app with a client secret and does not support Dynamic Client Registration, so Sume uses its own Slack app.
- Slack consent worked but MCP rejects the app: enable Slack MCP
If Slack OAuth consent succeeds but MCP initialization is rejected, the Slack app has not enabled the Slack MCP server. It is a separate switch from Agents.
- Slack slash command for music: 3 s ack, 5 replies in 30 min
A Slack command must be acknowledged in 3 s; response_url then allows 5 replies in 30 min. Start the Sume music job in webhook mode and reply when it lands.
Written by Sume