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
| Field | Type | Required | Notes |
|---|---|---|---|
ref | string | No | up 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
| Field | Type | Required | Notes |
|---|---|---|---|
steps | object[] | Yes | up to 1,100 items |
steps[].index | integer | Yes | 0–5000 |
steps[].name | string | Yes | up 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[].startedAt | number | No | |
steps[].completedAt | number | No | |
steps[].post | boolean | No |
Response 200
{
cancel: boolean
}POST /v1/runner/complete
The job's result.
Auth: none
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
conclusion | "success" | "failure" | "cancelled" | Yes | ||
steps | object[] | No | [] | up to 1,100 items |
steps[].index | integer | Yes | 0–5000 | |
steps[].name | string | Yes | up 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[].startedAt | number | No | ||
steps[].completedAt | number | No | ||
steps[].post | boolean | No | ||
outputs | object | No | {} | values: string (up to 65,536 characters) |
annotations | object[] | No | [] | up to 50 items |
annotations[].level | "error" | "warning" | "notice" | Yes | ||
annotations[].message | string | Yes | up to 4,000 characters | |
annotations[].file | string | No | up to 500 characters | |
annotations[].line | integer | No | ||
annotations[].title | string | No | up to 200 characters | |
annotations[].step | integer | No | ||
summary | string | No | up to 65,536 characters | |
error | string | No | up to 2,000 characters | |
timedOut | boolean | No |
Response 200
{
ok: true
}POST /v1/runner/logs
Self-hosted runners' output, in batches of timestamped lines.
Auth: none
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
lines | object[] | Yes | up to 20,000 items |
lines[].t | number | Yes | |
lines[].m | string | Yes | up 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
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
key | string | Yes | 1–512 characters | |
restoreKeys | string[] | No | [] | up to 10 items; each 1–512 characters |
version | string | Yes | matches ^[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
| Field | Type | Required | Notes |
|---|---|---|---|
key | string | Yes | 1–512 characters |
version | string | Yes | matches ^[0-9a-f]{64}$ |
size | integer | Yes | ≥ 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
| Field | Type | Required | Notes |
|---|---|---|---|
key | string | Yes | 1–512 characters |
version | string | Yes | matches ^[0-9a-f]{64}$ |
size | integer | No | ≥ 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
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | matches ^[^\\/:*?"<>|\r\n]{1,100}$ |
size | integer | Yes | ≥ 1 |
files | integer | Yes | ≥ 0 |
retentionDays | integer | No | 1–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
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | matches ^[^\\/:*?"<>|\r\n]{1,100}$ |
size | integer | No | |
files | integer | No |
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
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | No | matches ^[^\\/:*?"<>|\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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
| Query parameter | Type | Required | Notes |
|---|---|---|---|
ref | string | No | 1–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
| Status | Message |
|---|---|
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:file | Workflow file name in .cactive/workflows, e.g. ci.yml. |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
enabled | boolean | Yes |
Response 200
{
file: string
disabled: boolean
}Errors
| Status | Message |
|---|---|
404 | Repository not found |
404 | Workflow 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:file | Workflow file name in .cactive/workflows, e.g. ci.yml. |
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
ref | string | Yes | 1–255 characters; trimmed | |
inputs | object | No | {} | 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
| Status | Message |
|---|---|
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
| Query parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
workflow | string | No | up to 100 characters | |
branch | string | No | up to 255 characters | |
status | "queued" | "in_progress" | "waiting" | "completed" | "success" | "failure" | "cancelled" | "startup_failure" | No | ||
actor | string | No | up to 64 characters | |
event | "push" | "pull_request" | "schedule" | "workflow_dispatch" | No | ||
sha | string | No | matches ^[0-9a-f]{40}$ | |
cursor | string | No | up to 2,000 characters | |
limit | integer | No | 25 | 1–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
| Status | Message |
|---|---|
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:number | Issue or pull request number, or under pipelines a run number. |
| Query parameter | Type | Required | Notes |
|---|---|---|---|
attempt | integer | No | ≥ 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
| Status | Message |
|---|---|
404 | Repository not found |
404 | Run 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:number | Issue 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
| Status | Message |
|---|---|
404 | Repository not found |
404 | Run not found |
409 | This 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:number | Issue or pull request number, or under pipelines a run number. |
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
failedOnly | boolean | No | false | |
job | string | No | up 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
| Status | Message |
|---|---|
404 | Repository not found |
404 | Run 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:number | Issue or pull request number, or under pipelines a run number. |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
environment | string | Yes | matches ^[A-Za-z0-9 _.-]{1,100}$; trimmed |
decision | "approve" | "reject" | Yes | |
comment | string | No | up to 1,000 characters; trimmed |
Response 200
{
ok: true
}Errors
| Status | Message |
|---|---|
404 | Repository not found |
404 | Run 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:number | Issue or pull request number, or under pipelines a run number. |
:jobId | Job 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
| Status | Message |
|---|---|
404 | Repository not found |
404 | Run not found |
404 | Job 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:number | Issue or pull request number, or under pipelines a run number. |
:jobId | Job 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 parameter | Type | Required | Notes |
|---|---|---|---|
cursor | string | No | up 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
| Status | Message |
|---|---|
404 | Repository not found |
404 | Run not found |
404 | Job 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:number | Issue or pull request number, or under pipelines a run number. |
:jobId | Job 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
| Status | Message |
|---|---|
404 | Repository not found |
404 | Run not found |
404 | Job 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:number | Issue or pull request number, or under pipelines a run number. |
:artifact | Artifact name, URL-encoded. |
| Query parameter | Type | Required | Notes |
|---|---|---|---|
attempt | integer | No | ≥ 1; coerced from a string |
Response 200
{
url: string
name: string
size: number
}Errors
| Status | Message |
|---|---|
404 | Repository not found |
404 | Run not found |
404 | Artifact 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:number | Issue or pull request number, or under pipelines a run number. |
:artifact | Artifact name, URL-encoded. |
| Query parameter | Type | Required | Notes |
|---|---|---|---|
attempt | integer | No | ≥ 1; coerced from a string |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
404 | Repository not found |
404 | Run not found |
404 | Artifact 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository 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
| Status | Message |
|---|---|
400 | At most 100 commits at a time |
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository 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
| Status | Message |
|---|---|
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:environment | Environment name (letters, numbers, spaces, ., -, _; compared without case). |
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
reviewers | object[] | No | [] | up to 6 items |
reviewers[].type | "user" | "team" | Yes | ||
reviewers[].id | string | Yes | 3–64 characters | |
preventSelfReview | boolean | No | false | |
waitMinutes | integer | No | 0 | 0–43200 |
branchPolicy | "all" | "protected" | "selected" | No | "all" | |
branchPatterns | string[] | 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
| Status | Message |
|---|---|
400 | At most 100 environments |
400 | … … isn't in this organization |
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:environment | Environment name (letters, numbers, spaces, ., -, _; compared without case). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
404 | Repository not found |
404 | Environment 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:environment | Environment name (letters, numbers, spaces, ., -, _; compared without case). |
:secret | Secret name (letters, numbers and _; stored upper case). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
value | string | Yes | 1–200,000 characters |
Response 200
{
name: string
}Errors
| Status | Message |
|---|---|
400 | At most … secrets here |
404 | Repository not found |
404 | Environment not found |
413 | Secrets 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:environment | Environment name (letters, numbers, spaces, ., -, _; compared without case). |
:secret | Secret name (letters, numbers and _; stored upper case). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:environment | Environment name (letters, numbers, spaces, ., -, _; compared without case). |
:variable | Variable name (letters, numbers and _; stored upper case). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
value | string | Yes | up to 48,000 characters |
Response 200
{
name: string
}Errors
| Status | Message |
|---|---|
404 | Repository not found |
404 | Environment 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:environment | Environment name (letters, numbers, spaces, ., -, _; compared without case). |
:variable | Variable name (letters, numbers and _; stored upper case). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
Response 200
{
secrets: {
name: string
updatedAt: number
updatedBy: null | string
}[]
organization: {
name: string
updatedAt: number
}[]
}Errors
| Status | Message |
|---|---|
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:secret | Secret name (letters, numbers and _; stored upper case). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
value | string | Yes | 1–200,000 characters |
Response 200
{
name: string
}Errors
| Status | Message |
|---|---|
400 | At most … secrets here |
404 | Repository not found |
413 | Secrets 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:secret | Secret name (letters, numbers and _; stored upper case). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
Response 200
{
variables: {
name: string
value: string
updatedAt: number
}[]
organization: {
name: string
value: string
updatedAt: number
}[]
}Errors
| Status | Message |
|---|---|
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:variable | Variable name (letters, numbers and _; stored upper case). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
value | string | Yes | up to 48,000 characters |
Response 200
{
name: string
}Errors
| Status | Message |
|---|---|
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
:variable | Variable name (letters, numbers and _; stored upper case). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
Response 200
{
caches: {
key: string
ref: string
size: number
version: string
createdAt: number
lastUsedAt: number
}[]
bytes: number
}Errors
| Status | Message |
|---|---|
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:name | Repository name. |
| Query parameter | Type | Required | Notes |
|---|---|---|---|
key | string | No | up to 512 characters |
ref | string | No | up to 255 characters |
Response 200
{
removed: number
}Errors
| Status | Message |
|---|---|
404 | Repository 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 parameter | Description |
|---|---|
:orgId | Organization 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:secret | Secret name (letters, numbers and _; stored upper case). |
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
visibility | "all" | "selected" | No | "all" | |
repoIds | string[] | No | [] | up to 500 items; each 3–64 characters |
value | string | No | 1–200,000 characters |
Response 200
{
name: string
}Errors
| Status | Message |
|---|---|
400 | Not repositories of this organization: … |
400 | A new secret needs a value |
400 | At most … organization secrets |
413 | Secrets 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:secret | Secret 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 parameter | Description |
|---|---|
:orgId | Organization 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:variable | Variable name (letters, numbers and _; stored upper case). |
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
visibility | "all" | "selected" | No | "all" | |
repoIds | string[] | No | [] | up to 500 items; each 3–64 characters |
value | string | Yes | up to 48,000 characters |
Response 200
{
name: string
}Errors
| Status | Message |
|---|---|
400 | Not 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:variable | Variable 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
| Query parameter | Type | Required | Notes |
|---|---|---|---|
month | string | No | matches ^\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 parameter | Description |
|---|---|
:orgId | Organization 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 parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:deviceId | Device 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
| Field | Type | Required | Notes |
|---|---|---|---|
labels | string[] | Yes | up to 20 items; each matches ^[a-z0-9][a-z0-9._-]{0,49}$, trimmed, lowercased |
Response 200
{
labels: string[]
}Errors
| Status | Message |
|---|---|
404 | Runner not found |