Unity editor tool: generate an AI video clip with UnityWebRequest

A Unity coroutine posts a Wan 3.0 job to Sume, polls /v1/jobs/{id}/status with next_poll_after_seconds and downloads the MP4 with DownloadHandlerFile.

5 min readSume
All posts

In Unity, generate a placeholder cutscene clip from an editor script or a build-pipeline tool with a coroutine: UnityWebRequest.Post to https://api.sume.com/v1/videos, then UnityWebRequest.Get on /v1/jobs/{id}/status every few seconds, then a download with DownloadHandlerFile. Sume answers the submit with 202 and a job id; the status response says when to read again through next_poll_after_seconds (Sume jobs guide, read 2026-10-06).

Keep the API key out of anything you ship. A key inside a player build can be extracted, so this belongs in editor tooling or on your own server. The clip is wan-3.0, 5 seconds, 720p, $0.625 at Sume's $0.125 per second.

What does the MonoBehaviour look like?

JsonUtility needs serializable classes, so the two small ones below mirror the fields we read. An absent next_poll_after_seconds parses as 0, which the code replaces with 15. Needs Unity 2022.2 or newer for the string-body Post overload.

using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

[System.Serializable] class Job { public string id; }
[System.Serializable] class St { public bool terminal; public string sume_status; public int next_poll_after_seconds; }

public class SumeClip : MonoBehaviour {
  const string Api = "https://api.sume.com";
  void Auth(UnityWebRequest r) =>
    r.SetRequestHeader("Authorization", "Bearer " + System.Environment.GetEnvironmentVariable("SUME_API_KEY"));

  IEnumerator Start() {
    string json = "{\"model\":\"wan-3.0\",\"prompt\":\"Fog over a pixel-art harbor\",\"duration\":5,\"resolution\":\"720p\"}";
    using var post = UnityWebRequest.Post(Api + "/v1/videos", json, "application/json");
    Auth(post); post.SetRequestHeader("Idempotency-Key", "unity-harbor-001");
    yield return post.SendWebRequest();
    if (post.result != UnityWebRequest.Result.Success) { Debug.LogError(post.downloadHandler.text); yield break; }
    string id = JsonUtility.FromJson<Job>(post.downloadHandler.text).id;
    for (int i = 0; i < 120; i++) {
      yield return new WaitForSeconds(15);
      using var get = UnityWebRequest.Get(Api + "/v1/jobs/" + id + "/status");
      Auth(get); yield return get.SendWebRequest();
      var s = JsonUtility.FromJson<St>(get.downloadHandler.text);
      if (!s.terminal) continue;
      if (s.sume_status != "completed") { Debug.LogError(s.sume_status); yield break; }
      using var dl = UnityWebRequest.Get(Api + "/v1/videos/" + id + "/content?index=0");
      Auth(dl); dl.downloadHandler = new DownloadHandlerFile(Application.dataPath + "/clip.mp4");
      yield return dl.SendWebRequest(); yield break;
    }
  }
}

Does the clip play in the editor right away?

Unity's VideoPlayer takes a file path or URL, so point it at the saved clip.mp4 after the download finishes. The content endpoint needs the Authorization header, which is why the download goes through UnityWebRequest instead of giving a bare URL to the player. Check your target platform's supported codecs before you plan on playing it in a build.

Does re-running the script bill a second clip?

It can if you re-run the submit step. Send a stable Idempotency-Key on POST /v1/videos (here a fixed string; in practice a row id) so a repeat returns the original job. A give-up on the client never cancels the render, so keep the job id and read it again (Sume jobs guide, read 2026-10-06).

Sources

Related posts

More in Developers

All Developers posts

Written by Sume