JDK 27 HttpClient: poll a Sume job in one Java file
JDK 27 reached GA on 15 September 2026. A single-file java.net.http loop for GET /v1/jobs/:id/status with timeouts and next_poll_after_seconds.

Short answer
With JDK 27 you can run a Sume poll loop as one source file: java Poll.java job_123. Build one HttpClient, set a connect timeout and a per-request timeout, read terminal and next_poll_after_seconds off the status body, and sleep that long. The JDK 27 project page records General Availability on 15 September 2026.
There is no Sume-published Java SDK, so the loop below uses only the JDK. The contract it follows is on Sume's jobs and results page: async returns a job id, GET /v1/jobs/:id/status says when to look again, and terminal says when to stop.
What JDK 27 lists, and what it does not change here
None of the JDK 27 items below alter java.net.http. They are context for running the loop on JDK 27, and because Structured Concurrency is listed as a seventh preview, this post avoids it.
| JEP | Title |
|---|---|
| 523 | Make G1 the Default Garbage Collector in All Environments |
| 534 | Compact Object Headers by Default |
| 527 | Post-Quantum Hybrid Key Exchange for TLS 1.3 |
| 533 | Structured Concurrency |
The loop
Two timeouts are set on purpose. A HttpClient has no overall request deadline unless you give one, so a stalled connection would otherwise hold the poller forever. The regex reads two fields from the JSON so the file needs no dependency; swap in Jackson if you already have it.
import java.net.URI;
import java.net.http.*;
import java.time.Duration;
import java.util.regex.*;
public class Poll {
public static void main(String[] a) throws Exception {
var http = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
var req = HttpRequest.newBuilder(URI.create("https://api.sume.com/v1/jobs/" + a[0] + "/status"))
.timeout(Duration.ofSeconds(20))
.header("Authorization", "Bearer " + System.getenv("SUME_API_KEY")).build();
var done = Pattern.compile("\"terminal\"\\s*:\\s*true");
var next = Pattern.compile("\"next_poll_after_seconds\"\\s*:\\s*([0-9.]+)");
while (true) {
var res = http.send(req, HttpResponse.BodyHandlers.ofString());
if (res.statusCode() != 200) throw new IllegalStateException(res.statusCode() + " " + res.body());
if (done.matcher(res.body()).find()) { System.out.println(res.body()); return; }
var m = next.matcher(res.body());
Thread.sleep(m.find() ? (long) (Double.parseDouble(m.group(1)) * 1000) : 2000);
}
}
}Reading the result
When sume_status is completed, call GET /v1/jobs/:id/result. Completed jobs carry result.artifacts, each with an id, type, url and content_type; the URLs are Sume media URLs, and raw provider URLs are never public outputs.
If the status is failed or canceled, do not call the result route. It answers 409 job_not_completed for anything that is not completed, so read the failure from GET /v1/jobs/:id instead.
What Sume does and does not do
Sume keeps the job alive when your JVM exits and lets you pick the id back up from any process that holds it. It does not extend sync mode past 30 seconds, and subscribe mode is an alias of sync, so a Java service that waits on the submit call will see a 2xx envelope that is not terminal and must fall back to this loop.
Polling spends the read budget, 40 times the write budget on every plan, and the ratelimit-remaining header tells you what is left. Back off on retry-after if a 429 ever appears.
Sources
Related posts
More in Developers
- JDK 27 Java webhook verifier for Sume (HmacSHA256)
Verify a Sume sume-v1 webhook with javax.crypto and MessageDigest.isEqual on JDK 27: raw body bytes, five-minute window, empty secret refused.
- Sume webhook retry window: 4.5 minutes for jobs, 3 hours for runs
Job webhooks retry 10 times at a fixed 30 s, about 4.5 minutes. Run webhooks back off for about 3 hours. How long a deploy can take your receiver down.
- GET /v1/jobs thread_id filter: why a teammate's job still 404s
The thread_id filter on the Sume jobs list narrows results and never widens what an API key can read. Teammates' jobs stay 404, and only the creator can cancel.
- jobs_result batch: read a wave when some jobs are still running
Sume's batch jobs_result returns one entry per id in request order. Read ok per entry, treat job_not_completed as running, and re-read only failed_job_ids.
Written by Sume