---
title: "Browse/search the corpus (open — no key, values included)"
method: GET
path: "/v1/factors"
tags: ["Factors"]
---

# Browse/search the corpus (open — no key, values included)

`GET /v1/factors`

## Request

- Base URL: `https://api.greencalculus.com`
- URL: `https://api.greencalculus.com/v1/factors`
- Auth: none required

## Query parameters

- `search` string
- `section` string
- `key_prefix` string
- `family` string
- `limit` integer
- `offset` integer
- `cursor` string

## Response `200`

Matching factor keys, names, sections. meta.warnings explains any filter that matched nothing.

- FactorList: Browse/search results. Open — no key, no quota. Values ARE returned on this route. Use /v1/factors/{key} when you want one row plus its audit envelope (provenance, licence, verification) or a version pin via ?as_of=.
  - `meta` object, required
    - `gc_version` string
    - `gc_updated` string, date
    - `total` integer: Rows matching the filter.
    - `canonical_total` integer: Rows in the whole corpus at this version.
    - `returned` integer
    - `offset` integer
    - `next_cursor` string, nullable: base64(canonical_key). Prefer this over offset — stable across data-version bumps, and required to page relevance-ordered search results.
    - `filters` object: The filters as the endpoint understood them — echoed back so a silent mismatch is visible.
    - `warnings` string[]: Why a filter matched nothing. A 200 with an empty array and a warning is the normal way this endpoint says "no such thing".
    - `licences` object: One record per DISTINCT source on this page, keyed by source id — so the licence detail is carried once rather than repeated on every row. Join via factors[].source.id. `attribution` is present ONLY where the licence grants redistribution and requires a credit; its absence on a non-redistributable row is deliberate.
  - `factors` FactorRow[], required
    - `key` string
    - `name` string, nullable
    - `section` string, nullable
    - `activity_type` string, nullable
    - `factor` object
      - `value` number, nullable
      - `unit` string, nullable
      - `gas` string, nullable
      - `basis` string, nullable
      - `gwp_set` string, nullable
      - `gwp_set_basis` string, nullable: How we know the GWP set — "published" where the source states it, "inferred" where we deduced it. null means not recorded, which is deliberately NOT the same as published.
      - `country_iso3` string, nullable
      - `uncertainty` Uncertainty, nullable: The publisher's own stated range, never derived by us. null means NOT RECORDED — explicitly not a claim that no uncertainty exists.
        - `low` number, nullable
        - `high` number, nullable
        - `basis` string, nullable
        - `published_as` string, nullable: The publisher's exact wording, e.g. "±30-50%".
      - `uncertainty_basis` string, nullable: "none_published" means the publisher states plainly that no range exists. null means not recorded — a different fact from silence.
    - `source` SourceRef: Provenance to the line. Carried on 100% of rows — where in the source document the value was read, not just which document. A workbook cell where the publisher ships a workbook (DEFRA); otherwise the table, annex clause or page they did ship (IPCC, CBAM, ECCC).
      - `id` string
      - `cell_ref` string
      - `retrieved` string, date
    - `scope` object, nullable
      - `ghg_protocol` string, nullable
      - `category` string, nullable
    - `components` object, nullable: Per-gas decomposition keyed by gas (co2, ch4, n2o…), each with its own cell_ref. Lets a consumer re-base AR5↔AR6 without us.
    - `note` string, nullable: Includes what the publisher did NOT provide, stated verbatim.
    - `citation` FactorCitation: The canonical citation for one factor row, built by the API (src/citation.ts) and printed VERBATIM by every official client (Sheets add-in, JS and Python SDKs, MCP). Format: "<factor name>. <source name> — <publisher>, cell <cell_ref>, retrieved <date>. via GreenCalculus data version <version>, factor <key>. <proof URL>". On GET /v1/factors/{key} the version is the one actually SERVED, so a ?as_of= lookup cites the pin. Present on rows from 2026-09-09. The format is a published specification, free for anyone to implement against their own data: https://greencalculus.com/developers/citation/
      - `text` string
      - `source_id` string, nullable
      - `cell_ref` string, nullable
      - `version` string, nullable
      - `proof_url` string, nullable
    - `licence` object: The licence this row is published under, and whether the Business redistribution grant covers it. Present on the open browse from MB v2026.181 — the full terms, the required credit and the publisher are listed once per source under meta.licences. Absent (not empty) where no licence is on record: an empty value would read as "no licence applies".
      - `name` string
      - `redistributable` boolean

## Other responses

- `400`: gc_unknown_param — a query parameter this endpoint does not accept. The message names the offender and lists the accepted set. Other 400s: gc_limit_too_large, gc_offset_invalid, gc_cursor_invalid, gc_section_conflict.

---

[API](https://skmtc.dev/greencalculus/apis/greencalculus-api.md) · [All operations](https://skmtc.dev/greencalculus/apis/greencalculus-api/llms.txt) · [OpenAPI document](https://skmtc.dev/greencalculus/apis/greencalculus-api/revisions/2f742325958c?raw)
