API reference

Pipelines

Workflows, runs, logs, artifacts, environments, secrets, and the endpoints runners call.

See Pipelines. Runners call /v1/runner with their job's token (Authorization: Bearer sjt_…), which works only while that job is queued or running.

GET /v1/runner/job

The job's plan: steps, contexts and its secrets. The job counts as running from here.

Auth: none

Response 200

{
  plan: {
    protocol: number
    job: {
      id: string
      key: string
      name: string
      runId: string
      runNumber: number
      attempt: number
      workflow: string
      repository: string
      timeoutMinutes: number
    }
    contexts: {
      [key: string]: boolean | null | string | number | (boolean | null | string | number | object | {
        [key: string]: boolean | null | string | number | object
      })[] | {
        [key: string]: boolean | null | string | number | (boolean | null | string | number | object)[] | object
      }
    }
    env: {
      [key: string]: string
    }
    defaults: {
      shell?: string
      workingDirectory?: string
    }
    steps: {
      index: number
      id?: string
      name?: string
      if?: string
      run?: string
      shell?: string
      workingDirectory?: string
      uses?: "cache" | "checkout" | "upload-artifact" | "download-artifact"
      with?: {
        [key: string]: string
      }
      env?: {
        [key: string]: string
      }
      continueOnError?: boolean | string
      timeoutMinutes?: string | number
    }[]
    outputs: {
      [key: string]: string
    }
    marker: string
    limits: {
      logBytes: number
      summaryBytes: number
      artifactBytes: number
      cacheBytes: number
    }
    serverUrl: string
  }
}

POST /v1/runner/checkout

A git credential for the run's repository, minutes long.

Auth: none

Request body

FieldTypeRequiredNotes
refstringNoup to 255 characters

Response 200

{
  url: string
  authorization: string
  sha: string
  ref: string
}

POST /v1/runner/status

Step progress and a heartbeat; answers whether to stop.

Auth: none

Request body

FieldTypeRequiredNotes
stepsobject[]Yesup to 1,100 items
steps[].indexintegerYes0–5000
steps[].namestringYesup to 500 characters
steps[].status"pending" | "in_progress" | "completed"Yes
steps[].conclusion"success" | "failure" | "cancelled" | "skipped"No
steps[].outcome"success" | "failure" | "cancelled" | "skipped"No
steps[].startedAtnumberNo
steps[].completedAtnumberNo
steps[].postbooleanNo

Response 200

{
  cancel: boolean
}

POST /v1/runner/complete

The job's result.

Auth: none

Request body

FieldTypeRequiredDefaultNotes
conclusion"success" | "failure" | "cancelled"Yes
stepsobject[]No[]up to 1,100 items
steps[].indexintegerYes0–5000
steps[].namestringYesup to 500 characters
steps[].status"pending" | "in_progress" | "completed"Yes
steps[].conclusion"success" | "failure" | "cancelled" | "skipped"No
steps[].outcome"success" | "failure" | "cancelled" | "skipped"No
steps[].startedAtnumberNo
steps[].completedAtnumberNo
steps[].postbooleanNo
outputsobjectNo{}values: string (up to 65,536 characters)
annotationsobject[]No[]up to 50 items
annotations[].level"error" | "warning" | "notice"Yes
annotations[].messagestringYesup to 4,000 characters
annotations[].filestringNoup to 500 characters
annotations[].lineintegerNo
annotations[].titlestringNoup to 200 characters
annotations[].stepintegerNo
summarystringNoup to 65,536 characters
errorstringNoup to 2,000 characters
timedOutbooleanNo

Response 200

{
  ok: true
}

POST /v1/runner/logs

Self-hosted runners' output, in batches of timestamped lines.

Auth: none

Request body

FieldTypeRequiredNotes
linesobject[]Yesup to 20,000 items
lines[].tnumberYes
lines[].mstringYesup to 200,000 characters

Response 200

{
  ok: true
}

POST /v1/runner/cache/restore

Finds a cache for key (exact) or restoreKeys (prefixes, newest first) with the same version, in the job's ref, a pull request's target, then the default branch. Answers hit (exact, partial, none) and a presigned download.

Auth: none

Request body

FieldTypeRequiredDefaultNotes
keystringYes1–512 characters
restoreKeysstring[]No[]up to 10 items; each 1–512 characters
versionstringYesmatches ^[0-9a-f]{64}$

Response 200

{
  hit: "none"
  key?: undefined
  size?: undefined
  url?: undefined
} | {
  hit: "partial" | "exact"
  key: string
  size: number
  url: string
}

POST /v1/runner/cache/save

A presigned upload for a cache in the job's own ref only (key, version, size), or exists when that key is already saved there (caches are immutable).

Auth: none

Request body

FieldTypeRequiredNotes
keystringYes1–512 characters
versionstringYesmatches ^[0-9a-f]{64}$
sizeintegerYes≥ 1

Response 200

{
  exists: true
  url?: undefined
} | {
  url: string
  exists?: undefined
}

POST /v1/runner/cache/commit

Finishes a cache after its upload; the repository's oldest unused caches go when it passes its quota.

Auth: none

Request body

FieldTypeRequiredNotes
keystringYes1–512 characters
versionstringYesmatches ^[0-9a-f]{64}$
sizeintegerNo≥ 0

Response 200

{
  ok: true
}

POST /v1/runner/artifacts/upload

Starts an artifact of the job's run (name, size, files, retentionDays): a presigned PUT for exactly that size. Names are unique per run attempt.

Auth: none

Request body

FieldTypeRequiredNotes
namestringYesmatches ^[^\\/:*?"<>|\r\n]{1,100}$
sizeintegerYes≥ 1
filesintegerYes≥ 0
retentionDaysintegerNo1–400

Response 200

{
  url: string
}

POST /v1/runner/artifacts/commit

Finishes an artifact after its upload; it's then listed with the run and kept until its retention ends.

Auth: none

Request body

FieldTypeRequiredNotes
namestringYesmatches ^[^\\/:*?"<>|\r\n]{1,100}$
sizeintegerNo
filesintegerNo

Response 200

{
  ok: true
}

POST /v1/runner/artifacts/download

Presigned downloads of the run's artifacts (name for one; this attempt's first, then earlier attempts').

Auth: none

Request body

FieldTypeRequiredNotes
namestringNomatches ^[^\\/:*?"<>|\r\n]{1,100}$

Response 200

{
  artifacts: {
    name: string
    size: number
    url: string
  }[]
}

GET /v1/orgs/:orgId/repos/:name/pipelines/workflows

The workflows of a branch (default: the default branch), with their problems and last run.

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
Query parameterTypeRequiredNotes
refstringNo1–255 characters

Response 200

{
  ref: string
  sha: string
  workflows: {
    file: string
    name: string
    triggers: string[]
    dispatch: null | {
      inputs: {
        name: string
        description?: string
        type: "string" | "number" | "boolean" | "environment" | "choice"
        required: boolean
        default?: boolean | string | number
        options?: string[]
      }[]
    }
    problems: {
      message: string
      line?: number
      column?: number
      severity: "error" | "warning"
    }[]
    disabled: boolean
    lastRun: null | {
      runId: string
      number: number
      attempt: number
      workflowFile: string
      workflowName: string
      event: "push" | "pull_request" | "schedule" | "workflow_dispatch"
      ref: string
      branch: string
      sha: string
      title: string
      actor: {
        id: null | string
        label: null | string
      }
      status: "queued" | "in_progress" | "waiting" | "completed"
      conclusion: null | "success" | "failure" | "skipped" | "cancelled" | "timed_out" | "startup_failure"
      pullNumber: null | number
      cancelRequested: boolean
      waitingForConcurrency: boolean
      problems: null | {
        message: string
        line?: number
        column?: number
      }[]
      createdAt: number
      startedAt: null | number
      completedAt: null | number
    }
  }[]
}

Errors

StatusMessage
404Repository not found

PUT /v1/orgs/:orgId/repos/:name/pipelines/workflows/:file

Turns a workflow on or off (off: no event starts it).

Auth: user access token or platform agent key · Scopes: git:read, git:write

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:fileWorkflow file name in .cactive/workflows, e.g. ci.yml.

Request body

FieldTypeRequiredNotes
enabledbooleanYes

Response 200

{
  file: string
  disabled: boolean
}

Errors

StatusMessage
404Repository not found
404Workflow not found

POST /v1/orgs/:orgId/repos/:name/pipelines/workflows/:file/dispatches

Runs a workflow by hand on a branch with inputs (workflow_dispatch).

Auth: user access token or platform agent key · Scopes: git:read, git:write

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:fileWorkflow file name in .cactive/workflows, e.g. ci.yml.

Request body

FieldTypeRequiredDefaultNotes
refstringYes1–255 characters; trimmed
inputsobjectNo{}values: string (up to 10,000 characters), number or boolean

Response 201

{
  run: {
    runId: string
    number: number
    attempt: number
    workflowFile: string
    workflowName: string
    event: "push" | "pull_request" | "schedule" | "workflow_dispatch"
    ref: string
    branch: string
    sha: string
    title: string
    actor: {
      id: null | string
      label: null | string
    }
    status: "queued" | "in_progress" | "waiting" | "completed"
    conclusion: null | "success" | "failure" | "skipped" | "cancelled" | "timed_out" | "startup_failure"
    pullNumber: null | number
    cancelRequested: boolean
    waitingForConcurrency: boolean
    problems: null | {
      message: string
      line?: number
      column?: number
    }[]
    createdAt: number
    startedAt: null | number
    completedAt: null | number
  }
}

Errors

StatusMessage
404Repository not found

GET /v1/orgs/:orgId/repos/:name/pipelines/runs

Runs, newest first, filtered by workflow, branch, status, actor and event.

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
Query parameterTypeRequiredDefaultNotes
workflowstringNoup to 100 characters
branchstringNoup to 255 characters
status"queued" | "in_progress" | "waiting" | "completed" | "success" | "failure" | "cancelled" | "startup_failure"No
actorstringNoup to 64 characters
event"push" | "pull_request" | "schedule" | "workflow_dispatch"No
shastringNomatches ^[0-9a-f]{40}$
cursorstringNoup to 2,000 characters
limitintegerNo251–100; coerced from a string

Response 200

{
  runs: {
    runId: string
    number: number
    attempt: number
    workflowFile: string
    workflowName: string
    event: "push" | "pull_request" | "schedule" | "workflow_dispatch"
    ref: string
    branch: string
    sha: string
    title: string
    actor: {
      id: null | string
      label: null | string
    }
    status: "queued" | "in_progress" | "waiting" | "completed"
    conclusion: null | "success" | "failure" | "skipped" | "cancelled" | "timed_out" | "startup_failure"
    pullNumber: null | number
    cancelRequested: boolean
    waitingForConcurrency: boolean
    problems: null | {
      message: string
      line?: number
      column?: number
    }[]
    createdAt: number
    startedAt: null | number
    completedAt: null | number
  }[]
  cursor: null | string
}

Errors

StatusMessage
404Repository not found

GET /v1/orgs/:orgId/repos/:name/pipelines/runs/:number

A run (an attempt of it): jobs with steps, the job graph, approvals, artifacts.

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:numberIssue or pull request number, or under pipelines a run number.
Query parameterTypeRequiredNotes
attemptintegerNo≥ 1; coerced from a string

Response 200

{
  run: {
    runId: string
    number: number
    attempt: number
    workflowFile: string
    workflowName: string
    event: "push" | "pull_request" | "schedule" | "workflow_dispatch"
    ref: string
    branch: string
    sha: string
    title: string
    actor: {
      id: null | string
      label: null | string
    }
    status: "queued" | "in_progress" | "waiting" | "completed"
    conclusion: null | "success" | "failure" | "skipped" | "cancelled" | "timed_out" | "startup_failure"
    pullNumber: null | number
    cancelRequested: boolean
    waitingForConcurrency: boolean
    problems: null | {
      message: string
      line?: number
      column?: number
    }[]
    createdAt: number
    startedAt: null | number
    completedAt: null | number
  }
  attempt: number
  attempts: number[]
  graph: {
    key: string
    name: string
    needs: string[]
    environment: null | string
    matrix: boolean
  }[]
  jobs: {
    jobId: string
    key: string
    name: string
    matrix: null | {
      [key: string]: unknown
    }
    status: "queued" | "in_progress" | "waiting" | "completed"
    conclusion: null | "success" | "failure" | "skipped" | "cancelled" | "timed_out" | "startup_failure"
    waitingFor: null | "approval" | "timer" | "concurrency" | "capacity" | "runner"
    waitUntil: null | number
    runner: null | {
      kind: "hosted" | "self-hosted"
      label: null | string
      device: null | string
    }
    environment: null | {
      name: string
      url: null | string
    }
    steps: unknown[]
    annotations: unknown[]
    summary: null | string
    error: null | string
    continueOnError: boolean
    reusedFrom: null | number
    minutes: null | number
    queuedAt: null | number
    startedAt: null | number
    completedAt: null | number
    logArchived: boolean
  }[]
  approvals: {
    environment: string
    status: "pending" | "expired" | "approved" | "rejected"
    reviewers: {
      name: string
      type: "user" | "team"
      id: string
    }[]
    preventSelfReview: boolean
    canReview: boolean
    decidedBy: null | string
    comment: null | string
    decidedAt: null | number
    requestedAt: number
  }[]
  artifacts: {
    name: string
    size: number
    files: number
    attempt: number
    expiresAt: number
    createdAt: number
  }[]
  scopes: ("platform:admin" | "platform:infra" | "platform:analytics" | "platform:coverage" | "org:read" | "org:write" | "audit:read" | "tenant:read" | "tenant:write" | "members:read" | "members:write" | "projects:read" | "projects:write" | "deployments:read" | "deployments:write" | "env:read" | "env:write" | "keys:read" | "keys:use" | "keys:write" | "domains:read" | "domains:write" | "resources:read" | "resources:write" | "git:read" | "git:write" | "git:admin" | "logs:read" | "analytics:read" | "knowledge:read" | "knowledge:write" | "connectors:read" | "connectors:write" | "chat:use" | "mcp:connect" | "agents:read" | "agents:write" | "agents:run" | "mail:read" | "mail:send" | "mail:admin" | "calendar:read" | "calendar:write" | "contacts:read" | "contacts:write" | "issues:read" | "issues:write" | "issues:admin" | "maps:read" | "maps:write" | "drive:read" | "drive:write" | "crm:read" | "crm:write" | "crm:admin" | "marketing:read" | "marketing:write" | "marketing:send" | "marketing:admin" | "health:read" | "health:write" | "weather:read" | "weather:write" | "food:read" | "food:write")[]
}

Errors

StatusMessage
404Repository not found
404Run not found

POST /v1/orgs/:orgId/repos/:name/pipelines/runs/:number/cancel

Cancels a run: queued and waiting jobs end at once, running ones are stopped. Needs git:write.

Auth: user access token or platform agent key · Scopes: git:read, git:write

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:numberIssue or pull request number, or under pipelines a run number.

Response 200

{
  run: {
    runId: string
    number: number
    attempt: number
    workflowFile: string
    workflowName: string
    event: "push" | "pull_request" | "schedule" | "workflow_dispatch"
    ref: string
    branch: string
    sha: string
    title: string
    actor: {
      id: null | string
      label: null | string
    }
    status: "queued" | "in_progress" | "waiting" | "completed"
    conclusion: null | "success" | "failure" | "skipped" | "cancelled" | "timed_out" | "startup_failure"
    pullNumber: null | number
    cancelRequested: boolean
    waitingForConcurrency: boolean
    problems: null | {
      message: string
      line?: number
      column?: number
    }[]
    createdAt: number
    startedAt: null | number
    completedAt: null | number
  }
}

Errors

StatusMessage
404Repository not found
404Run not found
409This run has finished

POST /v1/orgs/:orgId/repos/:name/pipelines/runs/:number/rerun

Re-runs a finished run as a new attempt: all jobs, the failed ones, or one job (and what needs it).

Auth: user access token or platform agent key · Scopes: git:read, git:write

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:numberIssue or pull request number, or under pipelines a run number.

Request body

FieldTypeRequiredDefaultNotes
failedOnlybooleanNofalse
jobstringNoup to 100 characters

Response 200

{
  run: {
    runId: string
    number: number
    attempt: number
    workflowFile: string
    workflowName: string
    event: "push" | "pull_request" | "schedule" | "workflow_dispatch"
    ref: string
    branch: string
    sha: string
    title: string
    actor: {
      id: null | string
      label: null | string
    }
    status: "queued" | "in_progress" | "waiting" | "completed"
    conclusion: null | "success" | "failure" | "skipped" | "cancelled" | "timed_out" | "startup_failure"
    pullNumber: null | number
    cancelRequested: boolean
    waitingForConcurrency: boolean
    problems: null | {
      message: string
      line?: number
      column?: number
    }[]
    createdAt: number
    startedAt: null | number
    completedAt: null | number
  }
}

Errors

StatusMessage
404Repository not found
404Run not found

POST /v1/orgs/:orgId/repos/:name/pipelines/runs/:number/approvals

Approves or rejects the jobs of the current attempt waiting for an environment (its reviewers only).

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:numberIssue or pull request number, or under pipelines a run number.

Request body

FieldTypeRequiredNotes
environmentstringYesmatches ^[A-Za-z0-9 _.-]{1,100}$; trimmed
decision"approve" | "reject"Yes
commentstringNoup to 1,000 characters; trimmed

Response 200

{
  ok: true
}

Errors

StatusMessage
404Repository not found
404Run not found

GET /v1/orgs/:orgId/repos/:name/pipelines/runs/:number/jobs/:jobId

One job of a run: status, runner, environment, steps, annotations, summary and error.

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:numberIssue or pull request number, or under pipelines a run number.
:jobIdJob id: an agent job (job_…), under pipelines a pipeline job (pjb_…), or under crm an import or export (cjb_…); under marketing a list import (mkj_…).

Response 200

{
  run: {
    runId: string
    number: number
    attempt: number
    workflowFile: string
    workflowName: string
    event: "push" | "pull_request" | "schedule" | "workflow_dispatch"
    ref: string
    branch: string
    sha: string
    title: string
    actor: {
      id: null | string
      label: null | string
    }
    status: "queued" | "in_progress" | "waiting" | "completed"
    conclusion: null | "success" | "failure" | "skipped" | "cancelled" | "timed_out" | "startup_failure"
    pullNumber: null | number
    cancelRequested: boolean
    waitingForConcurrency: boolean
    problems: null | {
      message: string
      line?: number
      column?: number
    }[]
    createdAt: number
    startedAt: null | number
    completedAt: null | number
  }
  job: {
    jobId: string
    key: string
    name: string
    matrix: null | {
      [key: string]: unknown
    }
    status: "queued" | "in_progress" | "waiting" | "completed"
    conclusion: null | "success" | "failure" | "skipped" | "cancelled" | "timed_out" | "startup_failure"
    waitingFor: null | "approval" | "timer" | "concurrency" | "capacity" | "runner"
    waitUntil: null | number
    runner: null | {
      kind: "hosted" | "self-hosted"
      label: null | string
      device: null | string
    }
    environment: null | {
      name: string
      url: null | string
    }
    steps: unknown[]
    annotations: unknown[]
    summary: null | string
    error: null | string
    continueOnError: boolean
    reusedFrom: null | number
    minutes: null | number
    queuedAt: null | number
    startedAt: null | number
    completedAt: null | number
    logArchived: boolean
  }
}

Errors

StatusMessage
404Repository not found
404Run not found
404Job not found

GET /v1/orgs/:orgId/repos/:name/pipelines/runs/:number/jobs/:jobId/logs

A page of a job's log after cursor; done when the job finished and everything was read.

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:numberIssue or pull request number, or under pipelines a run number.
:jobIdJob id: an agent job (job_…), under pipelines a pipeline job (pjb_…), or under crm an import or export (cjb_…); under marketing a list import (mkj_…).
Query parameterTypeRequiredNotes
cursorstringNoup to 4,000 characters

Response 200

{
  status: "queued" | "in_progress" | "waiting" | "completed"
  steps: unknown[]
  lines: {
    n: number
    t: number
    s: number
    m: string
  }[]
  cursor: string
  done: boolean
}

Errors

StatusMessage
404Repository not found
404Run not found
404Job not found

GET /v1/orgs/:orgId/repos/:name/pipelines/runs/:number/jobs/:jobId/logs/raw

The whole log as text (up to 5 MB).

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:numberIssue or pull request number, or under pipelines a run number.
:jobIdJob id: an agent job (job_…), under pipelines a pipeline job (pjb_…), or under crm an import or export (cjb_…); under marketing a list import (mkj_…).

Response 200 with no body.

Errors

StatusMessage
404Repository not found
404Run not found
404Job not found

GET /v1/orgs/:orgId/repos/:name/pipelines/runs/:number/artifacts/:artifact

A download link for one of the run's artifacts (15 minutes); attempt picks an earlier attempt's.

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:numberIssue or pull request number, or under pipelines a run number.
:artifactArtifact name, URL-encoded.
Query parameterTypeRequiredNotes
attemptintegerNo≥ 1; coerced from a string

Response 200

{
  url: string
  name: string
  size: number
}

Errors

StatusMessage
404Repository not found
404Run not found
404Artifact not found

DELETE /v1/orgs/:orgId/repos/:name/pipelines/runs/:number/artifacts/:artifact

Deletes an artifact of the run now. Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:numberIssue or pull request number, or under pipelines a run number.
:artifactArtifact name, URL-encoded.
Query parameterTypeRequiredNotes
attemptintegerNo≥ 1; coerced from a string

Response 204 with no body.

Errors

StatusMessage
404Repository not found
404Run not found
404Artifact not found

GET /v1/orgs/:orgId/repos/:name/pipelines/statuses

What the runs of commits add up to (up to 100: ?sha=…&sha=…).

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.

Response 200

{
  statuses: {
    [key: string]: {
      state: "success" | "pending" | "failure" | "waiting" | "cancelled"
      runs: {
        number: number
        workflowFile: string
        workflowName: string
        event: string
        status: string
        conclusion?: string
        attempt: number
        createdAt: number
      }[]
    }
  }
}

Errors

StatusMessage
400At most 100 commits at a time
404Repository not found

GET /v1/orgs/:orgId/repos/:name/pipelines/environments

Environments with their rules, and the names of their secrets and variables.

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.

Response 200

{
  environments: {
    name: string
    reviewers: {
      type: "user" | "team"
      id: string
    }[]
    preventSelfReview: boolean
    waitMinutes: number
    branchPolicy: "all" | "protected" | "selected"
    branchPatterns: string[]
    secrets: {
      name: string
      updatedAt: number
      updatedBy: null | string
    }[]
    variables: {
      name: string
      value: string
      updatedAt: number
    }[]
    updatedAt: number
  }[]
}

Errors

StatusMessage
404Repository not found

PUT /v1/orgs/:orgId/repos/:name/pipelines/environments/:environment

Creates or changes an environment's rules: reviewers (up to 6 people or groups; empty means no approval), preventSelfReview, waitMinutes, branchPolicy (all, protected or selected with branchPatterns). Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:environmentEnvironment name (letters, numbers, spaces, ., -, _; compared without case).

Request body

FieldTypeRequiredDefaultNotes
reviewersobject[]No[]up to 6 items
reviewers[].type"user" | "team"Yes
reviewers[].idstringYes3–64 characters
preventSelfReviewbooleanNofalse
waitMinutesintegerNo00–43200
branchPolicy"all" | "protected" | "selected"No"all"
branchPatternsstring[]No[]up to 50 items; each 1–200 characters, trimmed

Response 200

{
  environment: {
    reviewers: {
      type: "user" | "team"
      id: string
    }[]
    name: string
    createdAt: number
    updatedAt: number
    orgId: string
    repoId: string
    preventSelfReview: boolean
    waitMinutes: number
    branchPolicy: "all" | "protected" | "selected"
    branchPatterns: string[]
  }
}

Errors

StatusMessage
400At most 100 environments
400… … isn't in this organization
404Repository not found

DELETE /v1/orgs/:orgId/repos/:name/pipelines/environments/:environment

Removes an environment with its secrets and variables. Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:environmentEnvironment name (letters, numbers, spaces, ., -, _; compared without case).

Response 204 with no body.

Errors

StatusMessage
404Repository not found
404Environment not found

PUT /v1/orgs/:orgId/repos/:name/pipelines/environments/:environment/secrets/:secret

Sets an environment secret (value, at most the platform's size). Only that environment's jobs get it, after its rules pass. Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:environmentEnvironment name (letters, numbers, spaces, ., -, _; compared without case).
:secretSecret name (letters, numbers and _; stored upper case).

Request body

FieldTypeRequiredNotes
valuestringYes1–200,000 characters

Response 200

{
  name: string
}

Errors

StatusMessage
400At most … secrets here
404Repository not found
404Environment not found
413Secrets are at most … KB

DELETE /v1/orgs/:orgId/repos/:name/pipelines/environments/:environment/secrets/:secret

Removes an environment secret. Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:environmentEnvironment name (letters, numbers, spaces, ., -, _; compared without case).
:secretSecret name (letters, numbers and _; stored upper case).

Response 204 with no body.

Errors

StatusMessage
404Repository not found

PUT /v1/orgs/:orgId/repos/:name/pipelines/environments/:environment/variables/:variable

Sets an environment variable (value). Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:environmentEnvironment name (letters, numbers, spaces, ., -, _; compared without case).
:variableVariable name (letters, numbers and _; stored upper case).

Request body

FieldTypeRequiredNotes
valuestringYesup to 48,000 characters

Response 200

{
  name: string
}

Errors

StatusMessage
404Repository not found
404Environment not found

DELETE /v1/orgs/:orgId/repos/:name/pipelines/environments/:environment/variables/:variable

Removes an environment variable. Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:environmentEnvironment name (letters, numbers, spaces, ., -, _; compared without case).
:variableVariable name (letters, numbers and _; stored upper case).

Response 204 with no body.

Errors

StatusMessage
404Repository not found

GET /v1/orgs/:orgId/repos/:name/pipelines/secrets

Secret names (never values): the repository's, and the org's visible to it. Needs git:write.

Auth: user access token or platform agent key · Scopes: git:read, git:write

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.

Response 200

{
  secrets: {
    name: string
    updatedAt: number
    updatedBy: null | string
  }[]
  organization: {
    name: string
    updatedAt: number
  }[]
}

Errors

StatusMessage
404Repository not found

PUT /v1/orgs/:orgId/repos/:name/pipelines/secrets/:secret

Sets a repository secret (value): KMS-encrypted, never returned, handed only to running jobs. Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:secretSecret name (letters, numbers and _; stored upper case).

Request body

FieldTypeRequiredNotes
valuestringYes1–200,000 characters

Response 200

{
  name: string
}

Errors

StatusMessage
400At most … secrets here
404Repository not found
413Secrets are at most … KB

DELETE /v1/orgs/:orgId/repos/:name/pipelines/secrets/:secret

Removes a repository secret. Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:secretSecret name (letters, numbers and _; stored upper case).

Response 204 with no body.

Errors

StatusMessage
404Repository not found

GET /v1/orgs/:orgId/repos/:name/pipelines/variables

Variables (values are visible): the repository's and the org's visible to it.

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.

Response 200

{
  variables: {
    name: string
    value: string
    updatedAt: number
  }[]
  organization: {
    name: string
    value: string
    updatedAt: number
  }[]
}

Errors

StatusMessage
404Repository not found

PUT /v1/orgs/:orgId/repos/:name/pipelines/variables/:variable

Sets a repository variable (value, readable in vars). Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:variableVariable name (letters, numbers and _; stored upper case).

Request body

FieldTypeRequiredNotes
valuestringYesup to 48,000 characters

Response 200

{
  name: string
}

Errors

StatusMessage
404Repository not found

DELETE /v1/orgs/:orgId/repos/:name/pipelines/variables/:variable

Removes a repository variable. Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
:variableVariable name (letters, numbers and _; stored upper case).

Response 204 with no body.

Errors

StatusMessage
404Repository not found

GET /v1/orgs/:orgId/repos/:name/pipelines/caches

The repository's caches: key, ref, size and when each was last used.

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.

Response 200

{
  caches: {
    key: string
    ref: string
    size: number
    version: string
    createdAt: number
    lastUsedAt: number
  }[]
  bytes: number
}

Errors

StatusMessage
404Repository not found

DELETE /v1/orgs/:orgId/repos/:name/pipelines/caches

Removes caches: one key (on one ref, or every ref), or all of them.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:nameRepository name.
Query parameterTypeRequiredNotes
keystringNoup to 512 characters
refstringNoup to 255 characters

Response 200

{
  removed: number
}

Errors

StatusMessage
404Repository not found

GET /v1/orgs/:orgId/pipelines/secrets

Org secret names and which repositories see them (never values).

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).

Response 200

{
  secrets: {
    name: string
    visibility: "all" | "selected"
    repoIds: string[]
    updatedAt: number
    updatedBy: null | string
  }[]
}

PUT /v1/orgs/:orgId/pipelines/secrets/:secret

Sets an organization secret: value (required for a new one), and visibility (all repositories, or selected with repoIds). Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:secretSecret name (letters, numbers and _; stored upper case).

Request body

FieldTypeRequiredDefaultNotes
visibility"all" | "selected"No"all"
repoIdsstring[]No[]up to 500 items; each 3–64 characters
valuestringNo1–200,000 characters

Response 200

{
  name: string
}

Errors

StatusMessage
400Not repositories of this organization: …
400A new secret needs a value
400At most … organization secrets
413Secrets are at most … KB

DELETE /v1/orgs/:orgId/pipelines/secrets/:secret

Removes an organization secret. Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:secretSecret name (letters, numbers and _; stored upper case).

Response 204 with no body.

GET /v1/orgs/:orgId/pipelines/variables

Organization variables with their values and which repositories see them.

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).

Response 200

{
  variables: {
    name: string
    value: string
    visibility: "all" | "selected"
    repoIds: string[]
    updatedAt: number
  }[]
}

PUT /v1/orgs/:orgId/pipelines/variables/:variable

Sets an organization variable: value, visibility and repoIds as for secrets. Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:variableVariable name (letters, numbers and _; stored upper case).

Request body

FieldTypeRequiredDefaultNotes
visibility"all" | "selected"No"all"
repoIdsstring[]No[]up to 500 items; each 3–64 characters
valuestringYesup to 48,000 characters

Response 200

{
  name: string
}

Errors

StatusMessage
400Not repositories of this organization: …

DELETE /v1/orgs/:orgId/pipelines/variables/:variable

Removes an organization variable. Needs git:admin.

Auth: user access token or platform agent key · Scopes: git:read, git:admin

Path parameterDescription
:orgIdOrganization id (org_…).
:variableVariable name (letters, numbers and _; stored upper case).

Response 204 with no body.

GET /v1/orgs/:orgId/pipelines/usage

Minutes this month (or month=2026-10) against the plan, by runner type.

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).
Query parameterTypeRequiredNotes
monthstringNomatches ^\d{4}-\d{2}$

Response 200

{
  usage: {
    month: string
    minutes: number
    billedMinutes: number
    selfHostedMinutes: number
    jobs: number
    byRunner: {
      runner: string
      selfHosted: boolean
      minutes: number
      billedMinutes: number
      jobs: number
    }[]
  }
  limits: {
    minutes: number
    overage: boolean
    concurrency: number
    maxMinutes: number
    logDays: number
    artifactDays: number
    artifactGb: number
    cacheGb: number
  }
  running: number
  artifactBytes: number
}

GET /v1/orgs/:orgId/pipelines/runners

Hosted runner types the org can use, and its self-hosted runners (devices approved for pipelines).

Auth: user access token or platform agent key · Scope: git:read

Path parameterDescription
:orgIdOrganization id (org_…).

Response 200

{
  hosted: {
    label: string
    description: string
    multiplier: number
    maxMinutes: number
    docker: boolean
    isDefault: boolean
  }[]
  selfHosted: {
    deviceId: string
    name: string
    platform: null | string
    labels: string[]
    customLabels: string[]
    networkMode?: "allowlist" | "full"
    online: boolean
    lastSeenAt: null | number
  }[]
}

PUT /v1/orgs/:orgId/pipelines/runners/:deviceId/labels

A self-hosted runner's own labels (runs-on: [self-hosted, <label>]).

Auth: user access token or platform agent key · Scopes: git:read, agents:write

Path parameterDescription
:orgIdOrganization id (org_…).
:deviceIdDevice id: an agent's (dev_…); under /v1/me/notifications a phone's install id; under /v1/me/sign-in-approvals a phone that approves sign-ins (apd_…); under /v1/me/vault the id a device made for its vault (22 base64url characters).

Request body

FieldTypeRequiredNotes
labelsstring[]Yesup to 20 items; each matches ^[a-z0-9][a-z0-9._-]{0,49}$, trimmed, lowercased

Response 200

{
  labels: string[]
}

Errors

StatusMessage
404Runner not found