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).
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 comparisonWhat it does
- Calls
GET /api/v1/runs/latestat 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_exceedis 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_kWhWhere:
min_watts/max_watts— per-runner idle/peak watts from CCF SPECpower data, scaled by vCPU countcpu_util— inferred per step type (0.10–0.95); defaults to 0.65 if unrecognised; adjustable via the public estimator APImem_util— inferred per step type (0.10–0.80); defaults to 0.50 for unrecognised stepsPUE— 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_dependenciesCache dependency installation
Detects npm install, pip install, bundle install etc. running without cache hits. Caching saves ~85% of the step's energy.
oversized_runnerDownsize 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_opportunitySwitch to ARM runners
Detects x86 runners on repos without platform-specific native code. ARM64 runners (arm-2core) are 37% cheaper per minute.
serial_parallelizable_jobsParallelize independent jobs
Detects 3+ jobs with no needs: dependencies that could run in parallel, reducing feedback time.
no_path_filtersAdd path filters
Detects push runs triggered by documentation-only changes (*.md, docs/**). paths-ignore can skip these entirely.
redundant_runsCancel redundant runs
Detects the same commit SHA triggering multiple runs. concurrency: cancel-in-progress: true fixes this.
always_failing_stepsFix chronically failing steps
Detects steps failing >50% of the time — all energy spent before the failure is wasted.
macos_to_linux_opportunityReplace 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_stepsShard 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_opportunityShard 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_triggerRemove 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_sprawlPrune 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_ratioReview 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_stepsRemove 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_bloatReduce 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_regionMove 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_concurrencyAdd concurrency group
Detects workflows without a concurrency: block. Without it, multiple pushes queue up unlimited parallel runners.
fail_fast_disabledRemove fail-fast: false
Matrix jobs with fail-fast: false keep running when one variant fails, burning minutes on a broken build.
matrix_explosionPrune matrix build combinations
Detects matrix strategies with ≥ 15 Cartesian combinations. Pruning to ≤ 8 meaningful combinations reduces queue time and cost.
docker_layer_cacheEnable 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_keyFix 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_jobAdd 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_filtersAdd 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_shallowUse shallow checkout
Deep git checkouts (fetch-depth: 0) are rarely needed. fetch-depth: 1 reduces clone time and bandwidth.
missing_job_timeoutAdd job timeout
Jobs without timeout-minutes can run for 6 hours on a hung process before GitHub cancels them.
artifact_retentionShorten artifact retention
Artifacts using the default 90-day retention incur storage charges. retention-days: 7 is sufficient for most build outputs.
high_frequency_scheduleReduce scheduled run frequency
Cron schedules running more than once per hour waste runners on stale checks. Reduce to hourly or daily.
windows_runner_taxReplace 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_timeoutTighten 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_redundancyReduce 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_modelUpgrade 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_modelDownsize 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_unchangedCache 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_arbSwitch 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_batchingBatch 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_frequencyReduce 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_outputAdd 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_cacheCache 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:
- Your organisation's own key added in Settings → Integrations → Electricity Maps (BYOK — takes priority)
- 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
Deployment Frequency
How often the team deploys to production. Elite: ≥1/day. High: ≥1/week.
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%.
MTTR
Mean time to restore service after a failure. Elite: <1h. High: <24h.
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 | completionThe 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_gramsandai_energy_kwhalongside 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 APIgpt-4o · gpt-4o-mini · gpt-4 · gpt-3.5-turbo · text-embedding-3-small · text-embedding-3-large · text-embedding-ada-002
Anthropic
managed APIclaude-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
gemini-1.5-pro · gemini-1.5-flash · gemini-2.0-flash · gemini-2.5-pro
Cohere
managed APIcommand-r-plus · command-r · embed-english-v3
Mistral
managed APImistral-large · mistral-small · mistral-7b
Ollama / vLLM / self_hosted
self-hostedllama-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-8B → llama-3-8b), and Ollama colon tags (llama3:8b → llama-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
| Plan | Cloud providers |
|---|---|
| Free | Not available |
| Starter | 1 provider |
| Team | Up to 3 providers |
| Enterprise | Unlimited |
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
| Category | kg CO₂e / USD |
|---|---|
| Cloud services | 0.168 |
| Software licences | 0.092 |
| Hardware equipment | 0.450 |
| Professional services | 0.085 |
| Office supplies | 0.320 |
| Marketing | 0.072 |
| Travel & accommodation | 0.186 |
| Utilities | 0.550 |
| Other | 0.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 / EnterpriseCI/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 / EnterpriseMachine-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 / EnterpriseExcel 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 / EnterpriseMaps 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 / EnterpriseUK 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 / EnterpriseAll 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 / EnterpriseAuditor-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 onlyInline 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 resultESG 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%).
WattTime
Free for US regions, paid for global. Marginal carbon intensity — most accurate for scheduling decisions.
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:
- Go to GitHub → Settings → Applications → EmitCI → Configure
- Under Repository access, select All repositories or choose specific ones
- 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):
- Create a Slack App at api.slack.com/apps
- Add a Slash Command:
/emitci→POST https://api.emitci.com/api/v1/slack/command - Copy the app's Signing Secret → give it to your operator to set as
SLACK_SIGNING_SECRETon the server - 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/estimatewith 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: completedTriggers ingestion of the run — energy estimation, rule engine, PR comment, anomaly detection.
installation: createdRegisters the installation and fetches initial repository list.
installation: deleted / suspendMarks 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?