Cursor self-hosted machines can't take Sume webhooks on a private URL
Sume rejects localhost, private-network and non-HTTPS webhook URLs. An agent on a self-hosted machine should poll status_url or use a public HTTPS receiver.

An agent running on a self-hosted machine usually cannot receive a Sume webhook directly, because the webhook_url must be a public HTTPS URL. Localhost, private-network and non-HTTPS URLs are rejected, so the machine should poll status_url, or a public receiver should sit in front of it.
Cursor Self-hosted Machines (Sep 2, 2026) offers My Machines and Team pools, and works with AWS Lambda, Vercel, Coder and Cloudflare.
What Sume accepts
Run webhooks apply the same validation, with a 2048-character limit, and re-check the URL at delivery time, not only at submit.
| URL | Result |
|---|---|
| Public HTTPS | Accepted. |
| http:// | Rejected. |
| localhost or a private-network address | Rejected. |
| A URL that redirects (3xx) | Not a delivery; redirects are not followed. |
Option one: poll from the machine
A machine that can reach the internet outbound does not need an inbound endpoint. Submit with mode: async, keep the job id, and poll GET /v1/jobs/{id}/status until terminal is true, honoring next_poll_after_seconds. Then fetch the result when result_ready is true.
The wait lives in your client, so its timeout can run to minutes without holding an HTTP request open. For a video, around 20 minutes is the docs' suggested client deadline.
Option two: a small public receiver
If you want to be told rather than ask, put a public HTTPS receiver somewhere that is reachable, and hand off from it. The Sume signature scheme is the same for job and run webhooks, so one verifier serves both.
- Verify the HMAC over
<timestamp>.<raw_body>and thesume-v1=header. - Store the event, answer 2xx within 10 seconds, and key on
job_id. - Let the self-hosted agent read the stored result on its next step.
- Keep status polling as a backup, because Sume tries a delivery up to 10 times and then stops.
Which events you will get
Job webhooks are terminal-only: job.completed, job.failed and job.canceled. There are no progress or partial events. A Format, Action or Agent Completion run sends a single *.run.terminal event per run instead, whatever number of clips it made.
If you need progress inside a long job, read GET /v1/jobs/:id/events, which is a pull snapshot rather than a stream.
Where the key lives
Whichever option you choose, the API key belongs in the machine's secret store, not in the repository. The signing secret is separate: read it from the dashboard Webhooks tab or GET /v1/webhooks/signing-secret, and store it as SUME_COM_WEBHOOK_SIGNING_SECRET for the receiver.
Sources
Related posts
More in Developers
- Demand Gen copy limits: 40-character headlines, one at 30 or fewer
Demand Gen allows 40-character headlines (one must be 30 or fewer), 90-character descriptions and 10-60 second videos. A checker script plus the Sume lengths.
- Design a render tool for a stateless MCP server: job ids as arguments
MCP 2026-07-28 removes protocol sessions. A render tool stays correct if its state lives in a job id the client passes back, as Sume jobs do.
- Claude rejects forced tool_choice: steer generate_video by description
Claude Sonnet 5.5 and Opus 5.5 return a 400 for tool_choice any or tool, and thinking cannot be disabled. Steer Sume tool calls with descriptions and a dry run.
- Draft with GPT Image 2.5 Flare, finish with Sunburst: a two-pass edit
OpenAI pairs Flare with fast generation and Sunburst with editing precision. A Python two-pass on Sume's Image API that drafts, then refines the first result.
Written by Sume