Skip to content
GitmoapAPIBeta
Buildpipelines
POST/repositories/{repo_id}/pipelines/{pipeline_id}/publish

Publish a draft pipeline definition.

publish_pipeline
  • pipeline:manage
    A token needs the pipeline:manage scope: Create, update, and delete pipeline definitionsGranted by write_api, write_repository.Every operation this scope unlocks
  • Audited · mutation

    x-gitmoap-audit: {"kind":"audited","arg":"mutation"}

Runs the same validation as creating a published pipeline — the graph must hold together and the name must be unique among the repository's published pipelines — then publishes it. Publishing an already-published pipeline changes nothing; when validation fails, the draft is left as it was.

Parameters

Path
  • repo_idRepositoryId (string · uuid)Repository id
  • pipeline_idPipelineId (string · uuid)Pipeline definition id

Responses

200Pipeline publishedapplication/json
  • created_atstringRFC 3339.
  • created_byActorSummary
  • edgesarray of Edge
    • The Edge schema
    • idEdgeId (string)
    • source_node_idNodeId (string)
    • target_node_idNodeId (string)
    • source_portPortName (string) or nulloptionalAbsent on a dependency-only edge.
    • target_portPortName (string) or nulloptionalAbsent on a dependency-only edge.
  • idPipelineId (string · uuid)
  • namePipelineName (string)
  • repo_idRepositoryId (string · uuid)
  • stagesarray of Stage
    • The Stage schema
    • idStageId (string)
    • namestring
    • stage_typeStageTypesourcebuildtestpublishdeploynotifycustomThe pipeline stage a capability belongs to. Maps verbatim to the stage_type field of a capability in gitmoap-provider.yaml.
    • barrier_modeBarrierModestrictlenientoptionalWhen a stage is allowed to start. strict waits for every step in every earlier stage to finish, so a failure anywhere stops what follows. lenient waits only for the steps a given step actually depends on, so an unrelated branch failing does not block it. strict is the default.
    • nodesarray of Nodeoptional
      • The Node schema
      • capability_idCapabilityId (string)
      • idNodeId (string)
      • namestring
      • allow_failurebooleanoptionalWhen true, this node's failure (a non-zero exit or a timeout, after any retries) is non-blocking: it does not fail the enclosing stage or the run. The node's transitive dependents — which can never receive its output — are skipped, while independent branches and later stages keep running. A run whose only failures were allow_failure nodes finishes succeeded_with_warnings.
      • approvalManualApproval or nulloptionalHolds this step until it is approved. A step deploying to an environment that requires approval is held as well, whether or not this is set.
      • changesarray of string or nulloptionalPath globs that decide whether this step runs: when none of them matches a path the push changed, the step is skipped. When absent and service is set, the service's own path globs apply.
      • configobjectoptionalThe step's provider-specific configuration, checked against the capability's config_schema when the run starts.
      • connectionProviderConnectionName (string) or nulloptionalThe provider connection to use, by name (e.g. aws-prod). When absent, the step uses the provider's only connection available to the repository, if there is exactly one.
      • cpustring or nulloptional
      • environmentEnvironmentSlug (string) or nulloptionalThe environment this step deploys to, by slug. It is looked up on the repository and then on each group above it when the run starts.
      • matrixMatrixSpec or nulloptionalRuns this step once for every combination of the named dimensions' values. At most 100 copies.
      • max_retriesinteger · int32optional0–∞
      • memorystring or nulloptional
      • resource_groupNodeResourceGroup or nulloptionalKeeps this step from running at the same time as any other step, in any of your organization's pipelines, that names the same resource group — a Terraform state, a shared staging database, a fragile external sandbox. The cancel_previous mode is not accepted here.
      • retry_delay_secondsinteger · int32optional0–∞
      • serviceServiceSlug (string) or nulloptionalThe catalog service this step acts on, by slug. Optional when the repository holds exactly one service, which is then implied; required when it holds more.
      • timeout_secondsinteger · int32 or nulloptional0–∞
      • variables_fromEnvironmentSlug (string) or nulloptionalAn environment whose plain variables this step reads, by slug, without deploying there — for a build that bakes the environment's settings in. The step receives the environment's non-secret variables and nothing else: no approval, no lock, no secrets, and no deployment is recorded. A step may name this or environment, not both.
      • versionProviderVersion (string) or nulloptionalPins a specific provider version. When absent, the provider's default version for this repository is used, as it stands when the run starts.
  • statusPipelineDefinitionStatusdraftpublishedWhether a pipeline definition can run. A draft is saved even when it is invalid — problems are reported, not refused — and cannot be run; a published definition must be valid to be saved, and can be run.
  • trigger_configTriggerConfig
  • updated_atstringRFC 3339.
  • component_instancesarray of ComponentInstanceoptional
    • The ComponentInstance schema
    • component_idComponentId (string · uuid)The component used, by id. Creating another component with the same name later never changes what this instance runs.
    • idNodeId (string)The instance's id, unique among the pipeline's step ids. Connections use it as they use a step id.
    • namestringDisplay name, also put in front of the display names of the steps it expands into.
    • versionComponentVersionRef (string)
    • component_refstring or nulloptionalThe reference as the author wrote it, kept for display. It is not used to find the component.
    • paramsobjectoptionalValues for the component's parameters, by parameter name.
    • stage_mapobjectoptionalMaps every stage slot the component declares to a stage of this pipeline, keeping the slots' order.
  • descriptionstring or nulloptional
  • diagnosticsValidationSummary or nulloptionalThe problems found in a draft. Present only for drafts.
    • The ValidationSummary schema
    • validboolean
    • violationsarray of ValidationViolation
    • warningsarray of ValidationWarningoptionalThings worth knowing that do not make the definition invalid, such as a deprecated component version. A violation stops a published definition from being saved; a warning never does. Left out when there are none.
200 exampleSynthesized example
{
"created_at": "2026-10-13T01:48:16Z",
"created_by": {
"email": "tomas@acme.example",
"id": "id-335b",
"username": "lin",
"avatar_url": "https://gitmoap.example/acme/077f6548"
},
"edges": [
{
"id": "id-60f5",
"source_node_id": "168dd8be-0ab6-42b9-bd80-0511993e24c8",
"target_node_id": "fb40fed0-b27f-44a4-be97-c902f9e498f6"
},
{
"id": "id-78b7",
"source_node_id": "9d1de576-585a-478a-9c3c-d46ac82b340f",
"target_node_id": "d2cce5fc-f4a8-49d0-8244-6bca92ced038"
}
],
"id": "c5172550-a514-4787-a9e1-500fda7e379c",
"name": "payments-api",
"repo_id": "5b0e7c2a-9d14-4e8b-a6f1-2c3d4e5f6a70",
"stages": [
{
"id": "id-80ef",
"name": "payments-api",
"stage_type": "source"
},
{
"id": "id-147d",
"name": "payments-api",
"stage_type": "source"
}
],
"status": "draft",
"trigger_config": {
"events": [
{
"type": "push"
},
{
"type": "push"
}
]
},
"updated_at": "2026-10-12T03:38:54Z",
"component_instances": [
{
"component_id": "e53886c4-7f26-4b69-912e-c4853e42d9c1",
"id": "id-d3af",
"name": "payments-api",
"version": "version-545d"
}
],
"description": "Renders each region as density contours of its operations.",
"diagnostics": {
"valid": false,
"violations": [
{
"code": "code-8951",
"message": "Stream pipeline status into the run header",
"target": {
"kind": "pipeline"
}
},
{
"code": "code-f463",
"message": "Inline scalar newtypes but keep their brand",
"target": {
"kind": "pipeline"
}
}
],
"warnings": [
{
"code": "code-5cc1",
"message": "Inline scalar newtypes but keep their brand",
"target": {
"kind": "pipeline"
}
},
{
"code": "code-29d2",
"message": "Stream pipeline status into the run header",
"target": {
"kind": "pipeline"
}
}
]
}
}
400The graph fails validation (each violation listed)application/json
Error codes
  • APPROVERS_NOT_IN_ENVIRONMENTA pipeline step names approvers its environment does not; a step may narrow its environment's approvers, not replace them
  • BAD_REQUESTThe request is malformed: a parameter or a body field is not a well-formed value of its type
  • PIPELINE_VALIDATION_FAILEDThe pipeline definition is invalid; violations lists every problem, so all of them can be fixed at once
  • 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-7f89",
"message": "Stream pipeline status into the run header"
}
}
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-bfb4",
"message": "Stream pipeline status into the run header"
}
}
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-ce78",
"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-9441",
"message": "Pin a page's payload to the build that rendered it"
}
}
409A published pipeline with this name already existsapplication/json
Error codes
  • CONFLICTThe request conflicts with the resource's current state; reason says how
  • LEGAL_ACCEPTANCE_REQUIREDAccept the current Terms of Service before changing anything; reading stays open
  • 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.
409 exampleSynthesized example
{
"error": {
"code": "code-af61",
"message": "Stream pipeline status into the run header"
}
}

CLI

gitmoap pipelines publish

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

Used in these guides