PowerShell 7: submit, poll and save a Sume video, no SDK
A Windows-friendly script for POST /v1/videos: Idempotency-Key, a 30-second poll on polling_url, and a download from unsigned_urls[0]. Fits in 14 lines.

Use Invoke-RestMethod to POST the job to https://api.sume.com/v1/videos, read polling_url from the 202 response, poll it until status leaves pending and in_progress, and download unsigned_urls[0] with the same Authorization header. The response is a bare object, so $job.polling_url works without any .data step.
The script
The script below uses wan-3.0 at 720p, 9:16, five seconds. Set $env:SUME_API_KEY first. One Idempotency-Key is created once per script run, so a re-run of the submit line (for example after a network error) returns the original job instead of a second paid one. A new run of the script gets a new key and a new job.
$h = @{ Authorization = "Bearer $env:SUME_API_KEY" }
$key = [guid]::NewGuid().ToString()
$body = @{
model = "wan-3.0"; prompt = "A paper boat on a rainy street, slow dolly in"
duration = 5; resolution = "720p"; aspect_ratio = "9:16"
} | ConvertTo-Json
$job = Invoke-RestMethod -Method Post -Uri "https://api.sume.com/v1/videos" `
-Headers ($h + @{ "Idempotency-Key" = $key }) `
-ContentType "application/json" -Body $body
Write-Host "job $($job.id) $($job.status)"
do {
Start-Sleep -Seconds 30
$s = Invoke-RestMethod -Uri $job.polling_url -Headers $h
Write-Host $s.status
} while ($s.status -in "pending", "in_progress")
if ($s.status -ne "completed") { throw "ended as $($s.status): $($s.error)" }
Invoke-WebRequest -Uri $s.unsigned_urls[0] -Headers $h -OutFile clip.mp4What the fields mean
Statuses on this surface are pending, in_progress, completed, failed and cancelled. The loop above exits on any of the last three. A failed job puts one string in error, and cancelled has none, so the throw prints whatever is there.
| Field | Used for |
|---|---|
| id | the job id; also readable at GET /v1/jobs/{id}/status |
| polling_url | the URL to GET in the loop |
| status | loop exit condition |
| unsigned_urls | download links, one per output, on completed jobs |
| error | a single string on failed jobs |
Cost and polling
The docs suggest a moderate polling interval such as 30 seconds, and say video generation usually takes from 30 seconds to several minutes. At that interval a five-minute job costs about ten GET requests.
For this request the price is worked out from the Sume catalog: wan-3.0 at 720p lists at $0.10 per second, Sume bills list x 1.25, so 5 s x $0.10 x 1.25 = $0.625, rounded up to $0.63. The poll shows that amount in usage.cost (see the grid in the Sume video docs).
-ContentTypeis required on the POST: a body that is notapplication/jsonis answered with 415.- Never write the key into the script; read it from the environment as shown.
If it stalls
A job that stays pending for a long time is normally just queued. Keep polling at the same interval. If you would rather not poll, add callback_url (HTTPS) to the body and verify the signed delivery instead; see the reconcile sweeper for keeping a poll as the backup.
Sources
Related posts
More in Developers
- PowerShell 7: verify a Sume webhook with HMACSHA256, constant-time
A PowerShell function that refuses an empty secret, checks the 300-second window and accepts any entry in a rotated sume-v1 header. Under 30 lines.
- PowerShell: Invoke-RestMethod for a 30-second Wan 3.0 clip
Windows PowerShell script that posts a 30-second wan-3.0 job, loops until it completes and saves the MP4 with Invoke-WebRequest. $3.75 at 720p.
- Pre-flight an Omni Flash request against the Sume model catalog
A short Python check that reads supported durations, resolutions and aspect ratios for gemini-omni-flash-1.1 via /v1/videos/models.
- Preflight a 3-minute Short with Timeline plan before you pay
POST /v1/timeline-1.0/plan compiles a Short without a job or a reserve and returns billable minutes and the estimate. A runnable Python check for six slots.
Written by Sume