> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dreamlayer.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Jobs and event streams

> Follow durable execution, resume server-sent events, and read canonical state.

# Jobs and event streams

## What this lets you do

Follow a durable execution, reconnect after a dropped stream, and avoid duplicate work.

This page describes image and sprite executions. For Video, use [Video jobs and recovery](/agent-api/video-jobs): acceptance returns JSON, the state set differs, and the stream uses `progress`, `asset`, and `done` without an initial `started` event.

## What you need

* An `execution_id` from the `started` event
* The latest received event ID
* The same authenticated account that created the execution

## Steps

### 1. Handle the closed event set

The closed public set is `started`, `thinking`, `progress`, `job`, `question`, `asset`, and `done`.

Do not branch on display text. Branch on event name and documented status fields.

### 2. Resume after disconnect

```bash theme={null}
curl --no-buffer https://api.dreamlayer.io/v1/executions/$EXECUTION_ID/events \
  -H "Authorization: Bearer $DREAMLAYER_API_KEY" \
  -H "DreamLayer-Version: 1" \
  -H "Last-Event-ID: $LAST_EVENT_ID"
```

Read `GET /v1/executions/{execution_id}` before deciding whether to retry. The canonical status is one of `needs_input`, `queued`, `running`, `completed`, `failed`, or `cancelled`.

The beta permits two active managed jobs per account. Sprite-sheet jobs can remain active across several event streams. Use the same execution ID and the last event ID on each reconnect; the job and its credit reservation continue independently of the stream.

## Confirm it worked

The resumed stream continues after the supplied event ID without creating a second execution or charge.

## Common errors

* `404`: use an execution owned by the authenticated account.
* `409`: read canonical state and stop applying an invalid state transition.
* `429`: back off for the request or open-stream limit. A queued execution waiting for an active-job slot continues independently.

## Troubleshooting

Persist the execution ID and latest event ID before updating the interface. If state is uncertain, read canonical state before submitting anything new.

## Next steps

* [Apply idempotency and retry rules](/agent-api/idempotency-and-retries)
* [Handle error codes](/agent-api/errors)

## Event payload examples

The IDs below are illustrative. Treat event IDs as opaque cursors in client storage. Events carry public execution state; progress text is display-only and `thinking` contains no reasoning text.

| Event | Example `data` |
| - | - |
| `started` | `{"execution_id":"d34db33f-0000-4000-8000-000000000001","conversation_id":"d34db33f-0000-4000-8000-000000000002"}` |
| `thinking` | `{}` |
| `progress` | `{"text":"Starting image generation."}` |
| `job` | `{"public_job_id":"d34db33f-0000-4000-8000-000000000003","status":"queued"}` |
| `question` | `{"question_id":"d34db33f-0000-4000-8000-000000000004","conversation_id":"d34db33f-0000-4000-8000-000000000002","text":"Which image should I use? Upload or attach one, then respond."}` |
| `asset` | `{"asset_id":"d34db33f-0000-4000-8000-000000000005","download_url":"https://api.dreamlayer.io/v1/image-jobs/d34db33f-0000-4000-8000-000000000003/asset"}` |
| `done` | `{"status":"completed"}` |

A wire event consists of fields separated by newlines and ends with a blank line:

```text theme={null}
id: 42
event: done
data: {"status":"completed"}

```

Ignore comment lines beginning with `:`. Join multiple `data:` lines before parsing JSON. Buffer partial frames across network chunks. Save a cursor only after processing a complete event. Do not assume every connection contains every event type.

`done` can also report `needs_input`, `failed`, or `cancelled`. For a non-retryable admission failure, `done` includes the same `error` as canonical execution state:

```json theme={null}
{"status":"failed","error":{"reason":"insufficient_credits","message":"The account has insufficient credits.","retryable":false}}
```

Inspect both the execution's `error` and `image_job.sanitized_error` when a run fails. Retryable admission failures stay queued and are retried by the service rather than being emitted as errors.

A `needs_input` event ends that turn's stream, not the entire conversation. Answer using `respond` and the conversation ID, then follow the answer's new execution ID. A stream can close before `done`; query canonical state rather than declaring success or submitting again.

The [Python and JavaScript examples](/agent-api/examples) implement parsing, cursor persistence, state checks, and reconnects. See [limits](/agent-api/limits) before increasing reconnect or polling frequency.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.