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

Read a pipeline run and the state of its steps

get_pipeline_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 run's status, what started it and at which commit, and where every step stands. To follow a run as it changes, read its status or open its event stream rather than reading this again.

Parameters

Path
  • repo_idRepositoryId (string · uuid)Repository id
  • pipeline_run_idPipelineRunId (string · uuid)Pipeline run id

Responses

200application/json
  • edgesarray of ResolvedEdgeThe connections between the run's steps, so a client can draw its graph. Each one feeds an output port of from_node into an input port of to_node.
    • The ResolvedEdge schema
    • from_nodeNodeId (string)
    • to_nodeNodeId (string)
    • from_portPortName (string) or nulloptionalAbsent on a dependency-only connection — one that orders two steps and carries nothing.
    • to_portPortName (string) or nulloptionalAbsent on a dependency-only edge.
  • last_event_idEventId (string · uuid)
  • nodesarray of NodeView
    • The NodeView schema
    • 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.
  • pipeline_namestring
  • pipeline_run_idPipelineRunId (string · uuid)
  • repo_idRepositoryId (string · uuid)
  • stagesarray of StageViewThe run's stages in execution order, each with how many of its steps have finished and failed.
    • The StageView schema
    • barrier_passedbooleanWhether every step in the stage has finished, so later stages may start.
    • failed_countinteger · int320–∞Steps in the stage that failed or timed out, not counting steps allowed to fail.
    • stage_idStageId (string)
    • stage_indexinteger · int320–∞The stage's position in execution order, counting from zero.
    • terminal_countinteger · int320–∞Steps in the stage that have finished, whatever their outcome.
    • totalinteger · int320–∞Steps in the stage.
  • started_atstring
  • statusPipelineStatusrunningsucceededsucceeded_with_warningsfailedtimed_outcancelledPer-PipelineRun status.
  • triggerTriggerContext
    • The TriggerContext schema
    • repo_idRepositoryId (string · uuid)
    • repo_pathstring
    • before_shastring or nulloptionalThe commit the ref pointed at before the push — what a paths filter compares against. On a run started by hand, the commit its starter named to compare from, if any.
    • branchstring or nulloptional
    • buildMrBuildTargetmerge_resultsourceor nulloptionalWhich commit a merge-request-triggered run built.
    • commit_shastring or nulloptional
    • depthinteger · int32optional0–∞How many pushes made by pipeline runs led to this run, one after another; 0 when no pipeline's push started it.
    • every_stepbooleanoptionalEvery step runs, whatever its path filter says — asked for by whoever started the run.
    • extraobjectoptionalAdditional fields supplied by whatever started the run, passed along without being interpreted.
    • kindTriggerKindpushmerge_requesttagschedulemanualoptionalWhat started this run.
    • mr_idMergeRequestId (integer · int64) or nulloptional
    • paramsobjectoptionalThe values a person supplied when starting the run, keyed by the parameter names the pipeline's manual trigger declares.
    • ref_namestring or nulloptionalThe full ref (e.g. refs/tags/v1.2.0). Set for runs a tag started, which branch cannot describe.
    • root_group_idGroupId (string · uuid) or nulloptionalThe organisation this run belongs to — the root group of the repository it was triggered for. Recorded when the run starts and never recalculated, so a repository moved to a different organisation part-way through a run keeps the artifacts, logs and cache it has already produced. Absent on runs that started before runs recorded this.
    • schedule_stemstring or nulloptionalWhich scheduled trigger fired, when kind is schedule.
    • source_shastring or nulloptionalThe source-branch commit this run tested: a merge request's source head for a merge-request run, whichever commit it built, and the commit itself for a push or manual run. Set by the platform; absent on a run whose graph the caller supplied, which never counts toward a merge request's pipelines.
    • target_branchstring or nulloptionalThe merge request's target branch.
    • target_shastring or nulloptionalThe target branch's tip this merge-request run was tested against. Once the target branch moves on, the merge check reports a merge-result run as out of date.
    • triggered_byActorSummaryoptionalWho started the run, set by the platform from the authenticated caller; a value supplied in a request is ignored.
    • trustTriggerTrusttrusteduntrustedoptionalWhether the code being built is trusted with the repository's connections and secrets. Set by the platform when the run starts, whatever a request says.
    • trust_reasonTrustReason or nulloptionalWhy the run has the trust it has: who wrote the code, a person's merge or approval, or the organization's AI configuration. Absent on runs that started before this was recorded.
  • versioninteger · int640–∞
  • finished_atstring or nulloptional
  • pipeline_idPipelineId (string · uuid) or nulloptionalThe pipeline definition this run was started from. Absent when that definition has since been deleted; pipeline_name still names what ran.
  • re_run_ofPipelineRunId (string · uuid) or nulloptional
200 exampleSynthesized example
{
"edges": [
{
"from_node": "from-node-0bd1",
"to_node": "to-node-b5a2"
}
],
"last_event_id": "6bc0ec82-b1c3-4ef0-a561-6a814db82393",
"nodes": [
{
"attempt": 5,
"capability_id": "ec108291-bdab-4473-9519-121b86e828ab",
"history": [],
"logs_href": "logs-href-f2f5",
"node_id": "be16a685-4e0e-4374-b711-83e3f872381f",
"node_run_id": "9f162ebb-2cd2-4561-85fb-0385fce174ee",
"provider_id": "14578b71-819b-4af5-af82-9e2b6c88db3d",
"stage_id": "67a07293-af96-4e05-9a69-340ad4fb46d5",
"stage_index": 6,
"status": "pending"
},
{
"attempt": 1,
"capability_id": "63361222-69e1-4cff-90ef-a61c4c594b4d",
"history": [],
"logs_href": "logs-href-c29f",
"node_id": "0ec35e74-ae6a-42af-9c51-eab6b03dbdf5",
"node_run_id": "44a01e25-b5dc-4d9a-b49d-ca9dfea649a6",
"provider_id": "19fd4009-2454-4a4e-bb10-5d656496c227",
"stage_id": "e09b97da-d0d9-4b9e-aebf-fb903116fde5",
"stage_index": 6,
"status": "pending"
}
],
"pipeline_name": "payments-api",
"pipeline_run_id": "9e2b7c41-3d5a-4f8e-b1c2-7a6d5e4f3c2b",
"repo_id": "5b0e7c2a-9d14-4e8b-a6f1-2c3d4e5f6a70",
"stages": [
{
"barrier_passed": false,
"failed_count": 3,
"stage_id": "9190af1c-b739-492b-aafb-2967b11ee428",
"stage_index": 3,
"terminal_count": 5,
"total": 7
}
],
"started_at": "2026-10-10T02:45:30Z",
"status": "running",
"trigger": {
"repo_id": "5b0e7c2a-9d14-4e8b-a6f1-2c3d4e5f6a70",
"repo_path": "repo-path-40e0",
"before_sha": "d821ff5583aa62b7d9fabab92d8db0cfcd34c87c",
"branch": "fix/payload-build-pin",
"build": "merge_result",
"commit_sha": "ed349b52be1ea349eeb0f29594f5741f74707610",
"depth": 74,
"every_step": false,
"extra": {},
"kind": "push",
"mr_id": 42,
"params": {},
"ref_name": "payments-api",
"root_group_id": "4c1d8e2f-6a3b-4f90-b7c5-1e2d3c4b5a69",
"schedule_stem": "schedule-stem-35a6",
"source_sha": "ec08a5fead992400f248b00651bef365afe39956",
"target_branch": "main",
"target_sha": "bf4052aceee6a1e19e85ec6dfc06271a69016e5f",
"triggered_by": {
"email": "mara@acme.example",
"id": "id-c9f8",
"username": "tomas",
"avatar_url": "https://gitmoap.example/acme/d4a1b3bf"
},
"trust": "trusted",
"trust_reason": {
"kind": "written_by_people"
}
},
"version": 39,
"finished_at": "2026-10-09T12:53:54Z",
"pipeline_id": "01e4a67b-4538-4e92-8fb7-3d9d56bc325b",
"re_run_of": "9e2b7c41-3d5a-4f8e-b1c2-7a6d5e4f3c2b"
}
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-83f3",
"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-85e1",
"message": "Inline scalar newtypes but keep their brand"
}
}
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-630b",
"message": "Inline scalar newtypes but keep their brand"
}
}
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-b75d",
"message": "Pin a page's payload to the build that rendered it"
}
}
501Pipelines are not configured on this deploymentapplication/json
Error codes
  • NOT_IMPLEMENTEDThis deployment has not configured the feature the operation needs; 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.
501 exampleSynthesized example
{
"error": {
"code": "code-fb0f",
"message": "Inline scalar newtypes but keep their brand"
}
}

CLI

gitmoap pipeline-runs get

  • --repo-ididRepository id (id or owner/repo path)
  • --pipeline-run-ididPipeline run id

Used in these guides