Documentation

EmitCI Docs

Everything you need to measure, reduce, and report the carbon footprint of your CI/CD pipelines.

What is EmitCI?

EmitCI measures the carbon footprint and compute cost of every CI/CD pipeline run — automatically, across six CI platforms, with no YAML changes and no code instrumentation required.

For GitHub Actions, EmitCI runs as a GitHub App: every time a workflow completes, it receives a webhook, fetches job and step timing metadata, and runs an energy estimation model based on GreenAlgorithms v2.2. The result: gCO₂e and kWh per run, per job, and per step, available in your dashboard within seconds.

For GitLab CI, Bitbucket Pipelines, Azure DevOps, CircleCI, and Jenkins, EmitCI polls the platform API every 5 minutes using read-only credentials you provide. The same energy model runs on the fetched pipeline data — the dashboard experience is identical regardless of CI platform.

What problem does it solve?

CI pipelines are invisible in sustainability reporting. They run hundreds or thousands of times per month on cloud compute, consuming real electricity — but most engineering teams have no idea how much, and no way to report it. EmitCI makes that invisible footprint visible, measurable, and reducible.

At the same time, most teams are overspending on CI. Uncached dependencies, oversized runners, and redundant runs account for 35% of typical CI spend on average. EmitCI surfaces ranked, actionable recommendations to cut both cost and carbon — ranked by dollar impact so you know where to start.

What EmitCI does

Measures every run

Energy (kWh) and carbon (gCO₂e) per workflow run, job, and step — using hardware specs, cloud region grid intensity, and PUE.

Benchmarks your pipeline

Compares your footprint against similar repos by language and workflow type, so you know if you're above or below the industry median.

Recommends what to fix

Ranked, specific recommendations (e.g. "cache npm install — saves $192/mo and 46g CO₂/mo") generated automatically after every run.

Enforces carbon budgets

Set a monthly CO₂ ceiling per repo. When exceeded, EmitCI posts a failure commit status on open PRs. Add it to your branch protection rules to hard-block merges — no YAML changes needed.

Full GHG inventory

Scope 1 (direct), Scope 2 (electricity), and Scope 3 (cloud, CI/CD, hardware, SaaS) in one Emissions page. SHA-256 verified ESG PDF, CSRD CSV, CDP workbook, and GHG Methodology PDF exports included.

Schedules green runs

Automatically shifts nightly and scheduled jobs to the lowest-carbon grid window within ±3 hours. Zero workflow changes.

Tracks DORA + CO₂/deployment

Deployment Frequency, Lead Time, CFR, and MTTR — plus CO₂ per deployment as the 5th DORA metric. Tier ratings: Elite / High / Medium / Low.

Works on 6 CI platforms

GitHub Actions, GitLab CI, CircleCI, Azure DevOps, Bitbucket Pipelines, and Jenkins — all normalized through the same energy estimation pipeline.

Embeds in your tools

VS Code extension estimates CO₂/run as you edit workflow files. Chrome extension overlays badges on GitHub Actions pages. npx emitci CLI for local estimates.

What EmitCI does not do

  • Read your source code, secrets, or environment variables
  • Require any changes to your workflow YAML files
  • Slow down or interfere with your CI runs in any way
  • Require a self-hosted agent or additional infrastructure

Quickstart

Install in under 60 seconds — you'll have live data before your next push lands.

1. Connect your CI platform

Go to app.emitci.com/login and sign in. The onboarding flow adapts to your CI platform:

  • GitHub Actions — sign in with GitHub, then install the EmitCI GitHub App. One click, read-only permissions, no source code access. Data arrives via webhook within seconds of your next run.
  • GitLab CI — sign in with GitLab OAuth or a Personal Access Token. EmitCI polls your pipelines every 5 minutes and posts carbon summaries as MR comments.
  • Bitbucket Pipelines — sign in with Google or email, then enter your Bitbucket workspace slug and an App Password (Pipelines: read scope). Polling starts immediately.
  • Azure DevOps — sign in with Google or email, then enter your organisation/project and a PAT (Build: read scope).
  • CircleCI — sign in with Google or email, then enter a personal API token.
  • Jenkins — sign in with Google or email, then enter your Jenkins URL, username, and API token.

Note

Exact permissions requested: Actions (read-only — workflow run metadata, job names, step names, durations), Metadata (read-only — repository names; required by all GitHub Apps), and Contents (read-only — workflow YAML files and Dockerfiles only, used to generate CI optimisation recommendations). Every other permission — Secrets, Pull requests, Issues, Administration — is absent. EmitCI cannot read application source code, access secrets, push commits, or modify anything in your repositories.

Note for security reviewers: There is a second, separate GitHub OAuth step when users log in to the dashboard. This uses read:org (to verify org membership), repo (to read repository names for display), and user:email (to retrieve your primary verified email address for account notifications and billing). No email is shared with third parties. Full details at /security.

Note

Welcome email: EmitCI sends a one-time welcome email when you first log in. We use the primary verified email from your GitHub account — this works regardless of whether your email is set to public or private on your GitHub profile. If you do not receive it, check your spam folder or verify that your GitHub account has at least one verified email address at github.com/settings/emails.

2. Backfill historical data (optional)

After install, you'll be offered a backfill — importing the last 30, 60, or 90 days of CI history. This gives your dashboard meaningful data immediately rather than waiting for new runs. Enterprise plans support extended backfill of up to 2 years of history — contact sales when setting up your account to arrange this.

3. Your first run appears automatically

Push any commit to a tracked repo. Your dashboard will show energy, CO₂, and recommendations within seconds — no further action needed.

Sign-in methods

EmitCI supports four ways to sign in — all land on the same dashboard and use the same session cookie.

GitHub

Primary sign-in for GitHub Actions users. OAuth redirects to github.com, no password stored. Grants read:org, repo (names only), and user:email.

GitLab

OAuth sign-in for gitlab.com users. Also supports self-hosted GitLab instances via a Personal Access Token (read_api + read_user scopes).

Google

Sign in with any Google or Google Workspace account. On first sign-in, EmitCI checks whether your Google email matches an existing account's billing email and auto-links them — no duplicate account is created. New Google sign-ins start a 14-day free trial like any other new account.

Email magic link

Passwordless sign-in for non-GitHub stakeholders (e.g. sustainability managers, finance, external auditors) invited by an admin. A one-time link is emailed and expires in 15 minutes.

Note

All sign-in methods issue the same JWT session cookie. A user who signs in via GitHub one day and Google another day will land in the same installation if their billing email matches — no data is duplicated.

Multi-platform CI

EmitCI supports five CI platforms beyond GitHub Actions. Once you connect platform credentials, EmitCI polls each platform every 5 minutes and processes runs through the same energy estimation and carbon accounting pipeline as GitHub Actions runs.

Supported platforms

GitLab CI

Token: GitLab personal access token (read_api scope)

Supports gitlab.com and self-hosted GitLab instances.

CircleCI

Token: CircleCI API token (read-only)

Polls pipelines and workflows via CircleCI v2 API.

Azure DevOps

Token: Azure DevOps PAT (Build: read)

Supports Azure DevOps Services (dev.azure.com) and Azure DevOps Server.

Bitbucket Pipelines

Token: Bitbucket App Password (pipeline:read)

Polls pipelines via Bitbucket Cloud API v2.

Jenkins

Token: Jenkins API token + base URL

Reads build JSON and workflow stage data via Jenkins REST API.

Connecting a platform

Go to Settings → Integrations. Select the platform, enter your API token and the required identifier (org slug, project ID, or base URL depending on the platform), then click Connect. EmitCI will begin polling within the next 5-minute window. Credentials are encrypted at rest with AES-256-GCM.

The connected integrations list shows a Last synced timestamp for each CI provider. If it shows "Sync pending…", the first poll hasn't completed yet — wait up to 5 minutes. Disconnecting and reconnecting a provider resets the sync cursor so EmitCI re-fetches the last 24 hours of runs on the next poll.

Note

CI platform integrations are available on all plans including the free trial — connect now to evaluate multi-platform carbon tracking before upgrading. All external CI runs appear in the same dashboard alongside GitHub Actions runs. The provider badge on each run indicates the source platform.

GitHub Measure Action

The EmitCI Measure Action is a zero-install way to add carbon reporting to any public or private repository — no GitHub App required. Add one step to any workflow and your run summary will include CO₂, energy, grade, and a Markdown table.

Usage

- name: Measure CI carbon footprint
  uses: emitci/measure@v1
  with:
    fail_on_exceed: 50    # optional: fail if CO₂ > 50g
    token: ${{ secrets.EMITCI_TOKEN }}  # optional: unlocks repo comparison

What it does

  • Calls GET /api/v1/runs/latest at the end of the run
  • Writes a Markdown CO₂ summary table to $GITHUB_STEP_SUMMARY
  • Posts a PR comment when triggered on a pull request event
  • Writes outputs: co2_grams, energy_kwh, grade
  • Exits 1 if fail_on_exceed is set and the budget is exceeded

No App needed

The action calls EmitCI's public /api/v1/runs/latest endpoint — no GitHub App installation is required. If you later install the full GitHub App, data from both sources is unified in your dashboard.

How energy is calculated

EmitCI uses the GreenAlgorithms v2.2 methodology, extended with Cloud Carbon Footprint (CCF) SPECpower benchmarks for per-runner watt values.

Energy formula

compute_kWh = (min_watts + cpu_util × (max_watts - min_watts))
              × duration_hours × PUE / 1000

memory_kWh  = memory_gb × mem_util × 0.375 W/GB
              × duration_hours × PUE / 1000

energy_kWh  = compute_kWh + memory_kWh

co2_grams   = energy_kWh × carbon_intensity_gCO2_per_kWh

Where:

  • min_watts / max_watts — per-runner idle/peak watts from CCF SPECpower data, scaled by vCPU count
  • cpu_util — inferred per step type (0.10–0.95); defaults to 0.65 if unrecognised; adjustable via the public estimator API
  • mem_util — inferred per step type (0.10–0.80); defaults to 0.50 for unrecognised steps
  • PUE — Power Usage Effectiveness: region-specific for Azure (1.12–1.58), AWS (1.10–1.20), and GCP (1.09–1.13)
  • carbon_intensity — gCO₂/kWh for the runner's cloud region across 75 regions; sourced from WattTime or Electricity Maps (BYOK) when configured, otherwise IEA 2023 regional averages

Runner watt values

Watt values are derived from CCF's per-vCPU SPECpower benchmarks and scaled by the number of vCPUs for the runner. For example, ubuntu-latest runs on Azure Cascade Lake with 2 vCPUs → min 1.28 W, max 7.94 W. Apple Silicon runners use manufacturer specifications. ARM runners (ubuntu-24.04-arm, ubuntu-latest-arm) use AWS Graviton 3 profiles.

You can inspect all runner specs at the public API: GET /api/v1/estimate/runners

Step-level breakdown

Energy is allocated to individual steps proportionally by wall-clock duration within each job. This lets you see which step (e.g. npm install, Run tests) consumes the most energy within a workflow run.

Carbon budgets

A carbon budget is a monthly CO₂ ceiling set per repository. When a repo approaches or exceeds its budget, EmitCI can alert you and optionally block new merges.

Setting a budget

Go to your repo's page in the dashboard → Settings → Carbon Budget. Enter a monthly CO₂ limit in grams. Sensible starting values:

  • Small repo (<50 runs/month): 500–1,000g
  • Medium repo (50–200 runs/month): 2,000–5,000g
  • Large monorepo (200+ runs/month): set based on your baseline from the last 30 days

Alert thresholds

At 80% of budget: email and Slack alert sent to configured channels. At 100%: another alert plus optional merge blocking.

Merge blocking

When merge blocking is enabled and a repo hits 100% of its budget, EmitCI posts a failure commit status named EmitCI / carbon-report on the head commit of every open PR. No changes to your workflow YAML are required.

The red status check appears automatically — but to make GitHub actually prevent the merge, you need one setup step on GitHub: go to your repository's Settings → Branches → branch protection rules, enable "Require status checks to pass before merging", and add EmitCI / carbon-report to the required checks list. Once configured, GitHub blocks the merge button until the budget resets at the start of next month or an Admin raises the limit.

Important

Merge blocking affects all open PRs on the repo simultaneously. Set up the branch protection rule and communicate the budget limit to your team before enabling hard enforcement.

Recommendations

After every workflow run, EmitCI's rule engine analyses the last 50 runs for that repo and generates ranked optimization recommendations. Each recommendation includes an estimated monthly CO₂ saving and a confidence score based on sample count.

Run metadata rules (Tier 1)

uncached_dependencies

Cache dependency installation

Detects npm install, pip install, bundle install etc. running without cache hits. Caching saves ~85% of the step's energy.

oversized_runner

Downsize over-provisioned runners

Detects large runners (4-core, xlarge) with <35% CPU utilization. Switching to a smaller runner saves ~72% of runner energy.

arm_runner_opportunity

Switch to ARM runners

Detects x86 runners on repos without platform-specific native code. ARM64 runners (arm-2core) are 37% cheaper per minute.

serial_parallelizable_jobs

Parallelize independent jobs

Detects 3+ jobs with no needs: dependencies that could run in parallel, reducing feedback time.

no_path_filters

Add path filters

Detects push runs triggered by documentation-only changes (*.md, docs/**). paths-ignore can skip these entirely.

redundant_runs

Cancel redundant runs

Detects the same commit SHA triggering multiple runs. concurrency: cancel-in-progress: true fixes this.

always_failing_steps

Fix chronically failing steps

Detects steps failing >50% of the time — all energy spent before the failure is wasted.

macos_to_linux_opportunity

Replace macOS runners with Linux

Detects macOS runners without Xcode/iOS/Swift tooling. macOS runners cost 10× more than Linux ($0.08 vs $0.008/min). Typically saves 90% of runner cost.

slow_test_steps

Shard slow test suite

Fires when average test step duration exceeds 20 min. Splitting into 2–4 parallel shards (pytest-xdist, jest --shard, GitHub matrix) cuts wall-clock time by 50–75% at the same runner cost.

test_parallelization_opportunity

Shard tests across parallel jobs

Fires when a single test step dominates >70% of a job's duration and runs for more than 20 min. Matrix sharding could halve developer wait time at zero extra cost.

duplicate_trigger

Remove duplicate push + PR trigger

Detects on: [push, pull_request] which fires two runs per PR commit — one for the push event and one for the PR event — doubling runner cost with zero added coverage. Recommend triggering on pull_request only.

branch_sprawl

Prune stale feature branches

Fires when >35% of runs originate from non-default branches. Stale branches with open CI queue up runners that never ship. Adding branch protection rules and auto-deleting merged branches reduces wasted builds.

low_deploy_ratio

Review CI-to-deploy ratio

Fires when the ratio of CI runs to deploy events exceeds 30:1. High ratios indicate CI is running heavily without shipping — often a sign of excessive branch churn or broken deploy pipelines.

dead_steps

Remove dead steps (<3 s)

Detects steps that consistently complete in under 3 seconds. Common culprits: echo commands, empty scripts, no-op actions left from old configs. Removing them reduces YAML noise and marginal runner overhead.

artifact_bloat

Reduce artifact upload size or frequency

Fires when artifact upload steps consistently take >45 seconds, indicating large artifacts being stored on every run. Scoping uploads to release branches only, or compressing before upload, typically cuts upload time by 60%.

suboptimal_runner_region

Move self-hosted runners to a lower-carbon region

Detects self-hosted runners labelled with a high-carbon cloud region (e.g. us-east-2 at 545 gCO₂/kWh) when a lower-carbon option in the same provider-continent group is available (e.g. us-west-2 at 130 gCO₂/kWh) at identical cost. Carbon saving only — no dollar change. Based on 12-month grid averages (IEA/Ember). Only fires when a region code is detectable in the runner label.

Workflow YAML rules (Tier 2)

missing_concurrency

Add concurrency group

Detects workflows without a concurrency: block. Without it, multiple pushes queue up unlimited parallel runners.

fail_fast_disabled

Remove fail-fast: false

Matrix jobs with fail-fast: false keep running when one variant fails, burning minutes on a broken build.

matrix_explosion

Prune matrix build combinations

Detects matrix strategies with ≥ 15 Cartesian combinations. Pruning to ≤ 8 meaningful combinations reduces queue time and cost.

docker_layer_cache

Enable Docker layer caching

Detects docker/build-push-action or docker build without cache-from. Adding type=gha cache typically cuts Docker build time by 60–80%.

poor_cache_key

Fix cache key quality

Flags cache keys using package.json (changes every npm install) instead of the lockfile. Use hashFiles('**/package-lock.json') for stable, high-hit-rate keys. Also flags fully static cache keys that never invalidate.

unconditional_deploy_job

Add branch guard to deploy jobs

Detects deploy jobs in pull_request-triggered workflows with no if: github.ref == 'refs/heads/main' guard — risks accidental production deploys from feature branches.

monorepo_no_path_filters

Add path filters in monorepo

Detects workflows with job names suggesting a monorepo (frontend, backend, api, packages/) but no paths: filter. Every push triggers all workflows even when only one package changed.

checkout_shallow

Use shallow checkout

Deep git checkouts (fetch-depth: 0) are rarely needed. fetch-depth: 1 reduces clone time and bandwidth.

missing_job_timeout

Add job timeout

Jobs without timeout-minutes can run for 6 hours on a hung process before GitHub cancels them.

artifact_retention

Shorten artifact retention

Artifacts using the default 90-day retention incur storage charges. retention-days: 7 is sufficient for most build outputs.

high_frequency_schedule

Reduce scheduled run frequency

Cron schedules running more than once per hour waste runners on stale checks. Reduce to hourly or daily.

windows_runner_tax

Replace Windows runners with Linux

Detects jobs using windows-latest without Windows-specific tooling (MSBuild, NuGet, .exe installers, PowerShell-only commands). Windows runners bill at 2× the Linux rate; Linux is sufficient for most cross-platform code.

tight_timeout

Tighten job timeouts to catch hangs faster

Fires when a job's timeout-minutes is set to 4× or more its observed maximum runtime. A job that hangs (network deadlock, infinite retry) burns the full timeout before GitHub kills it. Tightening saves wasted runner minutes on every future hang.

matrix_redundancy

Reduce matrix to oldest + latest versions

Detects matrix dimensions with 4+ numeric version values. Unless your code uses version-specific APIs, testing only the oldest supported and latest versions catches the same failures with fewer jobs. Keep intermediate versions in a weekly scheduled run.

Managing recommendations

All recommendations across every repository are listed at /recommendations. You can mark individual recommendations as Resolved (you acted on it) or Dismissed (acknowledged but not applicable). The Open / Resolved / Dismissed tabs let you track progress. Resolved recommendations are excluded from the monthly savings headline so the number stays meaningful.

AI inference optimization rules

When AI inference tracking is enabled, EmitCI analyses your AI usage patterns and surfaces cost and carbon savings alongside your CI recommendations. These appear in the AI tab on the recommendations page.

ai_legacy_embedding_model

Upgrade legacy embedding model

Fires when ada-002 usage is detected. text-embedding-3-small delivers equal or better retrieval quality at ~5× lower cost and ~78% less energy per token. text-embedding-3-large is available when maximum accuracy is needed at 2× the cost of small.

ai_oversized_model

Downsize to a smaller model

Fires when gpt-4o or claude-3-opus is used for tasks with short outputs (<150 tokens on average). For classification, structured extraction, and short summarisation, gpt-4o-mini or claude-3-5-haiku delivers equivalent accuracy at ~10× lower cost and ~90% less energy.

ai_reembed_unchanged

Cache embeddings for unchanged content

Fires when the same content hash is embedded more than once per 24-hour window. Embedding identical text repeatedly is pure waste — a local or Redis vector cache eliminates repeat API calls entirely.

ai_provider_carbon_arb

Switch to a lower-carbon provider for this use case

Fires when the current provider emits significantly more CO₂ than an alternative (e.g. OpenAI at ~388 gCO₂/kWh vs Mistral at ~50 gCO₂/kWh for French infrastructure). Shows the estimated CO₂ saving and cost delta. Only fires when a compatible alternative model exists for the detected call type.

ai_small_call_batching

Batch small embedding calls

Fires when embedding API calls average fewer than 5 inputs per call. Most providers support batch inputs (openai.embeddings.create(input=[...])). Batching reduces per-token overhead and can lower cost by 30–50%.

ai_embedding_frequency

Reduce re-embedding frequency for static content

Fires when the same document corpus is re-embedded more than once per day with no content change detected. For static knowledge bases (product docs, codebases), daily or weekly re-embedding is sufficient. Combine with a content-hash check before triggering the embed pipeline.

ai_uncapped_output

Add max_tokens to cap output length

Fires when completions regularly use >80% of the model's context window for output. Uncapped output is the single largest driver of per-call cost and energy. Adding max_tokens and designing the prompt to work within it reduces average cost per call without affecting quality for bounded tasks.

ai_no_response_cache

Cache repeated identical queries

Fires when the same prompt hash is sent to the same model more than 3 times in a 24-hour window with identical outputs. Caching the response (in Redis, a file, or an in-process dict) eliminates repeat API calls at zero quality cost.

Note

AI rules require at least 7 days of AI inference data before firing. Cost savings shown in the recommendations page use published API pricing as of mid-2025 — verify current pricing at your provider before making model decisions.

Benchmark-driven rules

Three additional rules fire when enough cross-customer benchmark data is available: your pipeline vs. peer median, energy trend degradation (linear regression), and anomalous run detection (z-score outliers). These improve as more organisations contribute data.

Analytics cards

The repo detail page shows additional analytics cards alongside recommendations:

Caching ROI

Per-step breakdown of uncached dependency installs, showing CO₂ wasted and potential monthly savings with an 85% cache-hit assumption.

Re-run Cost

Dollar and CO₂ cost of flaky test re-runs (run_attempt > 1) per workflow in the last 30 days. Each re-run fully rebills runner minutes.

Self-Hosted ROI

If you use self-hosted runners, shows total compute minutes and the equivalent GitHub-hosted cost you avoided this month. Visible only when self-hosted jobs are detected.

Self-Hosted Break-Even

For GitHub-hosted-only repos, estimates monthly savings and break-even months if you switched to an EC2 spot instance. Assumes $300 one-time setup and $0.015/hr EC2 t3.medium spot pricing.

Test Suite Growth

Fits a linear trend to weekly test step durations over the last 90 days and projects cost 60 days ahead. Shows when test costs are growing faster than 30 seconds/week.

Cost Forecast

Projects end-of-month CO₂ and GitHub cost based on your current pace, and shows progress against any active carbon budget.

PR carbon comments

Every time a workflow run completes on a pull request, EmitCI automatically posts a comment to the PR with the energy and CO₂ data for that run. No configuration required — it activates the moment EmitCI processes the first PR run.

What the comment includes

  • Total energy (kWh) and CO₂ (grams) for the run
  • Comparison to your 30-day baseline (e.g. "12% above average")
  • Top energy-consuming step (e.g. Run tests — 68% of run)
  • SCI score and carbon intensity for the runner region
  • Link to the full run breakdown in your dashboard

Note

If a PR has multiple workflow runs (e.g. test + build), EmitCI updates a single comment rather than posting one per run — keeping your PR clean.

Example comment

⚡ EmitCI — CI Carbon Report

  Run: build.yml · ubuntu-latest · 4m 12s
  Energy:   0.00187 kWh   (+8% vs baseline)
  CO₂:      0.83g          (carbon intensity: 442 gCO₂/kWh)
  Top step: Run tests — 71% of run

  SCI score: B  |  View full breakdown →

Anomaly detection

EmitCI monitors every workflow run against your historical baseline. When a run consumes significantly more energy than usual, it fires an anomaly alert automatically.

Trigger thresholds

An anomaly is flagged when either condition is met:

  • Ratio ≥ 2.0× — the run used at least twice the average energy of the last 10 baseline runs
  • Z-score ≥ 3.0σ — the run is 3 standard deviations above the mean (catches spikes even on high-variance pipelines)

A minimum of 5 baseline runs is required before anomaly detection activates for a repo. This prevents false positives on new repositories with limited history.

What happens when an anomaly fires

  • The anomaly is recorded in your dashboard under the Anomalies tab
  • The PR comment (if it was a PR run) is flagged with the spike ratio
  • If AI is enabled, an energy regression analysis comment is posted (see below)

Example anomaly in the PR comment

🚨 Energy spike detected — this run used 3.1× more energy than baseline
  Baseline avg: 3.42g CO₂ (last 10 runs)
  This run:    10.74g CO₂

  See energy regression analysis below ↓

Energy regression AI

When an anomaly is detected on a pull request and AI is available (BYOK or paid plan), EmitCI fetches the PR diff and asks Claude to identify which code changes likely caused the energy spike — then posts a targeted code-level review comment on the PR.

This turns "your CI used 3× more energy" into "this new loop in parse.py:42 is likely the cause — here's a fix."

What triggers it

  • Run is on a pull request (not a push or scheduled run)
  • Anomaly threshold met: ratio ≥ 2.0× or z-score ≥ 3.0σ
  • AI is available (your BYOK key or a paid plan EmitCI key)

Example output

⚡ EmitCI: Energy Regression Analysis

This PR's CI run used 3.1× more energy than baseline
(10.74g CO₂ vs 3.42g avg over 10 runs).

The most likely cause is the new generate_report() call in
src/reports.py (lines 142–180). It reads the entire dataset
into memory on every test run without mocking — pd.read_csv()
on a 50MB fixture will execute once per test class.

Suggested fix: mock pd.read_csv in your test setup, or use a
smaller fixture file for unit tests.

Note

The code reviewer analyses up to 30 changed files per PR, skipping non-code files (.md, .json, .yaml, images). It never stores your code — the diff is sent to the AI provider in a single request and not retained.

Green Time Scheduler

The Green Time Scheduler automatically reschedules cron-triggered workflows to the lowest-carbon grid window within ±3 hours of their original schedule.

How it works

EmitCI queries the Electricity Maps API for a 24-hour carbon intensity forecast for your runner's cloud region. If the current intensity is above 350 gCO₂/kWh, it finds the cleanest 2-hour window and defers the workflow via the GitHub Actions workflow_dispatch API.

Note

The scheduler only defers workflows matching deferrable patterns: nightly, weekly, scheduled, cron, dependency-update, security-scan. It never defers PR-triggered or push-triggered runs.

Tonight's Green Windows dashboard widget

The dashboard includes a Tonight's Green Windows panel showing the lowest-carbon 2-hour slot across your runner regions — updated hourly with a suggested cron expression you can drop straight into your workflow YAML. The widget is visible on Starter and above.

The widget requires a live Electricity Maps API key. EmitCI checks for one in this order:

  1. Your organisation's own key added in Settings → Integrations → Electricity Maps (BYOK — takes priority)
  2. The platform-level key configured by EmitCI (available when EmitCI has purchased an Electricity Maps licence)

If neither key is present, the widget is hidden entirely — no placeholder is shown. To enable it immediately on any plan, add your own Electricity Maps key in Settings → Integrations.

Note

Per-plan zone limits apply to the widget: Starter sees 1 region (4h cache), Team sees up to 3 regions (1h cache), Enterprise sees all detected regions (30-min cache).

Enabling the scheduler

Go to repo settings → Green Scheduling and toggle it on. No workflow YAML changes required. The scheduler will begin operating from the next scheduled trigger.

DORA Metrics

The DORA (DevOps Research and Assessment) page tracks the four standard engineering performance metrics — plus CO₂ per deployment as a 5th metric, giving VP Engineering teams a reason to instrument carbon reporting alongside their existing DORA dashboards.

The five metrics

deploys/day

Deployment Frequency

How often the team deploys to production. Elite: ≥1/day. High: ≥1/week.

hours

Lead Time for Changes

Time from code push to production deploy. Elite: <1h. High: <24h.

%

Change Failure Rate

Percentage of deployments that cause a production incident. Elite: <5%. High: <10%.

hours

MTTR

Mean time to restore service after a failure. Elite: <1h. High: <24h.

gCO₂e

CO₂ per Deployment

Average carbon footprint of a single production deployment run. The 5th metric unique to EmitCI.

How deploy runs are detected

EmitCI classifies a workflow run as a deployment when: the event is push, the branch is main or master, and the workflow name contains deploy, release, or prod. The classifier works without any YAML changes and covers both GitHub Actions and external CI platforms.

DORA tiers

Tiers are based on Google DORA thresholds. EmitCI computes your tier from the last 12 weekly snapshots. A repo must have at least 3 deploy runs to receive a tier rating.

Finding the DORA page

Navigate to DORA in the top navigation. Select a repo from the dropdown to see 12 weeks of trend charts, or view the installation-level summary for a rollup across all repos.

Public Leaderboard

The public leaderboard ranks open source repositories by carbon efficiency (lowest average CO₂/run first). It is opt-in — your repos are never listed without explicit consent.

Opting in

Go to Settings → Badge → Public Leaderboard and toggle visibility to Public. Requirements:

  • Repository must be public on GitHub (private repos are never listed)
  • At least 5 runs in the last 30 days (prevents stale data appearing)
  • Installation must be on a paid plan (ensures data quality)

What's shown

Each entry shows: rank, repository name, primary language, average CO₂/run, SCI grade, run count, and a 4-week trend indicator. The leaderboard is public and accessible without login at /insights/leaderboard/public.

Note

Opting in to the public leaderboard is a great way to demonstrate your team's commitment to sustainable engineering. Repos that improve their rank over time are highlighted with a trend arrow.

AI assistant & BYOK

EmitCI includes a conversational AI assistant in the dashboard that can answer questions about your pipeline carbon data — "which repo emits the most CO₂?", "were there any energy spikes this week?".

BYOK (Bring Your Own Key)

All plans support BYOK. Add your Anthropic or OpenAI API key in Settings → AI → API Key. It is encrypted at rest using AES-256-GCM and is only used to call the AI provider — never logged or shared.

With BYOK enabled, you also get: AI-generated PR carbon comments (more natural than the static template), AI runner classification for custom self-hosted runners, and green scheduling advisories.

Paid plan AI (no BYOK required)

Team and Enterprise plans include a EmitCI-hosted AI key at no additional cost. BYOK always takes priority over the hosted key if both are configured.

AI Inference Tracking

EmitCI can measure the carbon footprint of AI API calls made during your CI pipelines — LLM completions, embeddings, and other inference calls. For workflows that include RAG pipelines, LLM-based test generation, or AI code review steps, AI API calls can account for 2–5× the carbon of the runner compute.

All estimates are research-based approximations derived from Patterson et al. 2022, MLPerf Inference v4.0 benchmarks, and Luccioni et al. 2023. They are labeled as "estimated" in the dashboard and should not be used for regulatory filings without independent verification.

Note

AI inference tracking is available on all plans including Free. You need your EMITCI_TOKEN (from Settings → API) to authenticate reports.

How carbon is estimated

The formula is the same used in academic ML energy accounting:

energy_kwh = (
  input_tokens  / 1000 × input_kWh_per_1k  +
  output_tokens / 1000 × output_kWh_per_1k
) × PUE

co2_grams = energy_kwh × grid_intensity_gCO2_per_kWh

Energy factors are per-model (e.g. gpt-4o: 0.00040 kWh/1k input, 0.00160 kWh/1k output). Grid intensity is per-provider based on published data centre locations (e.g. OpenAI ≈ 388 gCO₂/kWh US mix, Google ≈ 220 gCO₂/kWh with renewable matching, Mistral ≈ 50 gCO₂/kWh France nuclear grid). Model names are normalised before lookup — date suffixes like -20241022 are stripped automatically.

Path 1 — Python SDK (emitci-ai)

The emitci-ai package wraps your existing OpenAI and Anthropic clients transparently.

pip install emitci-ai
# or with provider extras:
pip install "emitci-ai[openai,anthropic]"
import os
import openai
import anthropic
from emitci_ai import EmitCITracker

# Auto-reads EMITCI_TOKEN and GITHUB_RUN_ID from environment
tracker = EmitCITracker()

# Drop-in replacement — same interface, zero latency impact
oai = tracker.wrap_openai(openai.OpenAI())
anth = tracker.wrap_anthropic(anthropic.Anthropic())

# Use exactly as before — usage is reported in a background thread
response = oai.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Summarise this CI log..."}],
)

# Embeddings also tracked
embedding = oai.embeddings.create(
    model="text-embedding-3-small",
    input="your text here",
)

The wrapper reads response.usage after each call and fires tracker.report() in a daemon thread. The original response object is returned unchanged. If the API call fails or usage is null, nothing is reported — no exception is raised.

Manual reporting — if you use a provider not yet wrapped, report directly:

tracker.report(
    provider="google",
    model="gemini-1.5-pro",
    input_tokens=1_200,
    output_tokens=450,
    call_type="chat",   # "chat" | "embedding" | "completion"
    api_calls=1,
)

Path 2 — GitHub Actions (emitci/report-ai@v1)

Add a step after any AI-calling step in your workflow. The action reads GITHUB_RUN_ID automatically and posts usage to EmitCI using your token.

- name: Run AI pipeline step
  run: python scripts/embed_and_summarise.py
  env:
    OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

- name: Report AI carbon to EmitCI
  uses: emitci/report-ai@v1
  with:
    token:         ${{ secrets.EMITCI_TOKEN }}
    provider:      openai
    model:         gpt-4o-mini
    input_tokens:  1200    # read from your script's output
    output_tokens: 450
    api_calls:     1       # optional, defaults to 1
    call_type:     chat    # chat | embedding | completion

The action outputs co2_grams and energy_kwh so you can display them in your step summary or use them in subsequent steps. It never exits with a non-zero code on API failure — CI is never blocked.

Path 3 — REST API

Report usage from any script or CI system using a plain HTTP POST.

curl -X POST https://api.emitci.com/api/v1/ingestion/ai-usage \
  -H "Authorization: Bearer $EMITCI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "run_id":        '"$GITHUB_RUN_ID"',
    "provider":      "openai",
    "model":         "gpt-4o-mini",
    "input_tokens":  1200,
    "output_tokens": 450,
    "call_type":     "chat",
    "api_calls":     1,
    "source":        "action"
  }'

// Response
{
  "ok": true,
  "co2_grams": 0.000131,
  "energy_kwh": 0.000000339,
  "model": "gpt-4o-mini"
}

Supported values for provider: openai, anthropic, google, cohere, mistral, ollama, vllm, self_hosted. Supported values for call_type: chat, embedding, completion.

Self-hosted and local inference (Ollama, vLLM)

Ollama and vLLM both expose OpenAI-compatible APIs that return token counts in the same format as OpenAI. Use provider=ollama or provider=vllm (or provider=self_hosted for any other compatible server). For accurate grid intensity, pass the region field — otherwise EmitCI uses a global average of 442 gCO₂/kWh.

curl -X POST https://api.emitci.com/api/v1/ingestion/ai-usage \
  -H "Authorization: Bearer $EMITCI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "run_id":        '"$GITHUB_RUN_ID"',
    "provider":      "ollama",
    "model":         "llama-3-8b",
    "input_tokens":  800,
    "output_tokens": 320,
    "call_type":     "chat",
    "region":        "us-west-2"
  }'

The region field accepts any AWS, GCP, or Azure region identifier (e.g. us-west-2, europe-west4, eastus). It is used to look up the grid carbon intensity for the server's physical location. If your GPU server is on-premise, omit region and the global average is used.

Viewing AI carbon in analytics

Once events are ingested, AI carbon appears in two places:

  • Run list — each run shows ai_co2_grams and ai_energy_kwh alongside runner carbon. A badge marks runs with AI inference events.
  • Run detail — the step breakdown panel includes a per-event AI inference table (provider, model, tokens, call type, source, CO₂).

The AI usage summary is available at:

GET /api/v1/analytics/ai-usage?days=30
Authorization: Bearer <session-token>

// Response
{
  "total_ai_co2_grams": 4.21,
  "total_runner_co2_grams": 18.70,
  "ai_pct_of_total": 18.4,
  "by_model": [
    {
      "model":         "gpt-4o-mini",
      "provider":      "openai",
      "co2_grams":     3.12,
      "input_tokens":  45000,
      "output_tokens": 12000,
      "call_count":    38
    }
  ],
  "by_repo": [
    {
      "repo_full_name":  "acme/api",
      "ai_co2_grams":    3.80,
      "runner_co2_grams": 12.40
    }
  ]
}

Opt-in log scanning

If you cannot modify CI workflows (e.g. third-party pipelines), EmitCI can scan job logs post-ingestion to detect AI usage automatically. Log scanning is opt-in per installation and disabled by default.

Enable it in Settings → AI → Log scanning. When enabled, EmitCI fetches the plain-text log for each completed job and applies regex patterns to extract token counts and model names. Detected events are stored with source="log_parse". Log scanning is best-effort — it never blocks ingestion and failures are silently logged.

Important

Log scanning reads job logs from the GitHub Actions API. Job logs may contain sensitive information (masked secrets are replaced with *** by GitHub). EmitCI reads only the first 512 KB of each log and does not store log text — only the extracted token counts and model name.

Supported providers and models

OpenAI

managed API

gpt-4o · gpt-4o-mini · gpt-4 · gpt-3.5-turbo · text-embedding-3-small · text-embedding-3-large · text-embedding-ada-002

Anthropic

managed API

claude-3-5-sonnet · claude-3-5-haiku · claude-3-opus · claude-3-sonnet · claude-3-haiku · claude-opus-4 · claude-sonnet-4 · claude-haiku-4

Google

managed API

gemini-1.5-pro · gemini-1.5-flash · gemini-2.0-flash · gemini-2.5-pro

Cohere

managed API

command-r-plus · command-r · embed-english-v3

Mistral

managed API

mistral-large · mistral-small · mistral-7b

Ollama / vLLM / self_hosted

self-hosted

llama-3-8b · llama-3-70b · llama-3-405b · llama-3.1-8b · llama-3.1-70b · llama-3.2-3b · llama-2-7b · llama-2-13b · llama-2-70b · phi-3-mini · phi-3.5-mini · falcon-7b · falcon-40b · nomic-embed-text · all-minilm-l6-v2 · bge-m3 · mxbai-embed-large

If a model is not in the table, EmitCI falls back to provider-level average energy factors and labels the estimate accordingly. Date/version suffixes (-20241022, -preview, -instruct), HuggingFace org prefixes (meta-llama/Llama-3-8Bllama-3-8b), and Ollama colon tags (llama3:8bllama-3-8b) are normalised automatically before lookup.

Not supported

The following model types are outside the current token-based energy model and will be rejected by the ingestion API:

Image generation

DALL-E, Stable Diffusion, Midjourney, Flux

Energy scales with resolution and diffusion steps — not tokens. A different measurement unit is required.

Audio / speech models

Whisper (transcription), TTS, ElevenLabs

Energy scales with audio seconds, not tokens.

Fine-tuning and training jobs

OpenAI fine-tune API, Hugging Face Trainer, PyTorch training loops

Token-based inference accounting does not apply to training. Use POST /api/v1/ingestion/ai-training instead — it accepts gpu_type, gpu_count, and compute_hours and estimates both operational (Scope 3 Cat 1) and embodied (Scope 3 Cat 2) GPU carbon.

Video generation

Sora, Runway, Pika

Out of scope — no energy benchmarks available.

Note

If you attempt to report an unsupported provider or call type, the API returns a 400 with an unsupported_provider or unsupported_call_type error code and a list of valid values. CI is never blocked — the emitci/report-ai action treats API errors as warnings.

AI Training Carbon

Use POST /api/v1/ingestion/ai-training to report the carbon footprint of GPU compute jobs — model fine-tuning, pre-training, and evaluation runs. This endpoint uses a GPU-hour energy model, not the token-based model used for inference.

Two carbon components are estimated and reported separately:

  • Operational CO₂ (Scope 3 Category 1) — GPU power draw × PUE × runtime × grid intensity. Same methodology as runner compute.
  • Embodied CO₂ (Scope 3 Category 2) — GPU manufacturing lifecycle CO₂, amortized over a 3-year (26,280 h) useful life. Example: an H100 carries ~25,000 kg CO₂e in manufacturing; an 8-GPU, 24-hour training job is allocated 8 × 25,000,000 g × 24 h / 26,280 h ≈ 182,648 g embodied CO₂.

Note

All figures are research-based estimates (Boavizta database, IEA manufacturing studies, Patterson et al. 2022). Embodied carbon uncertainty is ±50% and is labeled accordingly in the dashboard. Do not use for regulatory filings without independent verification.

REST API

curl -X POST https://api.emitci.com/api/v1/ingestion/ai-training \
  -H "Authorization: Bearer $EMITCI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "run_id":        '"$GITHUB_RUN_ID"',
    "provider":      "self_hosted",
    "model":         "llama-3-70b",
    "gpu_type":      "h100",
    "gpu_count":     8,
    "compute_hours": 24.0,
    "region":        "us-east-1"
  }'

// Response
{
  "ok": true,
  "co2_grams": 142800.0,
  "embodied_co2_grams": 182648.0,
  "energy_kwh": 368.0,
  "model": "llama-3-70b"
}

Supported GPU types

Named embodied carbon factors exist for: h100, h100-pcie, a100, a100-pcie, a10g, l40s, l4, v100, v100-pcie, t4, p100, p4, mi250x, mi300x, m2-ultra, m3-ultra, rtx-4090, rtx-3090. Unknown GPU types fall back to an A100-equivalent estimate.

Viewing training carbon

Training runs appear in Analytics → AI Carbon under the GPU Training Runs table, showing operational CO₂, embodied CO₂, energy, and water consumption per run. Training totals are also included in ESG PDF reports under AI Model Training Runs (Scope 3 Categories 1 & 2).

ESG reports

Generate audit-ready PDF reports from Dashboard → Reports → Generate ESG Report.

What's included

  • Total energy (kWh) and CO₂ (kg) for the selected period
  • Year-over-year comparison vs. previous period
  • Breakdown by repository, workflow, and runner type
  • AI inference carbon (Scope 3 Cat 1) — per-model breakdown of LLM and embedding API calls
  • AI training carbon (Scope 3 Cat 1) — GPU-hour operational energy for training runs
  • Embodied GPU carbon (Scope 3 Cat 2) — hardware manufacturing lifecycle CO₂, amortized over 3-year GPU lifetime
  • Water consumption (ESRS E3) — estimated data centre water usage per run
  • Methodology pin (GreenAlgorithms v2.2, CCF 2024, Electricity Maps, Boavizta)
  • SHA-256 hash for tamper-evidence; audit trail includes all AI carbon components

Compliance mappings

The ESG PDF report (schema v1.3.0) includes ESRS E1-6 and ESRS E3 (water, EU CSRD), GHG Protocol Scope 3 Categories 1 (runner compute, AI inference, AI training energy) and 2 (embodied GPU hardware), GWP values per IPCC AR6, and Green Software Foundation SCI v1.0. It focuses on CI/CD emissions — designed to slot into a broader GHG inventory. For a complete Scope 1, 2 & 3 disclosure, use the Emissions page compliance exports (CSRD CSV, CDP workbook, Methodology PDF) which cover all categories. California SB 253 and TCFD GHG metrics are also supported.

ESG data webhooks

Available on Enterprise plans. Instead of (or alongside) manually downloading PDFs, EmitCI can push monthly GHG data automatically to your sustainability platform on the first day of each month. Configure webhooks from Settings → Integrations → ESG Webhooks.

Supported targets:

Workiva

OAuth 2.0 client credentials token exchange, then POST to Workiva Sustainability API /metric-values. Maps CI emissions to ESRS E1-6 Scope 3 Cat 3 metric IDs. Requires a Workiva service account (client_id + client_secret).

Diligent ESG

Bearer token auth to the Diligent ESG (Accuvio) activities API. Maps CI emissions to the scope3_fuel_energy category with full month date range. Requires your Company ID and API bearer token from the Diligent ESG portal.

Watershed

Generic JSON POST. Pushes Scope 3 CI emissions, energy (kWh), run count, and SCI score as a monthly activity record.

Persefoni

Generic JSON POST structured for Persefoni's GHG data ingestion API. Maps CI energy to the appropriate emission factor category.

Salesforce Net Zero Cloud

Generic JSON POST to your Net Zero Cloud org. Requires an OAuth client configured in Salesforce.

Custom endpoint

POST to any HTTPS endpoint. Payload is a JSON object with energy_kwh, co2_kg, sci_score, run_count, period_start, period_end, and a per-repo breakdown.

Note

ESG webhook configuration requires Manager role or above. Failed deliveries are retried automatically with exponential backoff (up to 3 attempts). Delivery status is visible in Settings → Integrations → ESG Webhooks.

Auditor share links

Share a read-only, time-limited view of an ESG report with an external auditor — no account required. From Reports → Generate ESG Report, click Share with auditor (visible once you have entered an organisation name).

How it works

  • A 256-bit cryptographically random token is generated and stored. The URL contains the token — the token is the credential.
  • The recipient opens the link in any browser — no EmitCI account, no login.
  • They see the same ESG report (CO₂ totals, emissions by category, repository breakdown, methodology) in a clean read-only view.
  • Every access is recorded (timestamp + access count) and visible in the share dialog for your audit trail.

Expiry

Links expire after 30, 60, or 90 days (your choice at creation, maximum 90 days). After expiry the recipient sees a "Link unavailable" page. You can revoke any link instantly from the share dialog — recipients immediately receive a 410 Gone response.

PIN protection

Toggle Require PIN to view when creating a link to add a 4–8 digit numeric PIN. The PIN is hashed server-side (PBKDF2-HMAC-SHA256, 200,000 iterations) and never stored in plain text. After generating the link, the PIN is displayed once in the dialog — copy it and share it with the recipient via a separate channel (e.g. SMS or phone call) so that the link and the PIN travel independently.

  • Rate limiting: 5 wrong attempts per IP per 15 minutes — after that the IP is blocked for 15 minutes.
  • Lockout: 10 total wrong attempts (across any IP) permanently locks the link. The recipient sees "Link locked — contact the organisation for a new link."
  • Remaining attempts: Each wrong attempt shows the remaining count ("7 attempts remaining before this link is locked").

Reissuing a link

If a link is locked, expired, or the recipient has lost the PIN, click Reissue next to the link in the share dialog. This revokes the old link immediately and creates a new one with the same report parameters (same org name, period, detail level). You can optionally set a new PIN on the reissued link. The old URL stops working the moment you confirm the reissue.

Note

Auditor share links are available on all plans that include ESG reports (Team and Enterprise). Links do not consume your run quota and do not require the recipient to have a GitHub account.

Emissions — Full GHG Inventory

The Emissions page (Insights → Emissions, Manager+ only) is your complete GHG inventory in one place:

  • Scope 1 — Direct emissions: office gas, company vehicles, on-site generators, refrigerant leaks (manually declared per reporting year).
  • Scope 2 — Purchased electricity: annual kWh × grid emission factor, declared per reporting year with market-based or location-based attribution.
  • Scope 3 — Cloud compute — Production AWS/GCP/Azure emissions tracked via billing APIs (compute, storage, network, serverless, databases).
  • Scope 3 — CI/CD — Every GitHub Actions (and other CI) run measured in real time.
  • Scope 3 — Hardware — Lifecycle emissions from developer devices (manufacturer PCF data × headcount).
  • Scope 3 — SaaS tools — Spend-based estimates for Slack, GitHub, Jira, Datadog, and other SaaS subscriptions (DEFRA 2023 factors).

The page shows a grand-total CO₂ summary strip, by-layer stacked bars, by-provider breakdown, year-over-year badge vs your locked base year, and one-click compliance export buttons. Access is Manager and Admin only — the page contains revenue, electricity costs, and headcount data.

Cloud compute setup

Connect cloud billing accounts from Settings → Cloud (Admin only). After connecting, a nightly sync pulls the last 30 days of billing data; you can also trigger a manual sync at any time.

Supported providers

AWS

Access Key ID + Secret Access Key

Tracks EC2, Lambda, S3, RDS, and Data Transfer. Requires the CostExplorer read permission on your IAM user or role.

API: Cost Explorer (ce:GetCostAndUsage)

GCP

Service account key JSON (paste contents)

Tracks Compute Engine, Cloud Run, Cloud Storage, BigQuery, Cloud SQL, and Egress. Service account needs roles/billing.viewer and roles/monitoring.viewer.

API: Cloud Billing API + Cloud Monitoring

Azure

Client ID + Tenant ID + Client Secret

Tracks Virtual Machines, App Service, Blob Storage, SQL Database, and Bandwidth. App registration needs Cost Management Reader on the subscription.

API: Cost Management Query API

Plan limits

PlanCloud providers
FreeNot available
Starter1 provider
TeamUp to 3 providers
EnterpriseUnlimited

Energy estimation methodology

Energy is estimated using the Cloud Carbon Footprint (CCF) methodology:

  • Compute: TDP × 0.5 utilisation × usage hours × PUE ÷ 1000 (kWh). Instance TDP from CCF SPECpower benchmarks; 60+ instance types covered across AWS, GCP, and Azure.
  • Storage: 0.00065 kWh per GB-month (SSD average, CCF methodology).
  • Network: 0.06 kWh per GB transferred (IEA/SHIFT Project).
  • Serverless (Lambda/Cloud Run): GB-seconds converted to vCPU-hours via the AWS Lambda spec (1,769 MB per vCPU), then treated as compute.
  • Managed databases (RDS, Cloud SQL, Azure SQL): same TDP registry as compute, with storage component added.

PUE defaults: AWS 1.20, GCP 1.10, Azure 1.185. Carbon intensity uses the same lookup chain as CI/CD — OWID/Ember annual averages per region, continent fallback, then IEA global average (442 gCO₂/kWh).

Developer hardware lifecycle

Also under Settings → Cloud, declare your team headcount, primary device type, average refresh cycle (years), and remote work percentage. EmitCI computes annualised Scope 3 Category 2 hardware lifecycle emissions using verified manufacturer Product Carbon Footprint (PCF) data:

  • MacBook Pro 14″ M3 — 147 kg CO₂e (Apple PCF 2023)
  • MacBook Pro 16″ M3 — 226 kg CO₂e (Apple PCF 2023)
  • MacBook Air M2 — 147 kg CO₂e (Apple PCF 2022)
  • Dell XPS 15 — 330 kg CO₂e (Dell PCF 2022)
  • ThinkPad X1 Carbon — 270 kg CO₂e (Lenovo PCF 2022)
  • Surface Laptop 5 — 290 kg CO₂e (Microsoft PCF 2022)
  • Generic laptop — 300 kg CO₂e (conservative midpoint)
  • Desktop workstation — 600 kg CO₂e (conservative)

Note

Hardware lifecycle CO₂ is shown on the Emissions page and included in ESG PDF reports under "Scope 3 Category 2 — Purchased goods and services (hardware)". It is not included in the CI/CD run-level data or exports. You can also bulk-import headcount via CSV (Settings → Cloud → Hardware → Import CSV).

Scope 1 & Scope 2 declarations

On the Emissions page, expand the Scope 1 or Scope 2 card. Each declaration is stored per reporting year so FY2025 and FY2026 records coexist independently.

  • Scope 1: enter total CO₂e (tCO₂e) from direct sources and a source description. Common sources: natural gas boilers, company-owned vehicles, diesel generators, refrigerant leaks (HFCs).
  • Scope 2: enter annual kWh and select a grid emission factor. EmitCI converts to tCO₂e. For market-based reporting, enter a supplier-specific factor or renewable energy certificate (REC) factor instead of the grid average.
  • Third-party assurance: each declaration records assurance level (none / limited / reasonable), provider name, engagement date, and reference number per year. These fields auto-populate the Verification columns in your CDP Excel workbook export.

SaaS tool emissions

On the Emissions page → SaaS Tools card, declare monthly SaaS spend by tool. EmitCI converts to monthly CO₂ using DEFRA 2023 spend-based factors (0.14 kgCO₂e/USD for software and IT services). Preset suggestions: Slack, GitHub, Jira, Figma, Notion, Linear, Datadog, PagerDuty. Totals roll into the grand-total strip.

Base year locking

On the Emissions page → Base Year card, set a GHG Protocol base year. Once set, that period is frozen — the data retention sweep will not delete records from locked years, and the year-over-year badge on the Emissions page compares the current period against your base year total. You can also lock additional closed periods (e.g. lock FY2024 and FY2025 while still editing FY2026).

Compliance exports (Emissions page)

Available on Team and Enterprise plans from the Emissions page → Compliance Exports card. Also see the dedicated Compliance Exports section below for the full list.

  • CSRD CSV — all GHG categories across Scope 1, 2 and 3 with completeness statements. Formatted for ESRS E1-6 auditor review.
  • CDP export — Excel workbook (C6.5) + JSON (C6.1/C6.3/C6.5/C7). Verification columns auto-populated from assurance data.
  • EcoVadis export — JSON mapping to E1.1/E1.2/E2.1 of the EcoVadis Environment theme.
  • SECR export — UK mandatory Scope 1+2 tCO₂e, intensity ratio tCO₂e/£1M, YoY comparison.
  • TCFD / IFRS S2 — JSON covering all four TCFD pillars.
  • GHG Methodology PDF — auditor-grade boundary, factors, formulas, uncertainty bounds. Required for SB 253 and CSRD limited assurance engagements.
  • XBRL / iXBRL (Enterprise) — ESRS E1-tagged xHTML for digital CSRD filing on ESAP.

Note

The ESG PDF report (Reports → Generate ESG Report) is separate — it focuses on CI/CD Scope 3 Category 3.3 and is designed to slot into a broader disclosure. The compliance exports above cover the full GHG inventory.

Scope 3.1 — Purchased Goods & Services

The Purchased Goods & Services card on the Emissions page lets you declare supplier spend by category and converts it to CO₂ using EPA USEEIO v2.0 spend-based emission factors.

Supported categories and EEIO factors

Categorykg CO₂e / USD
Cloud services0.168
Software licences0.092
Hardware equipment0.450
Professional services0.085
Office supplies0.320
Marketing0.072
Travel & accommodation0.186
Utilities0.550
Other0.200

Entry methods

  • Manual entry: select a category, enter the annual spend in USD, and EmitCI shows a live CO₂ preview before you save. Each entry is stored per reporting year.
  • CSV upload: drag-drop a CSV file with columns category, spend_usd, notes. EmitCI parses the file, applies EEIO factors, and shows a preview table before saving. Available via POST /scope3/purchases/upload.

Note

Spend-based EEIO factors are sector-average estimates with ±40–50% uncertainty. They are suitable for initial Scope 3 inventory building and trend tracking, but not for regulatory filings that require supplier-specific primary data. Use the methodology notes field to document data quality for auditors.

Compliance Exports

EmitCI produces nine compliance-ready outputs. Access them from Reports → Compliance Exports (ESG PDF, CSRD CSV, CDP, GHG Methodology PDF) or from the Emissions page → Compliance Exports card (CDP JSON, EcoVadis, SECR, TCFD, XBRL). All require Team or Enterprise plan.

ESG PDF report

Team / Enterprise

CI/CD-centric ESRS E1-6 mapped PDF with SHA-256 integrity hash and run-level audit trail. Covers Scope 3 Cat 3.3 (CI runners), Cat 1 (AI inference), and Cat 2 (GPU embodied carbon).

CSRD CSV

Team / Enterprise

Machine-readable CSV covering all GHG categories across Scope 1, 2, and 3 with completeness statements. Formatted for ESRS E1-6 auditor review.

CDP export (Excel + JSON)

Team / Enterprise

Excel workbook (C6.5 format) with Verification columns auto-populated from assurance data. JSON format maps Scope 1 → C6.1, Scope 2 → C6.3, Scope 3 → C6.5, SBTi targets → C7.

EcoVadis JSON

Team / Enterprise

Maps EmitCI GHG data to EcoVadis Environment theme: E1.1 (GHG management policy), E1.2 (Scope 1 & 2 CO₂ tCO₂e), E2.1 (Scope 3 CO₂ tCO₂e).

SECR JSON (UK)

Team / Enterprise

UK Streamlined Energy and Carbon Reporting: Scope 1 + 2 tCO₂e, intensity ratio tCO₂e/£1M revenue (provide annual_revenue_gbp param), year-over-year comparison. Endpoint: GET /reports/export/secr?annual_revenue_gbp=X.

TCFD / IFRS S2 JSON

Team / Enterprise

All four TCFD pillars: Governance (board oversight of climate risk), Strategy (transition and physical risk scenarios), Risk Management (carbon risk process), Metrics & Targets (Scope 1/2/3 totals + carbon intensity). Endpoint: GET /reports/export/tcfd.

GHG Methodology PDF

Team / Enterprise

Auditor-grade document: organisational boundary, data source table, emission factor table (with references), calculation formulas, uncertainty bounds (±10–50% by source), and exclusion justifications. Required for SB 253 and CSRD limited assurance.

XBRL / iXBRL (ESAP)

Enterprise only

Inline XBRL xHTML tagged with ESRS E1 taxonomy elements — esrs:GrossScope1GHGEmissions, esrs:GrossScope2GHGEmissions, esrs:GrossScope3GHGEmissions, esrs:TotalGHGEmissions — for mandatory digital CSRD filing on the European Single Access Point (ESAP). Endpoint: GET /reports/export/xbrl.

Scenario Modeling (What-If)

The Scenario Modeler (Insights → Scenario) calculates how much CO₂ and estimated cost you could save by making specific changes. It reads your actual baseline emissions and projects the outcome across five independent levers.

Levers

  • Green Shift % — shift schedulable builds (cron workflows) to low-carbon grid windows. Saving = green_shift_pct × schedulable_run_fraction × avg_intensity_delta × runner_co2.
  • CI Optimise % — eliminate runner waste (idle steps, redundant jobs, over-provisioned runners). Saving = ci_optimize_pct × runner_co2_kg.
  • AI Model Switch — switch AI inference calls to a lower-carbon model. Recalculates using target model's energy factor vs your current mix.
  • Run Reduction % — reduce total workflow run count. Saving = runner_reduction_pct × runner_co2_kg.
  • Renewable % — add RECs or PPAs to cover a share of compute. Saving = renewable_pct × scope2_co2_kg.

API

POST /api/v1/scenario/calculate
{
  "green_shift_pct": 30,
  "ci_optimize_pct": 20,
  "ai_model_switch": "claude-haiku-4",
  "runner_reduction_pct": 0,
  "renewable_pct": 50
}

// Response
{
  "baseline_co2_kg": 1250.0,
  "projected_co2_kg": 743.5,
  "co2_saving_kg": 506.5,
  "co2_saving_pct": 40.5,
  "cost_saving_usd": 38.2,
  "trees_equivalent": 23.0,
  "breakdown": [
    { "lever": "Green Shift", "saving_kg": 187.5 },
    { "lever": "CI Optimise", "saving_kg": 250.0 },
    { "lever": "AI Model Switch", "saving_kg": 31.2 },
    { "lever": "Renewables", "saving_kg": 37.5 }
  ]
}

Note

Scenario results are estimates — the Modeler uses your trailing 30-day emissions as baseline. Actual savings depend on implementation, grid conditions, and run pattern changes. Cost savings are indicative (cloud list prices, mid-2025) — verify with your provider before making budget decisions.

SBTi Target Tracking

Create science-based carbon reduction targets (Insights → Targets) and track real progress against a linear trajectory.

Supported frameworks

  • SBTi 1.5°C — 42% absolute reduction by 2030 (Scope 1, 2 & 3). The current SBTi near-term target pathway.
  • SBTi Well-below 2°C — 30% absolute reduction by 2030.
  • Paris Aligned — 50% absolute reduction by 2035.
  • Custom — any base year, target year, reduction %, and scope coverage.

Progress calculation

For each target, EmitCI calculates the linear required CO₂ for the current year:

required = base_co2 × (1 − target_pct/100 × years_elapsed / total_years)

This is compared against trailing 12-month actual CO₂. If actual ≤ required, the target is on track.

API

POST /api/v1/targets
{
  "name": "SBTi Net-Zero 2030",
  "framework": "sbti_1_5",
  "base_year": 2024,
  "base_co2_kg": 1250.0,
  "target_year": 2030,
  "target_pct_reduction": 42,
  "scope_coverage": "1,2,3"
}

GET /api/v1/targets   // returns list + progress per target
DELETE /api/v1/targets/{id}

CSRD Double Materiality Assessment

The Double Materiality Assessment (Insights → Materiality) implements the CSRD/ESRS 1 requirement to assess both financial and impact materiality for each ESG topic before deciding which ESRS standards to apply.

The two axes

  • Financial materiality: does this topic create financial risks, opportunities, or dependencies for the company? Rate 1 (no impact) → 5 (highly material).
  • Impact materiality: does the company have significant actual or potential impacts on people or the environment through this topic? Rate 1 → 5.

Topics covered

  • E1 Climate Change
  • E2 Pollution
  • E3 Water & Marine Resources
  • E4 Biodiversity & Ecosystems
  • E5 Circular Economy
  • S1 Own Workforce
  • S2 Workers in the Value Chain
  • G1 Business Conduct

A topic is material if either axis score ≥ 3 (per ESRS 1 §4 threshold principle). Material topics are highlighted on the 2D scatter matrix and linked to the relevant ESRS disclosure requirements.

API

GET /api/v1/materiality/topics   // topic + question definitions
POST /api/v1/materiality         // save responses
// Body: { "responses": { "E1": { "score": 4, "notes": "..." }, ... } }
GET /api/v1/materiality          // latest assessment + matrix result

ESG Copilot

The ESG Copilot is a section-aware AI assistant on the Emissions page, accessible from the Scope 3.1 Purchased Goods & Services section ("Get help with this section" button).

How it works

When you open the copilot, it receives context about your current GHG inventory state — which categories you have filled in, which are missing, and what your existing totals are. It then acts as a guided ESG onboarding assistant, asking for one data point at a time and explaining where to find each figure in your financial systems or sustainability tools.

Examples of copilot prompts:

  • "You haven't entered business travel yet — for a 50-person tech company this is typically 10–30% of total Scope 3. Do you use Concur or Navan? I can tell you which expense categories to pull."
  • "Your cloud services spend looks low relative to your CI/CD runner count — do you want to add your AWS or GCP billing totals separately under cloud services?"
  • "Your Scope 1 declaration is empty — have you verified your office has no gas heating, company vehicles, or diesel generators?"

API

POST /api/v1/assistant/esg-guide
{
  "question": "What do I need for business travel?",
  "section": "scope3_1_purchases"
}

// Returns: { "answer": "...", "section": "..." }

Note

The ESG Copilot uses the same AI infrastructure as the dashboard assistant. It respects your BYOK key if configured. Available on Team and Enterprise. Rate limited to the same quota as the AI assistant (2,000 interactions/month on Team, 10,000 on Enterprise).

Settings

All settings are at app.emitci.com/settings. What you can change depends on your role — see the roles section below.

Team members & roles

Found under Settings → Team. There are three roles:

Admin

CTO, Engineering Director, the person who installed the GitHub App

Everything — billing, inviting members, assigning roles, custom runners, account deletion. The GitHub org owner is always admin regardless of role assignment.

Manager

DevOps Lead, Engineering Manager, Platform Engineer

Set carbon budgets and goals, configure the Green Window Scheduler, add BYOK API keys, manage teams and repo assignments, configure ESG webhooks, trigger backfill. Cannot touch billing or invite members.

Team Manager

Engineering Manager, Tech Lead

Manage carbon budgets and goals for their assigned team's repos only. Cannot touch org-level settings, billing, or other teams.

Member

Sustainability Officer, Finance, Legal, External Auditor, Engineer

Read-only. View the dashboard and all analytics, download reports and CSV exports. Cannot change anything.

Note

Before any roles are assigned, everyone who logs in is treated as admin (bootstrap mode). Once the first explicit role is recorded, unassigned users default to Member (read-only).

Integrations & BYOK

Found under Settings → Integrations. Connect live carbon data sources to improve CO₂ accuracy beyond the default IEA static averages (±40%).

±3%

WattTime

Free for US regions, paid for global. Marginal carbon intensity — most accurate for scheduling decisions.

±5%

Electricity Maps

Average grid intensity · 80+ countries. Adding your own key here (BYOK) immediately enables the Tonight's Green Windows dashboard widget and improves carbon intensity accuracy for scheduler decisions and ESG reports.

Anthropic / OpenAI

BYOK AI key for energy regression analysis, PR comment generation, and green scheduling advisories.

Keys are encrypted at rest with AES-256-GCM and never logged. You can remove a key at any time — the system falls back to the next provider in the chain automatically.

Custom runners

Found under Settings → Runners (Admin only). If you use self-hosted runners with labels not in EmitCI's built-in registry, declare their specs here: vCPU count, memory, and TDP (watts). This raises the confidence score from the AI-inferred default to a declared-spec reading.

Repository access

EmitCI never asks you to type repository names manually. Repositories appear automatically in all dropdowns (Groups, Budgets, Scheduler) based on which repos the GitHub App has been granted access to. To add or remove repositories:

  1. Go to GitHub → Settings → Applications → EmitCI → Configure
  2. Under Repository access, select All repositories or choose specific ones
  3. Save — EmitCI receives a webhook instantly and the repos appear in all Settings dropdowns

Note

If a repository is missing, it means the GitHub App has not been granted access to it yet. The fix is always on the GitHub side, not in EmitCI settings.

Groups

Found under Settings → Groups (Admin and Manager). Group repositories by department or squad for carbon attribution and chargeback reporting. Groups are used in Exports → Chargeback to split CI electricity costs across teams. Only repositories the GitHub App has access to appear in the Groups dropdown.

Notifications

Found under Settings → Notifications. Configure where alerts are sent when budgets are exceeded, anomalies are detected, or payments fail:

  • Email — sent to the billing email on the account. If no email is on file, an inline prompt appears on the Notifications page asking you to add one before the toggles are shown.
  • Slack — add a Slack webhook URL to receive real-time budget/anomaly alerts and the optional weekly digest in a channel of your choice
  • Weekly Digest — toggle to receive a Monday 09:00 UTC summary of MTD CO₂, cost, top 3 repos, and open recommendations in Slack

No email address? If you signed up without providing an email, EmitCI prompts you to add one during onboarding and on the dashboard if your trial is ending or anomalies were missed. You can also add or change your address any time under Settings → Account → Contact Email.

Billing

Found under Settings → Billing (Admin only). View your current plan, included runs, usage this month, and next renewal date. Upgrade, downgrade, or cancel from here. Annual billing (pay 10 months, get 12) is available for Starter and Team plans.

Slack Digest & Slash Command

EmitCI integrates with Slack in two ways: a weekly digest sent automatically to your configured webhook, and a /emitci slash command for on-demand queries.

Weekly digest

Every Monday morning, EmitCI sends a Block Kit summary to your Slack webhook URL. The digest includes:

  • Week CO₂ (kg) and energy (kWh) with week-over-week trend (↑ / ↓)
  • Top 3 repos by footprint
  • Open recommendations count with a link to the dashboard
  • Runner cost for the week (when available)

To enable: paste your Incoming Webhook URL in Settings → Notifications → Slack. Weekly digest is available on Team and Enterprise plans.

Anomaly and budget alerts

Anomaly alerts (energy spike > 2× baseline) and carbon budget breach alerts are also delivered to your Slack webhook. This works on Starter and above — no additional setup needed beyond adding the webhook URL. If you have configured a per-repo alert_slack_url in your carbon budget settings, that URL takes priority; otherwise the installation webhook is used.

Slash command

The /emitci slash command lets any team member query EmitCI from Slack without opening the dashboard.

/emitci            → month-to-date CO₂, energy, cost (ephemeral)
/emitci status     → same as above
/emitci help       → available commands

To enable (one-time setup):

  1. Create a Slack App at api.slack.com/apps
  2. Add a Slash Command: /emitciPOST https://api.emitci.com/api/v1/slack/command
  3. Copy the app's Signing Secret → give it to your operator to set as SLACK_SIGNING_SECRET on the server
  4. Go to Settings → Notifications → Slack → /emitci slash command and paste your Slack workspace Team ID (found in Slack → your workspace name → Settings → About this workspace)

All slash command requests are verified with HMAC-SHA256 before processing. Available on Team and Enterprise plans.

Extensions & CLI

EmitCI provides three optional tools that bring carbon estimates into your local development environment — no dashboard visit required.

VS Code Extension

Install EmitCI from the VS Code Marketplace. When you open a workflow file (.github/workflows/*.yml, .gitlab-ci.yml, bitbucket-pipelines.yml), the status bar shows a live estimate:

🌿 ~2.1g CO₂/run  |  $0.016/run
  • Updates on save — calls POST /api/v1/estimate with your parsed runner and steps
  • Hover over the status bar item to see top 3 optimization tips for your runner
  • Run EmitCI: Estimate workflow from the Command Palette for a full side-panel breakdown
  • Run EmitCI: Connect account to unlock “vs repo average” comparison

Note

The VS Code extension calls the public estimate endpoint — no account required. Your workflow YAML is parsed locally; only the runner label and step names (not your full YAML) are sent to the API.

Chrome Extension

Install EmitCI from the Chrome Web Store. On any GitHub Actions run page (github.com/*/actions/runs/*), a carbon badge is injected next to the run duration:

🌿 2.1g CO₂  ·  B

The extension popup shows your login status. When logged in, it displays the CO₂ and grade for the current GitHub repo. When logged out, it shows a “Connect EmitCI” CTA.

  • Badge colours: green (<1g), yellow (<5g), red (≥5g)
  • Badge data is cached for 5 minutes to avoid excess API calls
  • Works on both the single run page and the workflow run list page

CLI (npx emitci)

Run carbon estimates from your terminal without installing anything globally:

npx emitci estimate                             # auto-detect .github/workflows/*.yml
npx emitci estimate --file .gitlab-ci.yml        # specific file
npx emitci login                                 # save token to ~/.emitci/config.json
npx emitci status                                # MTD stats (requires login)
npx emitci repos                                 # list tracked repos
npx emitci compare                               # local estimate vs repo average

The estimate command works without login — it parses your workflow YAML locally and calls POST /api/v1/estimate. Output includes a table with CO₂, energy, grade, and an annualized projection.

Public API

The EmitCI public API is available at https://api.emitci.com/api/v1. No API key required for public endpoints. Rate-limited to 60 requests/minute per IP.

POST /estimate

Estimate the CO₂ footprint of any CI run.

POST /api/v1/estimate
Content-Type: application/json

{
  "runner": "ubuntu-latest",
  "duration_seconds": 600,
  "cpu_utilization": 0.65,   // optional, defaults to 0.65
  "region": "eastus"         // optional
}

// Response
{
  "runner": "ubuntu-latest",
  "energy_kwh": 0.000156,
  "co2_grams": 0.069,
  "carbon_intensity_gco2_per_kwh": 442,
  "tdp_watts": 7.94,
  "methodology": "GreenAlgorithms v2.2..."
}

GET /estimate/runners

List all supported runner labels with their energy specs.

GET /api/v1/estimate/runners

// Returns array of:
{
  "label": "ubuntu-latest",
  "provider": "github",
  "vcpus": 2,
  "memory_gb": 7,
  "min_watts": 1.28,
  "tdp_watts": 7.94,
  "processor_type": "CASCADE_LAKE",
  "cloud_provider": "azure",
  "region_hint": "eastus",
  "data_source": "ccf_2024"
}

GET /badge/{owner}/{repo}.svg

Embeddable SVG badge showing SCI grade and average CO₂/run. Updated hourly. Suitable for GitHub READMEs.

GET /runs/latest

Fetch the most recent workflow run data for a repo. Used by the Measure Action and Chrome Extension.

GET /api/v1/runs/latest?repo=owner/repo

// Response
{
  "co2_grams": 2.14,
  "energy_kwh": 0.00485,
  "grade": "B",
  "runner_label": "ubuntu-latest",
  "workflow_name": "CI",
  "started_at": "2026-07-11T09:12:00Z"
}

GET /public/leaderboard

Fetch the public opt-in leaderboard. Requires no authentication. Cached for 1 hour. Rate-limited to 60 req/min.

GET /api/v1/public/leaderboard?language=Python&limit=20

// Response array of:
{
  "rank": 1,
  "repo_name": "owner/repo",
  "language": "Python",
  "avg_co2_grams": 0.42,
  "grade": "A",
  "run_count": 284,
  "trend": "improving"  // "improving" | "stable" | "worsening"
}

GET /dora/{owner}/{repo}

Fetch DORA metrics snapshots for a specific repo. Requires authentication.

GET /api/v1/dora/owner/repo?weeks=12

// Response
{
  "repo": "owner/repo",
  "dora_tier": "Elite",
  "snapshots": [
    {
      "period_start": "2026-07-07",
      "deployment_count": 14,
      "deployment_frequency": 2.0,
      "lead_time_hours": 0.8,
      "change_failure_rate": 0.02,
      "mttr_hours": 0.5,
      "co2_per_deployment_g": 1.21,
      "cost_per_deployment": 0.009
    }
  ]
}

Webhook events

EmitCI listens to GitHub App webhook events. You don't need to configure anything — webhooks are set up automatically when you install the app.

Events consumed

workflow_run: completed

Triggers ingestion of the run — energy estimation, rule engine, PR comment, anomaly detection.

installation: created

Registers the installation and fetches initial repository list.

installation: deleted / suspend

Marks the installation as suspended in the database.

Note

All webhooks are verified with HMAC-SHA256 using your GitHub App's webhook secret. Requests with invalid signatures are rejected with HTTP 401.

Exports & data

Export your raw workflow run data from Settings → Exports.

  • CSV — one row per workflow run with energy, CO₂, duration, runner, branch, event type
  • Excel (.xlsx) — same data with formatting and summary sheet
  • ESG PDF — audit-ready report (see ESG reports section)
  • ESG data webhooks — push monthly GHG data automatically to Workiva, Diligent ESG, Watershed, Persefoni, Salesforce Net Zero, or a custom endpoint (Enterprise only; see ESG reports → ESG data webhooks)
  • Team chargeback (Enterprise) — per-team CO₂ attribution for internal carbon accounting

Data retention

Free: 30 days. Starter: 90 days. Team: 1 year. Enterprise: up to 3 years. Retention is enforced nightly — runs older than the plan limit are permanently deleted. Cancelled paid subscriptions retain data for 1 year as a re-engagement window.

GDPR & data deletion

EmitCI is GDPR compliant. No personally identifiable information is stored beyond what GitHub provides in the webhook payload (GitHub login, organisation name, repository name).

Deleting your data

Go to Settings → Account → Delete Account. This immediately and permanently deletes all workflow runs, jobs, steps, recommendations, budgets, and SCI scores associated with your installation, fulfilling your right to erasure under GDPR Article 17.

Alternatively, email [email protected] with your GitHub organisation name.

Enterprise

The Enterprise plan is designed for regulated industries, large engineering organisations, and teams with compliance or procurement requirements that go beyond what a self-serve subscription covers. Book a demo at /enterprise or email [email protected].

Multi-org support

Connect multiple GitHub organisations to a single EmitCI account — one dashboard, one bill, one ESG report. Useful for companies with separate GitHub orgs for different business units, subsidiaries, or product lines. Each org's runs are tracked independently but aggregated in the top-level view.

Data retention

Enterprise retention is 3 years — covers the full CSRD 3-year baseline window and California SB 253 lookback requirements.

Extended backfill

Enterprise accounts can import up to 2 years of historical CI run data on initial setup — vs. 90 days on all other plans. This lets you establish a longer baseline for ESG year-over-year comparisons from day one. Arrange this when booking your demo.

SSO / SAML + SCIM provisioning

Single Sign-On via Okta, Azure AD, or any SAML 2.0-compatible identity provider (planned). SCIM provisioning will automatically sync user accounts and role assignments from your IdP — when an employee leaves, their EmitCI access is revoked automatically without manual intervention. Email [email protected] to join the SSO early access list.

IP allowlisting

Restrict dashboard and API access to approved corporate IP ranges or CIDR blocks. Configured per-installation by the EmitCI team during onboarding.

Compliance & legal

Custom MSA + DPA

Negotiate a Master Services Agreement and Data Processing Agreement tailored to your legal and procurement requirements. Includes SLA commitments, sub-processor disclosure, and a security addendum.

Security questionnaire

A pre-filled vendor security questionnaire is available for Enterprise customers going through procurement review. Email [email protected] — we respond within 2 business days.

Pre-filled security questionnaire

A completed vendor security questionnaire (standard SIG/CAIQ format) is available for Enterprise customers going through procurement review.

90-day deprecation notice

EmitCI commits to 90 days advance notice before removing or making breaking changes to any API endpoint, webhook schema, or export format — giving your integrations time to adapt.

Billing & invoicing

Enterprise customers can pay annually by invoice with a purchase order number — no credit card required. Invoices are net-30 and include itemised line items for the base subscription, run overage, and any add-ons. Contact [email protected] to set up invoiced billing.

Priority runner classification

When an unrecognised self-hosted runner label is detected on an Enterprise installation, the AI classification and registry patch runs within 1 hour — vs. the standard 24-hour nightly batch for all other plans.

Still have questions?