LangGraph DeltaChannel: keep Sume artifact URLs in state, not video
LangGraph 1.2 DeltaChannel stores only the per-step delta. Even so, keep Sume media out of state: store the artifact URL and job id and fetch bytes when needed.

Put the Sume job id and artifact URLs in your LangGraph state, never the media bytes. DeltaChannel makes large accumulating state cheaper to checkpoint, but a video is still the wrong thing to carry in a message list, and Sume already hands you a URL.
The LangChain Python changelog (read 2026-10-02) describes DeltaChannel, in beta in v1.2.0, as "a new channel type that stores only the incremental delta at each step rather than re-serializing the full accumulated value," with snapshot_frequency=K for periodic full snapshots. It is aimed at channels that grow, like a message list in a long thread.
What does DeltaChannel fix, and what does it not?
It fixes re-serializing the whole accumulated value at every step. A thread whose message list grows over fifty tool calls no longer rewrites the full list into each checkpoint. It does not shrink a single large value: if one step appends a base64 video, that delta is still huge, still stored, and still replayed when the state is rebuilt from deltas and the periodic snapshots.
I did not find, on the page I read, a claim about how DeltaChannel treats individual large values, so treat that as unconfirmed and measure your own checkpoints.
What does Sume give me instead of bytes?
A completed job result and webhook payloads carry artifact objects with an id, a url, a type and a content_type. The Webhooks page shows url values under https://media.sume.com/artifacts/.... Those are the small things to keep in state.
{
"event": "job.completed",
"request_id": "job_...",
"job_id": "job_...",
"status": "OK",
"payload": {
"artifacts": [
{
"id": "artf_...",
"url": "https://media.sume.com/artifacts/...",
"type": "image",
"content_type": "image/png"
}
]
}
}What should the state schema hold?
Keep four small fields per generation: the business key, the Sume job_id, the terminal status, and the list of artifact id and url pairs. Anything downstream that needs the file downloads it from the URL at the moment it needs it.
| Field | Source | Why keep it |
|---|---|---|
| job_id | Submit response request_id | Recover and re-poll after a restart |
| status | status endpoint sume_status | Branch without a second call |
| artifact id and url | Result or webhook payload | Small, stable handle for the file |
| idempotency key | Your own item id | Exact-retry safety |
How do I pass media to a later node that needs the file?
Pass the URL and let the node download it. A node that burns a caption onto a video, or uploads it to a social platform, needs bytes for a moment; it does not need them in a checkpoint. Download inside the node, process, upload, and return only the new URL or an id.
If the next step is another Sume call that takes a media input, give it the URL where the route accepts one. Check the live OpenAPI at https://api.sume.com/reference/json for each route's input fields rather than guessing, since the docs say that document is the schema source of truth.
Finally, size your checkpoints on a real thread. Run twenty generations and look at the stored state size per step. With URLs and ids it should grow by a few hundred bytes per item, and DeltaChannel then keeps even that growth from being rewritten at every step.
Are those URLs permanent?
The docs I read do not state an expiry for artifact URLs, so do not promise one downstream. If you must keep a file long term, download it into your own storage when the job completes and store your own URL next to the Sume one. For a full list of what a job returns, read it from GET /v1/jobs/{id}/result after result_ready, not from a checkpoint you wrote hours ago. Before you ship, read the live contract for every route you call at https://api.sume.com/reference/json, which Sume's docs name as the schema source of truth, and re-read the linked docs pages: limits, scopes and error codes change faster than blog posts do. Treat any number in this post as a snapshot dated 2026-10-02, and prefer the effective fields your own responses return, such as generation_limits, over a static table.
Sources
Related posts
More in Developers
- LangGraph error_handler after retries: do not resubmit a Sume job
LangGraph 1.2 node error handlers run after retries are exhausted. For a Sume call, the handler should read job status, not submit a second paid request.
- LangGraph request_drain and GraphDrained: resume a Sume job later
LangGraph 1.2 can drain a run after the current superstep. If a Sume job is in flight, save its id so the resumed run polls instead of resubmitting.
- LinkedIn API version 202510 sunsets Oct 15, 2026: what to change
LinkedIn Marketing version 202510 is sunset on October 15, 2026. Pin Linkedin-Version 202609 and add a check so a stale pin fails in CI, not in production.
- LinkedIn Videos API: 4 MB parts, ETags and finalizeUpload
LinkedIn video upload is initializeUpload, PUT each 4 MB part, collect the ETags, then finalizeUpload. A part splitter and the order rules that break uploads.
Written by Sume