Midjourney edit history: keep an edit lineage with Sume job metadata

Midjourney added edit-history navigation and plans persistent edit history. For the Sume image API, build your own lineage with metadata and the jobs list.

4 min readSume
All posts

Midjourney's editor now supports arrow-key navigation through edit history (9/23/26) and the team lists persistent edit history among upcoming features (10/1/26). The Sume image API does not hold an edit tree for you. It gives you the pieces to build one: a metadata object stored on each job, durable job ids, and a jobs list. This post shows a small lineage log.

What Midjourney says

From Midjourney's changelogs.

Midjourney edit history facts, read 2026-10-02
DateFact
9/23/26Arrow-key navigation through edit history, with support for v8.1 and v8.2 edit types.
10/1/26Persistent edit history listed under upcoming features.

Pieces Sume gives you

Every image generation creates a durable job; store its id. The jobs docs say to keep the job id so work survives process restarts. metadata on the request is stored on the job and is not sent to the provider, so it can hold parent_job_id and step.

GET /v1/jobs lists jobs and takes limit, status, type, thread_id, run_id and starting_after. An API key reads only the jobs its own member created in the key's workspace.

A lineage log

Write one line per edit to a JSONL file you own. The job id is the node, parent is the previous node, and prompt is the instruction. Undo is then "re-read an older node's result", and branching is two lines with the same parent.

import json, os, requests

H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}

def edit(parent_url, parent_id, prompt, log="lineage.jsonl"):
    r = requests.post("https://api.sume.com/v1/images", headers=H, timeout=60, json={
        "model": "openai/gpt-image-2.5",
        "prompt": prompt,
        "aspect_ratio": "auto",
        "mode": "async",
        "input_references": [{"type": "image_url", "image_url": {"url": parent_url}}],
        "metadata": {"parent_job_id": parent_id},
    })
    job = r.json()["data"]["job"]["id"]
    with open(log, "a") as f:
        f.write(json.dumps({"job": job, "parent": parent_id, "prompt": prompt}) + "\n")
    return job

Reading it back

Poll GET /v1/jobs/{id}/status, then fetch GET /v1/jobs/{id}/result once the job is complete; the result endpoint answers 409 job_not_completed before that. Store the Sume media URL from the result, not any provider URL.

Limits

Be honest about the gap:

  • There is no server-side tree: the log is yours to back up.
  • Visibility is per member, so a teammate's key cannot read your jobs; share results through your own store.
  • Result URLs are Sume-hosted; keep your own copy if you need long-lived archives.

Using the log

With the JSONL file in place, three useful things become one-liners. To undo, read the parent id of the current node and fetch its result. To branch, call the edit function again with the same parent. To audit, group lines by prompt and count how many passes a final image took.

Keep the log small: job id, parent id, prompt and timestamp are enough. The images themselves stay on Sume's hosted URLs, and you can copy the ones you want to keep into your own storage. Back up the log with the rest of your project files, because it is the only record of how the tree fits together.

If several people share one workflow, give each person their own key and each key its own log, then merge logs offline. Jobs are scoped to the member who created them, so one person's key cannot list another's work.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume