How to test a webhook URL before a Sume Format run uses it
POST /v1/webhooks/test-deliveries sends a signed webhook.test event to your URL. See the scope, the response fields, and the secret check, with no paid run.

Call POST /v1/webhooks/test-deliveries with the URL you plan to put on communication.webhook_url. Sume sends one signed dummy webhook.test event to it and returns the status code your server answered, any error, and a fingerprint of the signing secret it used. It needs a key with account:write, and it never starts a job or a Format run, so a test costs nothing in generation.
Do this before the first real run, and again whenever a receiver moves, because a wrong URL or secret otherwise shows up hours later as a webhook that never arrived. It is especially worth doing for unattended setups, such as a scheduled agent whose prompt carries the URL, where nobody is watching the first delivery.
What does the call send and return?
The request body has one field, webhook_url. Sume's docs say localhost, private-network and non-HTTPS URLs are rejected, so a laptop receiver needs a public HTTPS tunnel. The response describes the attempt, not a job.
| Item | Value |
|---|---|
| Endpoint | POST /v1/webhooks/test-deliveries |
| Scope | account:write |
| Body | webhook_url, a public HTTPS URL |
| Event sent | webhook.test with a request_id starting req_wh_test_ |
| Payload | ok: true and a message saying it is not a job or Format run |
| Response fields | status_code, delivered_at, error, signature_version, signing_secret_fingerprint |
| Recorded as a request | No; the dummy body has no job id or run id |
What is the call?
The script fails loudly when the receiver does not answer with a 2xx, so you can use it as a deploy check.
import os, sys, requests
r = requests.post(
"https://api.sume.com/v1/webhooks/test-deliveries",
json={"webhook_url": sys.argv[1]},
headers={"Authorization": "Bearer " + os.environ["SUME_API_KEY"]},
timeout=30,
)
r.raise_for_status()
d = r.json()["data"]
print("status:", d["status_code"], "error:", d["error"])
print("secret fingerprint:", d["signing_secret_fingerprint"])
sys.exit(0 if d["status_code"] and 200 <= d["status_code"] < 300 else 1)What should I check in the result?
Three things, in this order.
- A 2xx
status_codemeans the URL is reachable and your server answered inside Sume's reply window. A null status with anerrormeans Sume could not connect. - Compare
signing_secret_fingerprintwith the secret your receiver has loaded. The same fingerprint travels in thex-sume-webhook-secret-fingerprintheader on webhook deliveries, so a receiver can log which secret verified the call. Reading the secret itself withGET /v1/webhooks/signing-secretneedsaccount:read. - Confirm the receiver verified the signature and did not skip it. A receiver that returns 200 without checking
x-sume-webhook-signaturepasses this test and fails in production, so also send a request with a bad signature yourself and expect a 401.
How should the receiver treat webhook.test?
Branch on the event name before any database write. Real Format deliveries are format.run.terminal, and they carry a run id you use as the dedupe key. A webhook.test has no run id, so answer 200 and stop; if your handler tries to insert a row keyed by a missing id, the test fails for the wrong reason.
Keep this separate from redelivery. A test sends a dummy payload to any URL you name. Replaying a real finished run uses POST /v1/format-runs/{run_id}/webhook/redeliver, which only works for a terminal run that had a webhook registered, and it sends the real event with a fresh timestamp and signature.
Does a passing test guarantee delivery?
No. It proves the URL, the secret and a fast 2xx at one moment. Real deliveries are retried up to ten times with backoff when your server is slow or down, deliver only on completed or failed terminal states, and never on cancel or skip. A run that you cancel or that is skipped by on_active_run produces no webhook at all, so keep the receipt URL as a fallback for those.
Sources
Related posts
- Free webhook tester: see what a webhook sends before coding
- GET /v1/webhooks/signing-secret returns 403: key needs account:read
- Format run webhook redeliver 409: not configured or not terminal
- Python Sume webhook handler: stdlib verify and SQLite dedupe
- Hermes Agent cron job that starts a Sume Format run
More in Developers
- TikTok 23-60 fps and 360-4096 px: Sume Timeline and Trim conform
TikTok accepts 23 to 60 fps and 360 to 4096 pixels per side. Sume Timeline fps is 24, 25, 30 or 60 and size is 256-2160; Trim conform needs exact mode.
- TikTok 4 GB file cap: the average bitrate for 10, 30 and 60 minutes
4 GB over 3,600 seconds leaves about 8.9 Mbps on average. Here is the arithmetic for 10, 30 and 60 minutes and what to check on a Sume render before upload.
- TikTok 60-minute videos: API cap is 10 minutes, Sume renders 30
TikTok's developer docs list 10 minutes for API posts; Sume Timeline renders up to 1,800 seconds per job at $0.10 per minute. Plan a long cut around both.
- TikTok chunked upload: how many 5-64 MB parts for a 30-minute render
TikTok accepts 1 to 1,000 sequential chunks of 5 to 64 MB. A 1.8 GB file is 28 or 29 chunks at 64 MB. Sizing a Sume render for chunked upload, with a script.
Written by Sume