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
- Transactional outbox for paid API calls in Python (Sume)
Write the Sume request and its Idempotency-Key in the order's transaction, drain later: a tested Python outbox that survives crashes, 429s and 409s.
- Transcribe a three-hour recording when the API caps at ten minutes
Streaming sessions end at an hour; Sume STT jobs take up to 600 seconds. Split with Timeline audio, transcribe 18 chunks, and stitch word times back together.
- Translate an SRT and burn it in: Sume caption cues, limits, Python
Sume takes no SRT upload, but caption cues take the same text and times. A Python converter, the 200-cue and 60-second limits, and which fonts apply.
- Validate video duration and resolution in Python before you submit
Fetch GET /v1/videos/models and check duration, resolution and aspect_ratio per model in about 25 lines of Python, before a Sume video job fails.
Written by Sume