What the run printed
Returns the job’s captured execution log. Fetched on demand: a log
is a debugging artifact a caller wants occasionally, while
GET /api/v2/jobs/{id} is polled to terminal on every run, so the
log is a resource of its own rather than a field that would ride
every one of those polls to be read at most once.
Captured whenever the worker reports its own outcome, success and failure alike, since a job that succeeds while producing the wrong thing is exactly what a failure-only log cannot explain. A run the platform or the provider killed — out of memory, a crashed worker, a timeout, a job past its maximum runtime — never gets that far, so it reaches a terminal status carrying no log at all. That is a real gap and worth stating: the failures a caller most wants a log for are the ones least likely to have produced one.
204 is the normal answer for a job with no log, and the cases
behind it are deliberately not distinguished: this surface does not
capture logs at all, the job has not finished, the job predates log
capture, the run was killed before the worker could report one,
capture was attempted and failed, or the job ran on the public demo
deployment, which captures and stores the log like every other
serverless deployment but withholds it on read, because that surface
takes callers with no credential and a job id would otherwise be the
only thing between one anonymous caller and another’s run.
Because a 204 never says which of those it is, do not branch on the
reason — but do note that one of them resolves itself. A job that has
not finished may have a log once it does, so a caller that wants one
reads again after a terminal status. A 204 on a job already in a
terminal state is final, and so is a missing urls.logs; both mean
stop asking.
Only jobs run on the serverless platform (a
{deployment}.run.comfy.app host) have one today. An implementation
that captures no logs must still serve this operation, answering
204 for every job it can read, so that the two answers stay
distinct — Comfy Cloud does. A self-hosted deployment on a build
predating this operation has not implemented it yet and will answer
a routing 404 instead, which is the case job.urls.logs exists to
keep a client out of: its absence says the surface has no logs at
all, without a request.
Tied to the job’s own retention: this 404s under the same
conditions GET /api/v2/jobs/{id} does (unknown, not-yours, or past
its retention deadline). Nothing ages a log out ahead of the job’s
own expires_at, so a job never outlives its log.
Live tailing is not offered here yet. When it is, it arrives on this
same path under Accept: text/event-stream, leaving this
JSON snapshot the default; its resume semantics will be defined
then, against a capture that is incremental. Until then the SSE
log event on GET /api/v2/jobs/{id}/events is the reserved live
rail, and this is the authoritative snapshot it reconciles against.
授权
Authorization: Bearer <api-key> — account-scoped API keys on Cloud and serverless. Self-hosted accepts unauthenticated requests by default and can be configured with a static bearer token.
路径参数
响应
The captured log.
A job's captured execution log — the body of GET /api/v2/jobs/{id}/logs. Diagnostics, not a contract on content: this is whatever the workflow's own code and nodes wrote to standard output, in the order they wrote it, so nothing about its shape is stable between runs or between releases of a build. It is untrusted text — a workflow chooses what goes in it — and must be rendered as plain text rather than interpreted.
The captured output.
The BEGINNING of the captured output was discarded — text is the TAIL of a longer run. Implementations bound what they capture and store, so a workflow that prints megabytes keeps its last lines, where a failure normally is, instead of being dropped whole. True with an empty text means the log was captured and then shed entirely to fit. This describes the stored log, never the response: it does not mean a caller asked for part of one.
When the run's output was read back off the worker.
No further output will be appended to this log. Always true today, because a log is read back off the worker once, when the run ends, so a log that exists is already whole. Sent so that a surface which later captures output while a run is still going can say so, and a client written now against false keeps working when it does. false does not promise that more output will arrive, only that this snapshot may not be the last one.