Go: poll a Sume job with a context deadline, next_poll_after_seconds
A Go net/http poller for Sume jobs: 20-minute context deadline, sleeps set by next_poll_after_seconds, stops on data.terminal. Standard library only.

Let the server set the pace
The Sume status envelope tells a poller what to do next. Under data it carries status, terminal, result_ready and next_poll_after_seconds, which is null once the job is terminal. A loop that sleeps for that many seconds, and stops the moment terminal is true, is both polite to your read budget and short.
Add a hard deadline with a context so a stuck job cannot hold a goroutine forever. Twenty minutes is a reasonable ceiling for a video job; pick your own.
The program
Run it with SUME_API_KEY and a job id as the first argument: go run poll.go JOB_ID. It uses only the standard library and falls back to a 5-second sleep if the field is missing.
package main
import (
"context"; "encoding/json"; "fmt"; "net/http"; "os"; "time"
)
type env struct{ Data struct {
Status string `json:"status"`
Terminal bool `json:"terminal"`
Next *float64 `json:"next_poll_after_seconds"`
} `json:"data"` }
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Minute)
defer cancel()
url := "https://api.sume.com/v1/jobs/" + os.Args[1] + "/status"
for {
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SUME_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil { fmt.Println("stopped:", err); return }
var e env
json.NewDecoder(res.Body).Decode(&e); res.Body.Close()
fmt.Println(e.Data.Status)
if e.Data.Terminal { return }
wait := 5.0
if e.Data.Next != nil { wait = *e.Data.Next }
time.Sleep(time.Duration(wait * float64(time.Second)))
}
}What it leaves out on purpose
- Retries for 429 and 5xx: add them with the retry-after header if the poller is long-lived.
- The result fetch: when status is completed, call GET /v1/jobs/{id}/result, which returns 409 job_not_completed before then.
- Cancel on timeout: a context deadline stops your wait, not the job. Cancel with POST /v1/jobs/{id}/cancel only before generation has started; later it returns 409 job_generation_already_started.
Sources
Related posts
More in Developers
- gpt-image-1 cutover calendar: 18 days to Oct 23, 57 to Dec 1
A dated plan for the gpt-image-1 shutdown on 2026-10-23: inventory, canary, cut over and cleanup, with the Dec 1 ids on the same Sume migration.
- GPT Image 2.5 1536x1024 preset vs custom sizes on Sume
1536x1024 is an OpenAI preset and passes Sume's custom-size rules too: edges multiples of 16, max edge 3840, ratio up to 3:1, 655,360-8,294,400 pixels.
- Porting to Sume images: 400 unsupported_parameter checklist
Porting an image client to Sume: seed, stream, output_compression and size WxH return 400, and background works only on GPT Image 2.5. A fix for each.
- GPT Image 2.5 cost calculator in Python: token grid, checked vs Sume
A short Python function reproduces Sume's GPT Image 2.5 prices from the token grid, $0.0074 at low and $0.2635 at max for 1024x1024. Table to check it.
Written by Sume