R httr2: submit an AI video job, poll it, and save the MP4 (Wan 3.0)
An R script posts a Wan 3.0 job to Sume with httr2, loops on /v1/jobs/{id}/status using next_poll_after_seconds and writes the finished clip to disk.

In R, httr2 is enough to generate a clip: build a request with request(), add the bearer token with req_auth_bearer_token(), send JSON with req_body_json(), and read the result with resp_body_json(). Sume answers the submit with 202 and a job id, and you read GET /v1/jobs/{id}/status until terminal is true (Sume jobs guide, read 2026-10-06). The finished file comes from GET /v1/videos/{id}/content?index=0, which needs the same key.
The script requests wan-3.0, 5 seconds, 720p. At $0.125 per second that is $0.625, reserved at submit.
What is the whole script?
Set SUME_API_KEY in the environment, for example in .Renviron. The loop stops after 120 reads.
library(httr2)
key <- Sys.getenv("SUME_API_KEY")
base <- "https://api.sume.com"
stopifnot(nzchar(key))
submit <- request(paste0(base, "/v1/videos")) |>
req_auth_bearer_token(key) |>
req_headers(`Idempotency-Key` = "r-demo-wan-001") |>
req_body_json(list(model = "wan-3.0", prompt = "A paper boat on a rain puddle",
duration = 5, resolution = "720p")) |>
req_perform() |> resp_body_json()
id <- submit$id
for (i in 1:120) {
Sys.sleep(15)
s <- request(paste0(base, "/v1/jobs/", id, "/status")) |>
req_auth_bearer_token(key) |> req_perform() |> resp_body_json()
if (isTRUE(s$terminal)) break
if (!is.null(s$next_poll_after_seconds)) Sys.sleep(max(0, s$next_poll_after_seconds - 15))
}
stopifnot(s$sume_status == "completed")
request(paste0(base, "/v1/videos/", id, "/content?index=0")) |>
req_auth_bearer_token(key) |> req_perform(path = "clip.mp4")What do the other resolutions cost?
| Resolution | Per second | 5-second clip |
|---|---|---|
| 480p | $0.0625 | $0.3125 |
| 720p | $0.125 | $0.625 |
| 1080p | $0.25 | $1.25 |
Does re-running the poller bill a second clip?
No, as long as it only reads. Keep the paid POST /v1/videos in a separate step with an Idempotency-Key you own. A client-side give-up never cancels the render, so store the job id and read it again later instead of submitting a second time (Sume jobs guide, read 2026-10-06).
Sources
Related posts
More in Developers
- Rails Sidekiq job that polls an AI video API with perform_in
A Sidekiq worker reads Sume's /v1/jobs/{id}/status once, then reschedules itself with perform_in using next_poll_after_seconds until the job is terminal.
- Rails Active Job that polls an AI video API: retry_job and wait
An Active Job on Solid Queue reads Sume's job status once and calls retry_job with wait from next_poll_after_seconds until the video job is terminal.
- Read Sume TTS raw PCM in Python: f32le samples at 24 kHz
Ask the TTS Router for container raw, 24000 Hz and pcm_f32le, then load the samples with the standard library for DSP or a custom player.
- Record the Idempotency-Key before you POST a Sume video job
A worker that dies after submitting a video job loses the job id. Write the key to a ledger first, then POST; a retry returns the same job. Tested SQLite code.
Written by Sume