Java HttpClient: POST /v1/images on Sume with a 40-second timeout

A single-file Java program that calls Sume's image API with java.net.http, branches on 200, 202 and errors, and sets a timeout longer than the 30-second wait.

4 min readSume
All posts

Java's built-in HTTP client is a good fit for a one-off image call: no dependencies, one file.

The request is the same in every language: POST https://api.sume.com/v1/images with a bearer key from SUME_API_KEY, a JSON body with model, prompt and aspect_ratio, and a client timeout above the route's 30-second wait. The route defaults to mode: "sync", so the status code decides what you do next (docs read 2026-10-07):

Status codes to branch on

Sume POST /v1/images, read 2026-10-07.
StatusMeaningWhat the code below does
200Image finished inside the wait; data[].url holds the filePrints the result
202Wait expired (or mode is async or webhook); body is a job envelope with status_url and result_urlPrints the envelope; poll status_url and read result_url
502The job failed inside the wait; error has code, retryable, next_actionPrints the error
400, 404unsupported_parameter, or model_not_foundPrints the error

Java code

Save as Gen.java, then run SUME_API_KEY=... java Gen.java on JDK 17 or newer (the arrow switch needs 14+, single-file launch needs 11+).

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class Gen {
  public static void main(String[] args) throws Exception {
    String key = System.getenv("SUME_API_KEY");
    if (key == null || key.isEmpty()) throw new IllegalStateException("SUME_API_KEY missing");
    String body = "{\"model\":\"bytedance-seed/seedream-5-lite\","
        + "\"prompt\":\"matte ceramic mug on a white sweep, soft shadow\","
        + "\"aspect_ratio\":\"16:9\"}";
    HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.sume.com/v1/images"))
        .timeout(Duration.ofSeconds(40))
        .header("Authorization", "Bearer " + key)
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(body))
        .build();
    HttpResponse<String> r = HttpClient.newHttpClient()
        .send(req, HttpResponse.BodyHandlers.ofString());
    switch (r.statusCode()) {
      case 200 -> System.out.println("done: " + r.body());
      case 202 -> System.out.println("queued, follow status_url: " + r.body());
      default -> System.out.println("error " + r.statusCode() + ": " + r.body());
    }
  }
}

Notes

HttpClient has no request timeout unless you set one on the HttpRequest. Forty seconds leaves room above Sume's 30-second sync wait, so you see the 202 instead of your own timeout.

The body is built by string concatenation to stay dependency-free. For anything dynamic, build it with a JSON library so quotes in the prompt are escaped.

One bytedance-seed/seedream-5-lite image is $0.04375 billed (list $0.035 x 1.25). Prices here are Sume's list-times-1.25 figures. The catalog states the billable formula as "list × 1.25 → ceil usd cents", so treat the dollar amounts as the pre-rounding value and read the exact charge from billable_amount_usd_micros in the submit envelope. Failed or cancelled generations are not billed.

Sources: Sume Image API docs and Jobs and results (read 2026-10-07).

Sources

Related posts

More in Developers

All Developers posts

Written by Sume