PowerShell Invoke-RestMethod: a Sume video job to replace Sora

Replace a PowerShell script that called the Sora Videos API: submit to Sume /v1/videos with Invoke-RestMethod, poll polling_url, download the mp4.

4 min readSume
All posts

To replace a PowerShell script that called the Sora Videos API, POST the same prompt to https://api.sume.com/v1/videos with Invoke-RestMethod and an Authorization: Bearer header, then poll the returned polling_url until status is completed and save the file from unsigned_urls[0]. The job shape is still submit, poll, download; only the host, the model id and the key change.

A secondary-source guide dates the Sora 2 API shutdown to September 24, 2026 (Higgsfield, read 2026-10-11), so any script that still targets the old route fails and needs a new backend.

What changes in the script?

Most of a Sora script survives. The submit call, the polling loop and the file write stay. Four lines change.

Sora-era script lines and their Sume replacement (Sume docs, read 2026-10-11)
Script lineSora-eraSume
Base URLOpenAI videos routehttps://api.sume.com/v1/videos
Auth headerOpenAI keyAuthorization: Bearer $env:SUME_API_KEY
Modelsora-2 or sora-2-proa catalog id such as gemini-omni-flash-1.1, or sume/auto
Done checkSora status wordsstatus is completed; failed and cancelled are terminal

What does the full script look like?

This runs in PowerShell 7. It refuses to start without a key, sends an Idempotency-Key so a retried submit returns the original job, and stops on failed or cancelled.

$key = $env:SUME_API_KEY
if (-not $key) { throw 'SUME_API_KEY is not set' }
$h = @{ Authorization = "Bearer $key"; 'Idempotency-Key' = [guid]::NewGuid().ToString() }
$body = @{
  model = 'gemini-omni-flash-1.1'
  prompt = 'A paper boat drifting down a rain gutter, macro lens'
  duration = 8
  resolution = '720p'
  aspect_ratio = '16:9'
} | ConvertTo-Json
$job = Invoke-RestMethod -Method Post -Uri 'https://api.sume.com/v1/videos' `
  -Headers $h -ContentType 'application/json' -Body $body
Write-Host "submitted $($job.id)"
do {
  Start-Sleep -Seconds 15
  $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 "job ended as $($s.status)" }
Invoke-WebRequest -Uri $s.unsigned_urls[0] -Headers $h -OutFile out.mp4
Write-Host "saved out.mp4, cost $($s.usage.cost)"

Which values will the API reject?

The catalog controls validation: a duration, resolution or aspect ratio the model does not advertise returns a 400 instead of being dropped. Gemini Omni Flash 1.1 takes 3 to 10 seconds at 360p, 720p, 1080p or 4K in 16:9 or 9:16, so a Sora script that asked for 12 seconds needs a different model or two clips. Do not send seed or size; no v1 model accepts a seed and size returns 400 unsupported_parameter. Read GET /v1/videos/models to see each model's limits before you hard-code them.

Poll or use a callback?

A desktop script can poll every 15 to 30 seconds. A scheduled task that renders many clips is easier to run with callback_url, where Sume POSTs a signed body with x-sume-webhook-timestamp and x-sume-webhook-signature headers when the job reaches a terminal state. The webhook envelope is Sume's job envelope, so do not reuse a handler written for the old Sora events.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume