Rust reqwest: POST /v1/images on Sume and branch on 200 or 202

Call Sume's image API from Rust with reqwest::blocking and serde_json; one 40-second client timeout and a match on 200, 202 and errors.

4 min readSume
All posts

The blocking client is the shortest path for a CLI tool; use the async client inside a larger service.

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

Rust code

Add reqwest = { version = "0.12", features = ["blocking", "json"] } and serde_json = "1" to Cargo.toml, then SUME_API_KEY=... cargo run.

use serde_json::{json, Value};
use std::{env, time::Duration};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let key = env::var("SUME_API_KEY")?;
    let client = reqwest::blocking::Client::builder()
        .timeout(Duration::from_secs(40))
        .build()?;
    let res = client
        .post("https://api.sume.com/v1/images")
        .bearer_auth(key)
        .json(&json!({
            "model": "bytedance-seed/seedream-5-lite",
            "prompt": "matte ceramic mug on a white sweep, soft shadow",
            "aspect_ratio": "16:9"
        }))
        .send()?;
    let status = res.status().as_u16();
    let text = res.text()?;
    match status {
        200 => {
            let v: Value = serde_json::from_str(&text)?;
            println!("done: {}", v["data"][0]["url"]);
        }
        202 => println!("queued, follow status_url: {text}"),
        _ => println!("error {status}: {text}"),
    }
    Ok(())
}

Notes

The response is read as text first, so an error body that is not an image result never fails JSON parsing.

env::var("SUME_API_KEY")? fails fast when the key is missing instead of sending an unauthenticated request.

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