NewDebug failed jobs and retry from any step.

Operate CI through an API.

Submit a run, stream events, inspect each step, pause failures, retry from any step and publish a signed record. Programs use the same authenticated operations as the dashboard.

LOOP04beats
01Changesnapshot
02Verifyreplay
03Fixpause
04Mergepublish
Submit a run, stream its state, inspect it, retry it, and sign the result.

The API reference is written for the agent calling it

Every operation the dashboard performs is an API call, and an agent can make all of them. Each route documents the scope it requires, the request shape, and the response it returns — written to be consumed by the program calling it, not just read by a person.

A generated OpenAPI document describes the full surface, so an agent can enumerate routes, generate a client, or validate its calls before it makes them. The API is plain HTTP with JSON and NDJSON; no SDK or client library is required.

Calls that take time return before they finish, so an agent streams progress instead of holding a connection. Reads that return a decision also return its reason, so the caller can act on the result without parsing a log.

The API surface

All paths are relative to https://app.preloop.dev. Every call uses a bearer credential.

OperationMethod and pathReturns
SubmitPOST /api/v1/runsAccepted, with a run id and the resolved plan
List runsGET /api/v1/runs?limit=&status=Runs, newest first
Read a runGET /api/v1/runs/{run_id}Status, jobs, steps, conclusions
EventsGET /api/v1/runs/{run_id}/events.ndjsonNDJSON, one event per line
LogsGET /api/v1/runs/{run_id}/logs?job=The stored log for a job
Live logsGET /api/v1/runs/{run_id}/logs/live?job=Server-sent events
CancelPOST /api/v1/runs/{run_id}/cancelCancellation result
RerunPOST /api/v1/runs/{run_id}/rerunAccepted
ApprovePOST /api/v1/runs/{run_id}/jobs/{job_id}/approveEnvironment gate result
Approve a forkPOST /api/v1/runs/{run_id}/approve-forkFork hold released
Debug sessionsGET /api/v1/debug/sessionsPaused and attached sessions
Session detailGET /api/v1/debug/sessions/{session_id}State, lease holder, history
VerdictPOST /api/v1/debug/sessions/{session_id}/verdictIssues retry, continue or abort
Verdict pollGET /api/v1/debug/sessions/{session_id}/verdictWorker view; null on timeout, which is not an abort
ClosePOST /api/v1/debug/sessions/{session_id}/closeSession closed
Session auditGET /api/v1/debug/sessions/{session_id}/auditEvery mutating operation
DebuggerGET /api/v1/runs/{run_id}/debugWebSocket upgrade for the debug adapter
TestsGET /api/v1/tests, /impact, /flaky, /savingsSelection and outcome data
Test detailGET /api/v1/tests/{key}/explainThe decision, with its evidence
Step reuseGET /api/v1/runs/{run}/steps/{step}/reuseReuse decision for one step
RecordsGET /api/v1/attestationsReceipts, newest first, keyset paging
Record detailGET /api/v1/attestations/{id}Record, envelope, keys, publication state
PublishPOST /api/v1/attestationsSubmit a record from elsewhere

Expensive operations return before they finish, so callers can stream progress instead of holding a connection open. Reads that return a decision also return its reason, so an agent can act on the result without parsing a log.

Stream state instead of polling.

Beforebash
bashbash
while :; do
  status=$(gh api "repos/$REPO/actions/runs" \
    --jq '.workflow_runs[0].status')
  [ "$status" = "completed" ] && break
  sleep 20
done

gh run view --log-failed | head -40
# parse the log to find which step failed

Polling and log parsing.

Afterbash
bashbash
# stream the job instead of asking about it
plp ci logs "$RUN" --job test -f

# machine-readable state, including every skip reason
plp ci status "$RUN" --json

# attach to the paused job and retry the failed step
plp ci debug "$RUN" --from 6

Streaming, structured state and retry.

Credentials an agent carries

CredentialScope
Human loginDevice code flow (RFC 8628). No password ever reaches the CLI.
Agent loginFederated OIDC, or a signed single-use assertion (RFC 7523) with a one-time jti.
Agent exec tokenThe intersection of the user's grants, the agent's ceiling and the scopes requested, never wider than any of the three. TTL at most 15 minutes.
Task grantsBind one named action to one live run or job, issued for a single task rather than standing access.
ci-agent roleRuns and debugs its own jobs, and reads. No secrets, no OIDC token, no publishing and no approvals.
Human-only gatesEnvironment and fork approvals, agent administration, policy and secret administration stay with a person.

Useful control with clear limits.

An agent can inspect and repair a run, while scopes and human-only gates limit which changes it can make. The boundary is enforced by the token, not by convention.

  1. 01

    An agent cannot trigger a run on the default branch.

  2. 02

    Agent-authored pull requests open as drafts.

  3. 03

    A fix needs a clean verification before merge.

  4. 04

    Secret access during a debug session is disabled by default.

  5. 05

    One writer per session. Other controllers read state and audit history; mutations are recorded.

LOOP04beats
01Changesnapshot
02Verifyreplay
03Fixpause
04Mergepublish
An agent submits a run, streams its state, attaches when it pauses, retries the fix, and opens a draft pull request.

Agent questions

Q.01Does the API match the dashboard?

Yes. The dashboard uses the same authenticated API. There are no operations that require the UI when the credential has the required scope.

Q.02How does an agent learn that a job paused?

A paused session appears in GET /api/v1/debug/sessions and in the run's event stream. An agent can subscribe to the event instead of polling a log.

Q.03What happens if two agents attach?

One gets the writer lease. The other attaches read-only and can still read state and audit history. Concurrent mutations are refused rather than raced.

Q.04Can an agent read secrets?

Not with the ci-agent role. Its token excludes secrets, OIDC tokens, publishing and approvals entirely. Reading a secret during a debug session needs a human-held credential.

Q.05Is there an SDK?

The API is plain HTTP with JSON and NDJSON, and the CLI adds --json to every read command. Use the interface that fits your runtime; no specific client library is required.

Q.06Can an agent use the CLI instead of the API?

plp ci is a thin client over the same hosted API. Set PRELOOP_TOKEN for unattended use, or log in with a device code.

Q.07Can I retry from any step?

Yes. A retry can start from any requested step, including the failed step. The selected start point and the session history remain visible to the caller.

Start with submit and stream.

Use the API to submit a run and stream its state. Add pause, retry and attestation when the workflow needs them.