# Carbon Reduction Plan Check

A supplier's published Carbon Reduction Plan read against the PPN 006 template, part by part.

Finds the plan from a homepage or reads its URL; eight template parts found / not found / couldn't tell; which Scope 3 categories are reported; the plan's date; the gaps.

Since 24 February 2025 a supplier bidding for a central-government contract over £5 million a year must have published a Carbon Reduction Plan on its UK website, to the government's template: a commitment to net zero by 2050, a baseline year and the current year in tCO2e, Scope 1 and 2, Scope 3 categories 4, 5, 6, 7 and 9, carbon reduction projects, a director's sign-off, updated within a year (PPN 006 and its technical standard; the NHS asks the same of its suppliers). This endpoint finds the plan from the homepage (PPN 006 asks for it to be signposted there) or reads the plan's own address, and says which parts are there and which aren't. A check of the plan's form, said plainly: it can't say whether the figures are right.

- Price: 4 credits (8 on the free plan)
- Page: https://meetkatalis.com/apis/crp-check
- OpenAPI: https://meetkatalis.com/openapi.yaml

## Endpoints

- `GET /api/v1/crp-check?url=…` — The plan (page or PDF) or the supplier's homepage

## Call it

```bash
curl -H "x-api-key: $KATALIS_API_KEY" \
  "https://meetkatalis.com/api/v1/crp-check?url=https://www.softcat.com"
```

```javascript
const res = await fetch("https://meetkatalis.com/api/v1/crp-check?url=https://www.softcat.com", {
  headers: { "x-api-key": process.env.KATALIS_API_KEY },
});
if (!res.ok) throw new Error(`Katalis ${res.status}: ${await res.text()}`);
console.log(await res.json());
```

```python
import os, requests

r = requests.get(
    "https://meetkatalis.com/api/v1/crp-check?url=https://www.softcat.com",
    headers={"x-api-key": os.environ["KATALIS_API_KEY"]},
    timeout=60,
)
r.raise_for_status()
print(r.json())
```

## Example response (a real reply)

```json
{
  "url": "https://www.civica.com/globalassets/7.document-downloads/1.global-docs/misc/civica-carbon-reduction-plan-fy24-25.pdf",
  "foundFrom": "https://www.civica.com/en-us/policies-and-statements/sustainability/",
  "found": true,
  "company": "Civica UK Ltd.",
  "planDate": "2026-03-19",
  "meetsTemplate": false,
  "partsMet": 7,
  "partsTotal": 8,
  "parts": {
    "netZeroBy2050": { "found": true, "note": "Net zero by 2040, within the 2050 limit" },
    "baselineYearEmissions": { "found": true, "note": "Baseline year emissions for FY 22/23 reported." },
    "currentYearEmissions": { "found": true, "note": "Current year emissions for FY 24/25 reported." },
    "scope1and2": { "found": true, "note": "Scope 1 and Scope 2 emissions reported." },
    "scope3Categories": { "found": false, "note": "Categories 5, 6, 7 reported; 4, 9 not found" },
    "reductionProjects": { "found": true, "note": "Multiple completed and planned carbon reduction initiatives listed." },
    "directorSignOff": { "found": true, "note": "Signed off by the CEO." },
    "updatedWithinYear": { "found": true, "note": "Dated 2026-03-19" }
  },
  "scope3Found": ["5", "6", "7"],
  "gaps": ["Scope 3 categories 4 (upstream transport), 5 (waste), 6 (business travel), 7 (employee commuting) and 9 (downstream transport)"],
  "reading": "The plan has 7 of the 8 parts the PPN 006 template asks for. Not found: Scope 3 categories 4 (upstream transport), 5 (waste), 6 (business travel), 7 (employee commuting) and 9 (downstream transport)."
}
```

## What you'd build with it

- **Bid teams.** Before the bid: does our plan have every part the template asks for, and is it dated this year?
- **Buyers and primes.** Dozens of bidders' plans checked for completeness in minutes, not an afternoon.
- **Bid tools.** A PPN 006 flag on every supplier profile.

## Why this one

- **The template's parts, one by one.** Eight named parts from PPN 006's technical standard, each found, not found or couldn't tell, with a short note.
- **Found from the homepage.** PPN 006 asks for the plan to be signposted there; the check starts where the buyer would.
- **Form, not truth, and says so.** Completeness against the template, never a judgement on the emissions figures.

## Conventions

- Auth: `x-api-key: kat_live_…` on every request (free key at https://meetkatalis.com/developers: a verified email and mobile, 100 credits a month, no card).
- One credit balance across every API; each endpoint's price is on its page and in `x-credits` in https://meetkatalis.com/openapi.yaml.
- Keys are camelCase everywhere. A registered company is `company: { name, number, status, statusDetail?, filingsOverdue? }` on the register endpoints; the enrichment family (enrich, score, assess, brand-kit, ai-visibility, tender-match) keeps `business` / `profile` with `companyNumber`.
- Every error has `code` and `requestId`; every reply an `x-request-id` header; a charged reply `x-credits-remaining`; a reply that gave credits back `x-credits-refunded`. Missing = 404 with `query`.
- Burst ceiling 60 requests a minute per key (429, `Retry-After`, no credits used). A failure on our side (5xx) gives the call's credits back.
- Company data contains public sector information licensed under the Open Government Licence v3.0.

Provided "as is"; results come from public sources and, in places, AI, and may be inaccurate or out of date; not legal, professional or credit advice. Terms: https://meetkatalis.com/apis/terms