API Reference

REST API reference for the CI Sizer collector and receiver.

Overview

All endpoints are under /api/v1 unless noted otherwise. The OpenAPI specification is auto-generated and served live at /swagger on the receiver. The spec file is also available at docs/openapi.json in the repository.

Authentication

CI Sizer uses a two-tier token system:

  • Read token (--read-token): Pre-shared admin credential for read/query endpoints. Used as Authorization: Bearer <read-token>.
  • Push tokens (derived from --hmac-key): Scoped, time-limited HMAC-SHA256 tokens for collectors. Generated via POST /api/v1/token.

Authentication behaviour depends on the configured auth mode. See Configuration — Authentication Modes for details.

Authentication by Endpoint (OIDC Mode)

In oidc mode, endpoints use two tiers. The relaxed tier also accepts a Bearer read token, enabling programmatic access (e.g., from the GARM provider).

EndpointAuth TierOIDC SessionBearer Read Token
GET /healthNone
POST /api/v1/tokenRead tokenYes
POST /api/v1/metricsPush token
GET /api/v1/sizing/*RelaxedYesYes
GET /api/v1/runners/overviewRelaxedYesYes
GET /api/v1/runners/{runner}RelaxedYesYes
All other protected endpointsStrictYesNo

In gateway mode, replace “OIDC Session” with “Gateway JWT (X-Access-Token)”. In none mode, all protected endpoints accept the Bearer read token.

Health and Info

No authentication required.

MethodPathDescription
GET/healthHealth check
GET/api/v1/infoService info (version, auth mode, CI provider, forgejo_base_url, logout_url)

Token and Metrics Ingest

MethodPathAuthDescription
POST/api/v1/tokenRead tokenGenerate a scoped push token
POST/api/v1/metricsPush tokenReceive and store a metric summary

Push Token Generation

curl -s -X POST http://localhost:8080/api/v1/token \
  -H "Authorization: Bearer <read-token>" \
  -H "Content-Type: application/json" \
  -d '{"organization":"my-org","repository":"my-repo","workflow":"ci.yml","job":"build"}'

The returned token is scoped to the specified org/repo/workflow/job combination and expires after the configured --token-ttl (default: 2 hours).

Metrics Query

MethodPathDescription
GET/api/v1/metrics/repo/{org}/{repo}/{workflow}/{job}Query stored metrics for a workflow/job
GET/api/v1/metrics/runner/{runner}Query stored metrics for a specific runner
GET/api/v1/debug/metricsDump all metric rows from the database

Metrics Response Example

[
  {
    "id": 1,
    "organization": "my-org",
    "repository": "my-org/my-repo",
    "workflow": "ci.yml",
    "job": "build",
    "run_id": "run-123",
    "received_at": "2026-02-06T14:30:23.056Z",
    "payload": {
      "start_time": "2026-02-06T14:30:02.185Z",
      "end_time": "2026-02-06T14:30:22.190Z",
      "duration_seconds": 20.0,
      "sample_count": 11,
      "containers": [
        {
          "name": "runner",
          "cpu_cores": { "peak": 2.007, "avg": 1.5, "p50": 1.817, "p95": 2.004 },
          "memory_bytes": { "peak": 18567168, "avg": 18567168 }
        }
      ]
    }
  }
]

CPU metric distinction:

  • cpu_total_percent — system-wide, 0–100%
  • cpu_cores (containers) — cores used (e.g., 2.0 = two full cores)
  • peak_cpu_percent (processes) — per-process, where 100% = 1 core

All memory values are in bytes.

Sizing

MethodPathDescription
GET/api/v1/sizing/repo/{org}/{repo}/{workflow}/{job}Compute container sizes from historical data

Query Parameters

ParameterDefaultDescription
runs5Number of recent runs to analyse (1–100)
buffer20CPU headroom percentage (memory uses a staircase buffer)
cpu_percentilep95CPU stat to use: peak, p99, p95, p75, p50, avg

Sizing Response Example

{
  "containers": [
    {
      "name": "runner",
      "cpu":    { "request": "960m", "limit": "1", "enforced": false },
      "memory": { "request": "1024Mi", "limit": "1024Mi", "enforced": true }
    }
  ],
  "total": {
    "cpu":    { "request": "970m", "limit": "1500m" },
    "memory": { "request": "647Mi", "limit": "1024Mi" }
  },
  "meta": {
    "runs_analyzed": 10,
    "buffer_percent": 20,
    "cpu_percentile": "p95",
    "cpu_sizing_mode": "observe",
    "memory_qos": "guaranteed"
  }
}

For details on the sizing algorithm, buffers, and enforcement modes, see Sizing Algorithm.

Energy and Carbon

MethodPathDescription
GET/api/v1/energy/repo/{org}/{repo}/{workflow}/{job}Energy/carbon estimates for a workflow/job

Supports ?from= and ?to= time range filters (ISO 8601).

Aggregation and Dashboard

All aggregation endpoints support ?from=, ?to= (ISO 8601) and ?limit= / ?offset= pagination.

MethodPathDescription
GET/api/v1/metrics/overviewGlobal KPI summary with per-org breakdown
GET/api/v1/metrics/org/{org}Org detail with per-repo summaries
GET/api/v1/metrics/org/{org}/repo/{repo}Repo detail with per-workflow summaries
GET/api/v1/sizing/org/{org}Org-wide sizing overview
GET/api/v1/sizing/org/{org}/repo/{repo}Repo-wide sizing overview
GET/api/v1/compare/reposCross-repo KPI comparison (?org=)
GET/api/v1/compare/workflowsCross-workflow KPI comparison (?org=&repo=)
GET/api/v1/runnersList known runners
GET/api/v1/runners/overviewRunner fleet overview
GET/api/v1/runners/{runner}Runner detail with per-org breakdown
GET/api/v1/success-failure-stats/repo/{org}/{repo}/{workflow}/{job}Pass/fail statistics

Sizing Overrides

MethodPathDescription
GET/api/v1/sizing/overridesList all overrides
PUT/api/v1/sizing/overrides/{org}Upsert org-level override
PUT/api/v1/sizing/overrides/{org}/{repo}Upsert repo-level override
PUT/api/v1/sizing/overrides/{org}/{repo}/{workflow}Upsert workflow-level override
PUT/api/v1/sizing/overrides/{org}/{repo}/{workflow}/{job}Upsert job-level override
DELETESame paths as PUTRemove override at that scope

Override hierarchy: job > workflow > repo > org (most-specific wins). Fields left null are inherited from the next parent scope. See Sizing Algorithm — Sizing Overrides for details.

OIDC UI Routes

Available when auth mode is oidc.

MethodPathDescription
GET/ui/loginInitiate OIDC login
GET/ui/callbackOIDC callback
GET/ui/logoutLogout
GET/ui/meCurrent user info

OpenAPI Specification

The OpenAPI spec is auto-generated from the receiver’s route definitions and served live at /swagger. The spec file is also committed to the repository at docs/openapi.json.

Note: The OpenAPI spec is generated code — do not edit it manually. Run make openapi in the ci-sizer repository to regenerate it after API changes.