MiniMax video callback_url: echo the challenge in 3 seconds
MiniMax checks a callback_url by POSTing a challenge you must echo within 3 seconds. Sume skips the handshake and signs each terminal webhook instead.

MiniMax validates a callback_url by POSTing a body with a challenge field, and your server must echo it back within 3 seconds; after that, status updates arrive as the task moves through processing, success or failed (read 2026-10-02). Sume's callback_url on /v1/videos has no handshake. It sends one signed POST when the job reaches a terminal state, and you verify the signature.
How do the two callbacks compare?
MiniMax documents the callback on its text-to-video reference and still recommends polling in its guide, which names a 10 second interval. Sume's webhook rules come from its webhooks guide and its video generation page.
| Question | MiniMax | Sume |
|---|---|---|
| Setup check | POST with a challenge, echo within 3 s | None; the URL must be public HTTPS |
| Events | processing, success, failed | Terminal only: job.completed, job.failed, job.canceled |
| Authenticity | Not described on the pages I read | HMAC SHA 256 over timestamp.body in x-sume-webhook-signature |
| Retries | Not described | Up to 10 attempts, 30 s apart, 10 s timeout |
How do you verify a Sume webhook?
Sume signs <timestamp>.<raw_body> with your workspace signing secret and sends sume-v1=<hex> in x-sume-webhook-signature. During a secret rotation the header holds one entry per live secret, so accept any match. Reject old timestamps; five minutes is the documented default. The sketch below refuses an empty secret, which would otherwise make every signature forgeable:
import hashlib, hmac, time
def verify(raw_body: bytes, timestamp: str, header: str, secret: str, tolerance: int = 300) -> bool:
if not secret:
return False
try:
ts = int(timestamp)
except ValueError:
return False
if abs(time.time() - ts) > tolerance:
return False
msg = f"{ts}.".encode() + raw_body
expected = "sume-v1=" + hmac.new(secret.encode(), msg, hashlib.sha256).hexdigest()
ok = False
for entry in header.split(","):
if hmac.compare_digest(entry.strip().encode(), expected.encode()):
ok = True
return ok
if __name__ == "__main__":
body, now = b'{"event":"job.completed"}', str(int(time.time()))
sig = "sume-v1=" + hmac.new(b"s3cret", f"{now}.".encode() + body, hashlib.sha256).hexdigest()
print(verify(body, now, sig, "s3cret"), verify(body, now, sig, ""))What about polling?
Keep polling as a fallback on both sides. Sume's docs say delivery is an optimization, never the only recovery path: a job can reach its terminal state while your endpoint was down, and status_url still has the answer. Use job_id as your idempotency key, because a redelivery sends the same event again.
MiniMax's tasks are queryable for the last 7 days according to its guide (read 2026-10-02), so a missed callback there has a deadline. Sume's polling and webhook behavior do not state a comparable expiry on the pages used here, so store the result URL when you first see it.
Which handshake mistakes are common?
- Answering MiniMax's challenge after parsing slow business logic: respond first, work later.
- Verifying a Sume signature against re-serialized JSON: use the raw body bytes.
- Treating a webhook as proof of payment or output: fetch the job result before you publish.
- Returning 200 before storing the event: Sume retries only on errors and non-2xx.
Sources
Related posts
More in Models
- MiniMax video tasks are queryable for 7 days: poll every 10 s
MiniMax says video tasks can be queried for the last 7 days and suggests polling every 10 seconds. What that means for your pipeline, and Sume's 30 s example.
- Where are the lyrics in a Lyria 3.5 result? Gemini vs Sume
Google returns Lyria 3.5 lyrics and song structure as text beside the audio. Sume puts model-reported lyrics or a section map in result.lyrics when present.
- Nano Banana 2 Lite model id: Vertex hyphens vs Gemini API dots
Google's Gemini API names Nano Banana 2 Lite gemini-3.1-flash-lite-image; its Cloud post writes gemini-3-1-flash-lite-image. Sume's image catalog lists neither.
- Nano Banana negative prompt: describe what you want instead
Google's Gemini image guide says to write semantic negative prompts: describe an empty street, not 'no cars'. Sume's image request has no negative field.
Written by Sume