Slack scheduleMessage: announce a finished Sume render

Slack lets a bot schedule a post up to 120 days ahead, with at most 30 per 5 minutes in a channel. Finish the Sume render first, then schedule the announcement.

5 min readSume
All posts

Render with Sume first, then schedule the Slack announcement for the time you want, not the other way around. chat.scheduleMessage takes a post_at up to 120 days ahead, so a finished render can wait for a launch hour. A Slack channel accepts at most 30 scheduled messages in a 5 minute window, so a batch of finished renders needs to be spaced out.

The Slack facts are from chat.scheduleMessage, read 2026-10-10. The Sume facts are from Runs and results and Run webhooks.

What are the Slack limits?

The method page lists a Tier 3 rate limit, a maximum of 120 days ahead, and no more than 30 messages in a 5 minute window to the same channel. The errors time_in_past and time_too_far report a bad time. Messages scheduled with metadata do not post, so leave metadata off.

The 120 day horizon is generous, but a far-off post is a promise. If you change the render later, you need to delete the scheduled message and schedule a new one. Keep the ids.

Scheduling limits (Slack docs, read 2026-10-10)
LimitValueEffect on a render announcement
Horizon120 daysPlan a release up to about four months out
Per channel30 messages per 5 minutesSpread a 100-render batch over time
time_in_pastErrorCompute post_at after the render ends
time_too_farErrorReject dates beyond 120 days
MetadataMessage does not postDo not attach it

Why render first?

A scheduled message holds the text you gave it. If you schedule a post that links to a render before the render exists, you commit to a link that may point at a failed run. Run first, wait for the format.run.terminal webhook with outcome ok, then schedule.

Media URLs from a finished Format run are durable media.sume.com HTTPS URLs that do not expire, per the runs page. A message scheduled 60 days out therefore still points at working media.

Time zones are the usual source of time_in_past. Compute post_at as a Unix time in UTC from the launch hour in the audience's zone, and check that it is in the future by a small margin before you call Slack.

How do I handle a batch?

If 100 renders finish within minutes, you cannot schedule all 100 for the same minute in one channel. With a limit of 30 per 5 minutes, count the windows: 100 / 30 rounds up to 4 windows, so the last message goes out at least 15 minutes after the first when you schedule them as they finish. Instead, assign each a post_at spread over the day and keep a counter of how many you have scheduled per window.

Respect the Tier 3 rate limit too, and retry a rate-limited call after the wait Slack asks for.

What can go wrong?

Cancel a post if the render is later found wrong. Keep the scheduled message id with the Sume run id so one lookup finds both. Do not rerun the Sume call to fix it; reading a finished run again is a plain GET, while a new Format run is a new paid run.

Dedupe on the run webhook's request_id, since a delivery can repeat. Otherwise the same render is scheduled twice, and the channel sees two announcements.

Keep the scheduling step idempotent in your own store. Save a row keyed by run id before you call Slack, and skip the call when the row already has a scheduled message id. A crash between the Slack call and the write can still duplicate a message so reconcile against the channel when in doubt.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume