Discord interaction token lasts 15 minutes: deliver a long Sume run

A Discord follow-up works for 15 minutes; a long-form Format run takes 15 to 30. Edit the original reply when young, post as the bot to the channel when not.

4 min readSume
All posts

A Discord slash command can defer its reply, but the interaction token it receives is valid for only 15 minutes, while a long-form Sume Format run is documented as 15 to 30 minutes of work. So deliver the result by editing the original reply only while the token is young, and fall back to posting a message into the channel with the bot token once it is not.

Store three things when the command arrives: the application id, the interaction token and the channel id, plus the time you received it. Your Sume run webhook handler needs all of them to choose a delivery path.

The two clocks

Discord's interactions page gives the shape: you must acknowledge within 3 seconds, a deferred response (type 5) shows the loading state, and the follow-up endpoints under /webhooks/{application_id}/{interaction_token} accept calls for 15 minutes. Editing the first reply is PATCH /webhooks/{application_id}/{interaction_token}/messages/@original.

Sume's side is on the Format runs page: a run moves through queued and processing to a terminal state, long-form video is 15 to 30 minutes of work, and a run expires 90 minutes after creation. A format.run.terminal webhook tells you when it ended. The two windows overlap only partly, so a short run can use the interaction token and a long one cannot rely on it.

Delivery paths for a finished run (read 2026-10-03)
PathEndpointAuthValid for
Edit the deferred replyPATCH /webhooks/{app_id}/{token}/messages/@originalToken in the URL15 minutes after the command
Follow-up messagePOST /webhooks/{app_id}/{token}Token in the URL15 minutes after the command
Channel messagePOST /channels/{channel_id}/messagesAuthorization: Bot token, SEND_MESSAGES permissionAs long as the bot stays in the channel

Choosing the path

The function below takes the moment the command arrived and picks a path with a one-minute margin. A message body is limited to 2000 characters, so it sends only the result link, which also avoids Discord's upload size limit; see Discord file size limits for why a link is safer for video.

import os, time, requests

API = "https://discord.com/api/v10"

def deliver(app_id, token, channel_id, received_at, url):
    body = {"content": f"Your video is ready: {url}"}
    if time.time() - received_at < 14 * 60:
        r = requests.patch(f"{API}/webhooks/{app_id}/{token}/messages/@original",
                           json=body, timeout=10)
    else:
        bot = os.environ["DISCORD_BOT_TOKEN"]
        r = requests.post(f"{API}/channels/{channel_id}/messages", json=body,
                          headers={"Authorization": f"Bot {bot}"}, timeout=10)
    r.raise_for_status()
    return r.status_code

Failure handling

Run the function from the Sume webhook handler after you have verified the signature and stored the event. If Discord answers with an error, raise so your handler returns a non-2xx and Sume redelivers; dedupe on the run id so a repeated delivery edits the same message instead of posting a second one. For a run that fails, send the same two paths a short failure notice instead of a link.

If the bot is not in the channel, the fallback path returns a permissions error. Check that during command registration, not after a 25-minute run.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume