Skip to content
GitmoapAPIBeta
Buildpipeline-runs
GET/repositories/{repo_id}/pipeline-runs/{pipeline_run_id}/nodes/{node_run_id}

Read one step of a pipeline run, at any attempt

get_node_run
  • pipeline:read
    A token needs the pipeline:read scope: View pipeline runs and definitionsGranted by read_api, read_repository, write_api, write_repository.Every operation this scope unlocks

Returns the step's name, stage, provider and capability, status, attempt number, timing, exit code and error summary. Address it by the id of any of its attempts, current or earlier; the answer describes the step as it stands. Anyone who can read the repository may call it.

Parameters

Path
  • repo_idRepositoryId (string · uuid)Repository id
  • pipeline_run_idPipelineRunId (string · uuid)Pipeline run id
  • node_run_idNodeRunId (string · uuid)Node run id (current or historic attempt)

Responses

200application/json
  • attemptinteger · int320–∞
  • capability_idCapabilityId (string)The capability this step runs, as {provider}:{name} (e.g. docker:build).
  • historyarray of NodeAttemptRecordEarlier attempts of this step after retries, oldest first.
    • The NodeAttemptRecord schema
    • attemptinteger · int320–∞
    • finished_atstringWhen the attempt ended, RFC 3339.
    • node_run_idNodeRunId (string · uuid)
    • statusNodeStatuspendingawaiting_approvaldispatchedrunningsucceededfailedtimed_outskippedcancelledWhere a step has got to.
    • exit_codeinteger · int32 or nulloptional
  • logs_hrefstringRelative URL of this step's logs.
  • node_idNodeId (string)
  • node_run_idNodeRunId (string · uuid)
  • provider_idProviderId (string)The provider that runs this step (e.g. docker), as chosen from the catalog when the run started.
  • stage_idStageId (string)
  • stage_indexinteger · int320–∞
  • statusNodeStatuspendingawaiting_approvaldispatchedrunningsucceededfailedtimed_outskippedcancelledWhere a step has got to.
  • allow_failurebooleanoptionalThe author marked this step as allowed to fail: if it fails or times out, the stage and the run carry on (the run ends succeeded_with_warnings) and only the steps that depend on it are skipped. Show such a failure as a warning.
  • duration_msinteger · int64 or nulloptional0–∞
  • error_summarystring or nulloptionalWhy the step failed, skipped, timed out or was cancelled, in a sentence or two. For a step that failed after it ran, the same text as failure describes.
  • exit_codeinteger · int32 or nulloptional
  • failureNodeFailure or nulloptionalWhy a step that ran failed, as a cause a client can act on. Absent for a step that succeeded or never ran.
  • finished_atstring or nulloptional
  • namestringoptionalThe step's display name, as the pipeline's author wrote it when the run started. Empty for older runs recorded without one; show the capability instead.
  • originNodeOrigin or nulloptionalThe component this step was expanded from, when the author wrote a component instance rather than the step itself. Absent for a step the pipeline declares directly, and for runs that predate this field.
    • The NodeOrigin schema
    • component_idComponentId (string · uuid)
    • component_nameComponentName (string)
    • inner_node_idNodeId (string)This node's identifier inside the component body — what its author called it, before expansion prefixed it with the instance.
    • instance_idNodeId (string)The component instance in the pipeline the author wrote.
    • versionComponentVersion (string)The version the instance's reference resolved to.
  • retry_afterstring or nulloptionalWhen the platform next checks whether a held step can start, RFC 3339 — the wait timer's expiry, or the next check of the concurrency lock. Absent when nothing is scheduled, including while waiting for an approval, which a person gives rather than a clock.
  • started_atstring or nulloptional
  • waiting_onNodeWaitKindapprovalwait_timerconcurrency_lockor nulloptionalWhy a step that has not started is being held: it is waiting for an approval, for an environment's wait timer, or for another run to release its concurrency lock. Absent for a step that is simply waiting for the steps before it.
200 exampleSynthesized example
{
"attempt": 2,
"capability_id": "44b143ae-386a-4a84-9518-e89b94a8ede1",
"history": [
{
"attempt": 7,
"finished_at": "2026-10-15T04:11:55Z",
"node_run_id": "25dc1bbb-ae7d-49e8-9abe-f4bb5e75641f",
"status": "pending"
},
{
"attempt": 6,
"finished_at": "2026-10-16T05:50:00Z",
"node_run_id": "50bda785-46aa-4336-a8e0-60fdb6df8f21",
"status": "pending"
}
],
"logs_href": "logs-href-47c2",
"node_id": "2d9fb172-a60c-4e08-a6e6-d9eeb05ff8bb",
"node_run_id": "473e9b4c-b94a-4812-acb2-d63a22a7979c",
"provider_id": "4dcd07e8-a7fa-45b9-a435-2a2dfff7f485",
"stage_id": "d1935dff-a7cb-4c67-9109-931243a8f2fe",
"stage_index": 7,
"status": "pending",
"allow_failure": false,
"duration_ms": 87,
"error_summary": "error-summary-9ff7",
"exit_code": 57,
"failure": {
"kind": "setup_failed"
},
"finished_at": "2026-10-16T14:27:34Z",
"name": "payments-api",
"origin": {
"component_id": "98556786-042c-42cf-8d24-dd50af7c139b",
"component_name": "payments-api",
"inner_node_id": "28a20164-4e15-4df5-8fe9-509231a99540",
"instance_id": "45064ebd-bf84-4521-a795-dfdc62577978",
"version": "version-1923"
},
"retry_after": "retry-after-d144",
"started_at": "2026-10-15T17:40:31Z",
"waiting_on": "approval"
}
400Bad request — a path parameter is not a well-formed value of its typeapplication/json
Error codes
  • BAD_REQUESTThe request is malformed: a parameter or a body field is not a well-formed value of its type
  • errorErrorBody
    • The ErrorBody schema
    • codestringThe coarse category, tied to the status: NOT_FOUND, CONFLICT, INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all.
    • messagestringWhat went wrong, for a person. Written to be read, not parsed: match on reason or code.
    • fieldstring or nulloptionalOn a 400 that refused one field's value, the field, as its JSON path: email, items[0].name. Put the message under that input. Absent on every other error.
    • reasonstring or nulloptionalThe specific code, when the error has one: LAST_ORGANIZATION_OWNER, BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and on code otherwise.
    • required_scopestring or nulloptionalThe scope the access token was missing, on INSUFFICIENT_SCOPE.
    • violationsanyoptionalPresent on the structured-validation errors (PROVIDER_VALIDATION_FAILED per-node, PIPELINE_VALIDATION_FAILED DAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
400 exampleSynthesized example
{
"error": {
"code": "code-273c",
"message": "Inline scalar newtypes but keep their brand"
}
}
401application/json
Error codes
  • UNAUTHORIZEDNo credential was sent, or the one sent is invalid, expired or revoked
  • errorErrorBody
    • The ErrorBody schema
    • codestringThe coarse category, tied to the status: NOT_FOUND, CONFLICT, INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all.
    • messagestringWhat went wrong, for a person. Written to be read, not parsed: match on reason or code.
    • fieldstring or nulloptionalOn a 400 that refused one field's value, the field, as its JSON path: email, items[0].name. Put the message under that input. Absent on every other error.
    • reasonstring or nulloptionalThe specific code, when the error has one: LAST_ORGANIZATION_OWNER, BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and on code otherwise.
    • required_scopestring or nulloptionalThe scope the access token was missing, on INSUFFICIENT_SCOPE.
    • violationsanyoptionalPresent on the structured-validation errors (PROVIDER_VALIDATION_FAILED per-node, PIPELINE_VALIDATION_FAILED DAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
401 exampleSynthesized example
{
"error": {
"code": "code-3e98",
"message": "Pin a page's payload to the build that rendered it"
}
}
403application/json
Error codes
  • FORBIDDENYou are signed in but may not do this here; reason names the permission or the rule that refused it
  • INSUFFICIENT_SCOPEThe access token lacks the scope this operation needs; required_scope names it
  • PERMISSION_REQUIREDYou need a permission you do not hold here; the message names it
  • errorErrorBody
    • The ErrorBody schema
    • codestringThe coarse category, tied to the status: NOT_FOUND, CONFLICT, INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all.
    • messagestringWhat went wrong, for a person. Written to be read, not parsed: match on reason or code.
    • fieldstring or nulloptionalOn a 400 that refused one field's value, the field, as its JSON path: email, items[0].name. Put the message under that input. Absent on every other error.
    • reasonstring or nulloptionalThe specific code, when the error has one: LAST_ORGANIZATION_OWNER, BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and on code otherwise.
    • required_scopestring or nulloptionalThe scope the access token was missing, on INSUFFICIENT_SCOPE.
    • violationsanyoptionalPresent on the structured-validation errors (PROVIDER_VALIDATION_FAILED per-node, PIPELINE_VALIDATION_FAILED DAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
403 exampleSynthesized example
{
"error": {
"code": "code-b4fb",
"message": "Label every synthesized example"
}
}
404application/json
Error codes
  • NOT_FOUNDThe resource does not exist — or exists and you cannot see it: a private resource you have no access to answers exactly as an absent one does
  • errorErrorBody
    • The ErrorBody schema
    • codestringThe coarse category, tied to the status: NOT_FOUND, CONFLICT, INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all.
    • messagestringWhat went wrong, for a person. Written to be read, not parsed: match on reason or code.
    • fieldstring or nulloptionalOn a 400 that refused one field's value, the field, as its JSON path: email, items[0].name. Put the message under that input. Absent on every other error.
    • reasonstring or nulloptionalThe specific code, when the error has one: LAST_ORGANIZATION_OWNER, BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and on code otherwise.
    • required_scopestring or nulloptionalThe scope the access token was missing, on INSUFFICIENT_SCOPE.
    • violationsanyoptionalPresent on the structured-validation errors (PROVIDER_VALIDATION_FAILED per-node, PIPELINE_VALIDATION_FAILED DAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
404 exampleSynthesized example
{
"error": {
"code": "code-59ae",
"message": "Pin a page's payload to the build that rendered it"
}
}

CLI

gitmoap pipeline-runs get-node-run

  • --repo-ididRepository id (id or owner/repo path)
  • --pipeline-run-ididPipeline run id
  • --node-run-ididNode run id (current or historic attempt)

Used in these guides