---
title: "ci"
description: "CI on one model for every service:\na **service** (`buildkite` today), a **connection** (one account of it:\na Buildkite organization), its **pipelines** (each builds one repo),\n**builds**, **jobs**, and each job's **check**. Pando runs no CI.\n\n- **Stored by Pando, pushed by the service.** A connection gets a\n  webhook URL; the service's webhooks keep builds and jobs (state,\n  times, links) in the monorepo's records, written in one step with\n  their events on the monorepo's stream (`ci.build`, `ci.job`) before\n  the webhook is answered. Viewers cost the service nothing.\n- **A check is a job named by its step key**: a job keyed `ci` writes\n  the status `ci` (`app` `buildkite`, `creator` `app:buildkite`), so\n  `required_checks = [\"ci\"]` in `.pando/pando.toml` gates merges on it.\n  Commands and triggered builds report; waits and blocks do not. Only\n  the newest job with that key, in the newest build of that pipeline\n  for that commit, reports (a retry or a rebuild takes over). States:\n  passed is success; failed is failure (soft failed: success);\n  canceled, not run after a failure (`broken`) or not taken by an\n  agent (`expired`) are error; a skipped step is success.\n- **Fetched from the service when opened**: a job's log (its last\n  1 MiB), a build's annotations and artifacts (first 100 of each), a\n  pipeline's configuration (read at most every 5 minutes). Cached once\n  settled (finished over 30 s ago), else for 10 s.\n- **Actions**, any member: Rebuild (a new build of the same commit\n  with fresh tokens; the service's own rebuild would reuse the old\n  build's env), Cancel and Retry (passed through).\n- **Mapping a build to a repo**: Pando's own builds carry\n  `meta_data.pando_delivery`, `pando_monorepo` and `pando_repo`; a\n  build started in the service maps through the buildkite hook that\n  names its pipeline. Other builds (another monorepo's, another\n  organization's, an unmapped pipeline's) are answered 200 and ignored.\n- **Who pushed** comes from Pando's own records: the delivery that\n  started the build, else the push or merge that made the commit.\n- **The service's rate limit**: Buildkite allows 200 REST calls a\n  minute per organization and 50 per user token. A connection makes at\n  most 40 a minute (10 are left for starting builds); past that, or\n  after Buildkite answers 429, calls answer 429 `ci_rate_limited`\n  (\"try again in N s\", with `retry_after_ms`). A reader of a log,\n  annotations or artifacts gets the last copy instead, when there is\n  one: 200 with `cached: true`, `complete: false` and\n  `retry_after_ms`. pipeline.yml shows its stored copy with\n  `configuration_error`. Never a 5xx for the hold.\n\nErrors from the service: `ci_unauthorized` (502: the token lacks a\nscope), `ci_refused` (409: Buildkite refused the action),\n`ci_service` (502), `ci_rate_limited` (429), `ci_token_missing` (503:\nthe Worker secret BUILDKITE_API_TOKEN is not set).\n"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.gitpando.com/llms.txt
> Use this file to discover all available pages before exploring further.

Path: Pando API

CI on one model for every service:
a **service** (`buildkite` today), a **connection** (one account of it:
a Buildkite organization), its **pipelines** (each builds one repo),
**builds**, **jobs**, and each job's **check**. Pando runs no CI.

- **Stored by Pando, pushed by the service.** A connection gets a
  webhook URL; the service's webhooks keep builds and jobs (state,
  times, links) in the monorepo's records, written in one step with
  their events on the monorepo's stream (`ci.build`, `ci.job`) before
  the webhook is answered. Viewers cost the service nothing.
- **A check is a job named by its step key**: a job keyed `ci` writes
  the status `ci` (`app` `buildkite`, `creator` `app:buildkite`), so
  `required_checks = ["ci"]` in `.pando/pando.toml` gates merges on it.
  Commands and triggered builds report; waits and blocks do not. Only
  the newest job with that key, in the newest build of that pipeline
  for that commit, reports (a retry or a rebuild takes over). States:
  passed is success; failed is failure (soft failed: success);
  canceled, not run after a failure (`broken`) or not taken by an
  agent (`expired`) are error; a skipped step is success.
- **Fetched from the service when opened**: a job's log (its last
  1 MiB), a build's annotations and artifacts (first 100 of each), a
  pipeline's configuration (read at most every 5 minutes). Cached once
  settled (finished over 30 s ago), else for 10 s.
- **Actions**, any member: Rebuild (a new build of the same commit
  with fresh tokens; the service's own rebuild would reuse the old
  build's env), Cancel and Retry (passed through).
- **Mapping a build to a repo**: Pando's own builds carry
  `meta_data.pando_delivery`, `pando_monorepo` and `pando_repo`; a
  build started in the service maps through the buildkite hook that
  names its pipeline. Other builds (another monorepo's, another
  organization's, an unmapped pipeline's) are answered 200 and ignored.
- **Who pushed** comes from Pando's own records: the delivery that
  started the build, else the push or merge that made the commit.
- **The service's rate limit**: Buildkite allows 200 REST calls a
  minute per organization and 50 per user token. A connection makes at
  most 40 a minute (10 are left for starting builds); past that, or
  after Buildkite answers 429, calls answer 429 `ci_rate_limited`
  ("try again in N s", with `retry_after_ms`). A reader of a log,
  annotations or artifacts gets the last copy instead, when there is
  one: 200 with `cached: true`, `complete: false` and
  `retry_after_ms`. pipeline.yml shows its stored copy with
  `configuration_error`. Never a 5xx for the hold.

Errors from the service: `ci_unauthorized` (502: the token lacks a
scope), `ci_refused` (409: Buildkite refused the action),
`ci_service` (502), `ci_rate_limited` (429), `ci_token_missing` (503:
the Worker secret BUILDKITE_API_TOKEN is not set).

## Operations

- [The CI tab's top - services, connections, pipelines, required checks](/api/ci/getCi/)
- [Connect a CI service (owners)](/api/ci/createCiConnection/)
- [Disconnect a CI service (owners)](/api/ci/deleteCiConnection/)
- [Stored builds, newest first](/api/ci/listCiBuilds/)
- [A build and its jobs](/api/ci/getCiBuild/)
- [A job's log, from the service (its last 1 MiB)](/api/ci/getCiJobLog/)
- [A build's annotations, from the service (first 100)](/api/ci/listCiAnnotations/)
- [A build's artifacts, from the service (first 100)](/api/ci/listCiArtifacts/)
- [Download an artifact of this build](/api/ci/downloadCiArtifact/)
- [Build the same commit again, with fresh tokens](/api/ci/rebuildCiBuild/)
- [Cancel a running build (passed through)](/api/ci/cancelCiBuild/)
- [Retry a job (passed through)](/api/ci/retryCiJob/)
- [A pipeline - its configuration (pipeline.yml) and its builds](/api/ci/getCiPipeline/)
- [New build - the pipeline builds a branch's head as Pando has it](/api/ci/startCiBuild/)
- [Buildkite's webhooks (the URL a connection shows)](/api/ci/buildkiteWebhook/)


Source: https://docs.gitpando.com/api/tags/ci/index.md
