---
title: "Calculate a product's footprint and store it as an immutable snapshot"
method: POST
path: "/pcf/products/{productId}/calculations"
---

# Calculate a product's footprint and store it as an immutable snapshot

`POST /pcf/products/{productId}/calculations`

Refused with 409 PCF_INCOMPLETE while any BOM line is unresolved (no factor, or a unit that does not convert), or when the BOM is empty. Requires org.write_data.

## Response `201`

Stored calculation

- PcfCalculationResponse
  - `data` PcfCalculation, required — A calculated footprint. id, createdAt and createdBy are null for a preview.
    - `boundary` string, required
    - `complete` boolean, required
    - `createdAt` string, date-time, nullable, required
    - `createdBy` string, nullable, required
    - `declaredQuantity` number, double, required
    - `declaredUnit` string, required
    - `factorLibrary` PcfFactorLibrary, required
      - `available` boolean, required
      - `boundary` string, nullable
      - `impactCategory` string, nullable
      - `lciaMethod` string, nullable
      - `name` string, required
      - `regionCodes` string[], required
      - `systemModel` string, nullable
      - `version` string, nullable
    - `id` string, nullable, required
    - `kgCo2ePerDeclaredUnit` number, double, required
    - `lines` PcfCalculationLine[], required
      - `convertedQuantity` number, double, nullable, required — The quantity in the factor's activity unit.
      - `description` string, required
      - `factor` PcfFactor, required
        - `activityCode` string, required
        - `activityUnit` string, required
        - `categoryName` string, required
        - `factorValue` number, double, required
        - `id` string, required
        - `name` string, required
        - `referenceProduct` string, nullable
        - `regionCode` string, required
        - `releaseId` string, required
        - `releaseName` string, required
        - `releaseVersion` string, required
        - `releaseYear` integer, nullable
        - `scope` integer, required
        - `sourceLocation` string, nullable
        - `sourceUuid` string, nullable
        - `split` PcfEmissionSplit — Fossil, biogenic and land-use-change parts of a GWP100 value, in the same unit as the value they split.
          - `biogenic` number, double, required
          - `fossil` number, double, required
          - `landUseChange` number, double, required
        - `unit` string, required
      - `kgCo2e` number, double, nullable, required
      - `position` integer, required
      - `quantity` number, double, required
      - `quantityUnit` string, required
      - `resolved` boolean, required — False when the line has no factor or its unit does not convert; it is then left out of the totals.
      - `split` PcfEmissionSplit, required — Fossil, biogenic and land-use-change parts of a GWP100 value, in the same unit as the value they split.
        - `biogenic` number, double, required
        - `fossil` number, double, required
        - `landUseChange` number, double, required
      - `stage` 'materials' | 'packaging' | 'transport' | 'energy' | 'waste', required
    - `methodVersion` string, required
    - `productId` string, required
    - `productName` string, required
    - `regionCode` string, nullable, required
    - `split` PcfEmissionSplit, required — Fossil, biogenic and land-use-change parts of a GWP100 value, in the same unit as the value they split.
      - `biogenic` number, double, required
      - `fossil` number, double, required
      - `landUseChange` number, double, required
    - `stages` PcfStageTotal[], required
      - `kgCo2e` number, double, required
      - `share` number, double, required — The stage's fraction of the total, 0 when the total is 0.
      - `stage` 'materials' | 'packaging' | 'transport' | 'energy' | 'waste', required
    - `totalKgCo2e` number, double, required — Footprint of declaredQuantity declaredUnit of product.
    - `warnings` PcfWarning[], required
      - `code` 'line_unmatched' | 'unit_incompatible' | 'regional_proxy' | 'negative_factor' | 'missing_split' | 'zero_quantity', required
      - `linePosition` integer, nullable, required
      - `message` string, required

## Other responses

- `401` — Unauthorized
- `403` — Forbidden
- `404` — Not Found
- `409` — Conflict

## Changes

- **2026-10-01** `b4751fd15397` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/greentally/apis/esgai-api/changes/pcf/products/:productId/calculations/post.md)

---

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