---
title: "Job progress as Server-Sent Events"
method: GET
path: "/api/jobs/{job_id}/stream"
tags: ["Jobs and downloads"]
---

# Job progress as Server-Sent Events

`GET /api/jobs/{job_id}/stream`

## Request

- Base URL: `https://epw.tools`
- URL: `https://epw.tools/api/jobs/{job_id}/stream`
- Auth: API key in header `X-API-Key`

Server-Sent Events endpoint for real-time log streaming.

Emits a comment-line keepalive every ``_SSE_KEEPALIVE_SEC`` seconds so
reverse proxies (Cloudflare Tunnel, nginx) don't tear down the
connection during long quiet stretches of a multi-minute job.
Module-level so tests can shrink the interval to a fraction of a
second (hostile peer-review R18).

R2-6 — reconnects no longer replay the whole log: every log event
carries an SSE ``id:`` (its index), browser auto-reconnects send it
back as ``Last-Event-ID``, and manual reconnects (e.g. after a token
refresh, where the browser does not send the header) can pass
``?from=<count already received>``.

## Path parameters

- `job_id` string, required

## Query parameters

- `from` integer
- `key` string, nullable
- `token` string, nullable

## Headers

- `X-API-Key` string, nullable

## Response `200`

Successful Response

- unknown

## Other responses

- `402`: Insufficient credits for this operation.
- `422`: Validation Error
- `429`: Rate limit exceeded — retry after a short delay.

---

[API](https://skmtc.dev/epw/apis/epw-tools-api.md) · [All operations](https://skmtc.dev/epw/apis/epw-tools-api/llms.txt) · [OpenAPI document](https://skmtc.dev/epw/apis/epw-tools-api/revisions/e6b60fc7a6d7?raw)
