PACT Initiative Developer Documentation

Living Document,

This version:
https://wbcsd.github.io/introduction/
Feedback:
public-dev@pathfinder.sine.dev with subject line “[pact-dev-docs] … message topic …
Issue Tracking:
GitHub
Editor:

Abstract

To reach net zero emissions before 2050, we need all business to measure, account for and disclose carbon emissions as a first step to reducing them. The PACT (Partnership for Carbon Transparency) Initiative is cross-value chain initiative to define and accelerate credible, verified primary emission data exchange.

1. Introduction

This document aims to provide guidance to those developing PACT Conformant Solutions. It is not self-contained and does not replace the Technical Specifications. It can nevertheless be used as the main source for developers, as it links to the Technical Specifications whenever needed.

1.1. Our goal

The Partnership for Carbon Transparency (PACT) seeks to accelerate decarbonization through the creation of transparency on emissions in the value chain. For that end, we need an open and global network of interoperable solutions for the secure, peer-to-peer exchange of accurate, primary and verified product emissions data — across all industries and value chains. The § 1.2 Pathfinder Network aims at being precisely this network of interoperable solutions. In order to establish it and take it further, we propose the adoption of the § 1.3 Pathfinder Framework methodology. Following it, we shall be able to exchange § 1.4 Product Carbon Footprint (PCF)s through entire supply and value chains, hopefully reaching net zero emissions before 2050.

1.2. Pathfinder Network

The Pathfinder Network is a concept created by the Partnership for Carbon Transparency and powered by the World Business Council for Sustainable Development (WBCSD). It refers to the data exchange infrastructure that enables organizations to connect across value chains and industries to share Product Carbon Footprint (PCF) data. The Network creates interoperability between technology solutions and industry-focused data exchange platforms, meaning organizations are flexible in their choice of provider. It can be seen as a sort of convener or facilitator. In the simplest of terms, through the Pathfinder Network, we aim to create the “internet for emissions data” — the common nexus for all organizations to connect seamlessly, exchange and derive insights from emissions data.

1.3. Pathfinder Framework

The Pathfinder Framework provides industry-agnostic methodological guidance for the calculation of product-level emissions data. The adoption of the methodology described in Pathfinder Framework: Guidance for the Accounting and Exchange of Product Life Cycle Emissions makes it possible to exchange Product Carbon Footprint data, hence being essential for the establishment and growth of the Pathfinder Network. The technical counterpart of this methodology is described in detail in the Technical Specifications, which will be referred to several times throughout this document.

1.4. Product Carbon Footprint (PCF)

A Product Carbon Footprint is the carbon (equivalent) emissions relating to a product. Products can be any kind of item exchanged between entities, including “pieces”, metric or volumetric quantities of a product, etc.

Within the context of the Pathfinder Framework, Product Carbon Footprints are represented as ProductFootprint objects. Details about ProductFootprint, including a description of all its fields, can be found here. An example of ProductFootprint can be found in the § 4.2.1 ProductFootprint Example section.

1.5. What do I need to implement to exchange PCFs through the Pathfinder Network?

In order to exchange Product Carbon Footprint (PCF) data through the Pathfinder Network, a solution must conform to the Pathfinder Technical Specifications. In a nutshell, this amounts to implementing an HTTP REST API, with three mandatory actions (§ 3.1.1 Authenticate, § 3.1.2 ListFootprints, and § 3.1.3 GetFootprint) and one optional action (§ 3.2.1 Events). Below (in section § 2 Example API - Plug and Play) you will find an example API which should give you a more concrete idea of what is required. You will also find detailed instructions on how to build your own solution’s API (in section § 3 Overview of the Technical Specification), by repeatedly referring to the Technical Specifications. In the appendix, you will also find references to documentation that will help you make sure your solution meets the necessary requirements.

Once your solution is ready, do not forget to submit it to the Online Catalog and test it in one of PACT’s monthly connectathons.

2. Example API - Plug and Play

The following is an example implementation of an HTTP REST API conforming to the Pathfinder Technical Specifications.

A demo version of this API is available at https://api.pathfinder.sine.dev and will be used in all examples below. If you want to run the example API locally, you can also do so, by cloning this repository and following the instructions provided here.

A Swagger UI visualization is available here.

Bellow is a list of all endpoints exposed by this example:

2.1. Authentication

The authentication flow starts with a GET request to the /.well-known/openid-configuration endpoint, which returns the OpenId Provider Configuration Document. In that JSON document, the value of the token_endpoint field is the endpoint used to retrieve an access_token, i.e., the AuthEndpoint.

Authentication flow: AuthEndpoint discovery
Endpoint

/.well-known/openid-configuration

HTTP request

GET

Example request (cURL)
curl -X 'GET' \
'https://api.pathfinder.sine.dev/2/.well-known/openid-configuration' \
-H 'accept: application/json'
Example response
{
    "issuer": "https://api.pathfinder.sine.dev/",
    "authorization_endpoint": "https://api.pathfinder.sine.dev/2/auth/token",
    "token_endpoint": "https://api.pathfinder.sine.dev/2/auth/token",
    "jwks_uri": "https://api.pathfinder.sine.dev/2/jwks",
    "response_types_supported": [
        "token"
    ],
    "subject_types_supported": [
        "public"
    ],
    "id_token_signing_alg_values_supported": [
        "RS256"
    ]
}

Authentication is made through a POST request to the AuthEndpoint /auth/token with id (aka client_id / username) hello and secret (aka client_secret / password) pathfinder.

Details about the Authenticate action, the authentication process, and the authentication protocol used can be found in section § 3.1.1 Authenticate.

Action

Authenticate

Endpoint

/auth/token

HTTP request

POST

Credentials

id: hello
secret: pathfinder

Example request (cURL)
curl -X POST --user hello:pathfinder \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials"  https://api.pathfinder.sine.dev/2/auth/token
Example response
{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6ImhlbGxvIn0.hUDxqoQR0e4b5emxYl1M0nUMuy1w_VjrB0G3s2ul-oqzNEJnUbgkI9tzo1iGFkMkipSoEZyyOpmUd0IE-kswdaRNmTebn5aGxeARLh3OoknHWyRizU7ZNf4f1ow3Z0wpWfXHH6vxP1IyMTjuk5E1oFqpf2vBteHMrUg0KiZf2rRuJGBQQqYKa7Dj0vlLH0LH2yPEq0Od9EgETyPfaz_LgO8jMQN6PKwrCa2h79Y-BtOym_rlFsGyvmungCdYcXFMiwCS3fg5bHX8iK_ygx3InSS_GcSlp7HYp9OyEwV61j3QOMOeAY4n-ToxTWnommHfu20XczY0nNfqcmoJ4eXOxw",
    "token_type": "bearer",
    "scope": null
}

This access token must be used in all other calls to the API.

2.2. Fetching Data

Data can be fetched from the example API through two actions:

§ 2.2.1 ListFootprints

enumerates the ProductFootprints available to the authenticated user;

§ 2.2.2 GetFootprint

retrieves a single ProductFootprint given its unique id.

2.2.1. ListFootprints

The ListFootprints action returns a list of ProductFootprints available to the authenticated user, through the /footprints endpoint.

A GET request to this endpoint can be made with the optional limit parameter, which restricts the number of the ProductFootprints.

Note: An optional filter parameter is part of the PACT Technical Specifications but not implemented by the example API provided at https://api.pathfinder.sine.dev. See § 3.1.2 ListFootprints for details.

Action

ListFootprints

Endpoint

/footprints

Options

limit=<integer>

HTTP request

GET

Authorization

Bearer

Example request (cURL)
curl -X 'GET' \
'https://api.pathfinder.sine.dev/2/footprints?limit=2' \
-H 'accept: application/json' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6ImhlbGxvIn0.hUDxqoQR0e4b5emxYl1M0nUMuy1w_VjrB0G3s2ul-oqzNEJnUbgkI9tzo1iGFkMkipSoEZyyOpmUd0IE-kswdaRNmTebn5aGxeARLh3OoknHWyRizU7ZNf4f1ow3Z0wpWfXHH6vxP1IyMTjuk5E1oFqpf2vBteHMrUg0KiZf2rRuJGBQQqYKa7Dj0vlLH0LH2yPEq0Od9EgETyPfaz_LgO8jMQN6PKwrCa2h79Y-BtOym_rlFsGyvmungCdYcXFMiwCS3fg5bHX8iK_ygx3InSS_GcSlp7HYp9OyEwV61j3QOMOeAY4n-ToxTWnommHfu20XczY0nNfqcmoJ4eXOxw'
Example response
{
    "data": [
        {
            "id": "d9be4477-e351-45b3-acd9-e1da05e6f633",
            "specVersion": "1.0.0",
            "version":0,
            "created": "2022-05-22T21:47:32Z",
            ...
        },
        {
            "id": "c3028ee9-d595-4779-a73a-290bfa7505d6",
            "specVersion": "1.0.0",
            "version":0,
            "created": "2022-05-22T21:47:32Z",
            ...
        }
    ]
}

Note: The actual response contains an array of ProductFootprints which are omitted for brevity here. See § 4.2.1 ProductFootprint Example for an example of a complete ProductFootprint.

2.2.2. GetFootprint

The GetFootprint action returns a specific ProductFootprint, identified by its unique id, through a GET request made to the /footprints/<footprint-id> endpoint. This can be used to retrieve the latest version of that ProductFootprint.

Action

GetFootprint

Endpoint

/footprints/<footprint-id>

HTTP request

GET

Authorization

Bearer

Example request (cURL)
curl -X 'GET' \
'https://api.pathfinder.sine.dev/2/footprints/d9be4477-e351-45b3-acd9-e1da05e6f633' \
-H 'accept: application/json' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6ImhlbGxvIn0.hUDxqoQR0e4b5emxYl1M0nUMuy1w_VjrB0G3s2ul-oqzNEJnUbgkI9tzo1iGFkMkipSoEZyyOpmUd0IE-kswdaRNmTebn5aGxeARLh3OoknHWyRizU7ZNf4f1ow3Z0wpWfXHH6vxP1IyMTjuk5E1oFqpf2vBteHMrUg0KiZf2rRuJGBQQqYKa7Dj0vlLH0LH2yPEq0Od9EgETyPfaz_LgO8jMQN6PKwrCa2h79Y-BtOym_rlFsGyvmungCdYcXFMiwCS3fg5bHX8iK_ygx3InSS_GcSlp7HYp9OyEwV61j3QOMOeAY4n-ToxTWnommHfu20XczY0nNfqcmoJ4eXOxw'
Example response
{
    "data": {
        "id": "d9be4477-e351-45b3-acd9-e1da05e6f633",
        "specVersion": "2.0.0",
        "version": 0,
        ...
    }
}

Note: The actual response contains a complete ProductFootprint, many fields of which are omitted here for brevity’s sake. See § 4.2.1 ProductFootprint Example for an example of a complete ProductFootprint.

2.3. Sending an event

In the actions above (§ 2.2.1 ListFootprints and § 2.2.2 GetFootprint), the authenticated user played the role of data recipient and the solution that of data owner. The flow of information in that case is the following: the data recipient asks the data owner for ProductFootprint(s) and the data owner returns them.

The Events action allows for more complex interactions between data owner and data recipient, namely:

Only the former is implemented in this example.

The /events endpoint allows the example API to play the role of data recipient, which can be notified of an update to a ProductFootprint.

To execute this action, the authenticated user (in this case, the data owner) must make a POST request to the /events endpoint, sending a PF Update Event in its body.

For details about the syntax of the request and response see § 3.2.1 Events.

Note: This functionality is optional. See § 3.2 Optional functionality for more details.

Action

Events

Endpoint

/events

HTTP request

POST

Authorization

Bearer

Example request (cURL)
curl -X 'POST' \
'https://api.pathfinder.sine.dev/2/events' \
-H 'accept: */*' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VybmFtZSI6ImhlbGxvIn0.hUDxqoQR0e4b5emxYl1M0nUMuy1w_VjrB0G3s2ul-oqzNEJnUbgkI9tzo1iGFkMkipSoEZyyOpmUd0IE-kswdaRNmTebn5aGxeARLh3OoknHWyRizU7ZNf4f1ow3Z0wpWfXHH6vxP1IyMTjuk5E1oFqpf2vBteHMrUg0KiZf2rRuJGBQQqYKa7Dj0vlLH0LH2yPEq0Od9EgETyPfaz_LgO8jMQN6PKwrCa2h79Y-BtOym_rlFsGyvmungCdYcXFMiwCS3fg5bHX8iK_ygx3InSS_GcSlp7HYp9OyEwV61j3QOMOeAY4n-ToxTWnommHfu20XczY0nNfqcmoJ4eXOxw' \
-H 'Content-Type: application/json' \
-d '{
        "specversion": "1.0",
        "id": "1234",
        "source":"http://localhost:3000",
        "time": "2023-04-12T14:27:58.535Z",
        "type": "org.wbcsd.pathfinder.ProductFootprint.Published.v1",
        "data": {
            "pfIds": [
                "f4b1225a-bd44-4c8e-861d-079e4e1dfd69"
            ]
        }
    }'
Example response

HTTP status code OK 200 with empty body

3. Overview of the Technical Specification

The Technical Specification specifies a data model for GHG emission data at product level based on the Pathfinder Framework Version 2, and a protocol for interoperable exchange of GHG emission data at product level.

To allow for interoperable PCF data exchange, solutions must implement an HTTP REST API, also defined in the technical specification.

The scope of the HTTP API is minimal by design and new features will be added in future versions of the specification.

In order to be conformant with the Pathfinder Framework, a solution’s HTTP REST API must include the following mandatory features:

There is also a recommended but optional feature:

Further details about the HTTP REST API can be found in Section 6 (HTTP REST API) of the Technical Specification.

3.1. Mandatory Functionality

3.1.1. Authenticate

The HTTP REST API requires users to authenticate themselves before they are able to either fetch data (see § 3.1.2 ListFootprints and § 3.1.3 GetFootprint) or submit a events (see § 3.2.1 Events).

The Authenticate action is mandatory and must be implemented in accordance with RFC6749, Section 4.4 (OAuth2 Client Credentials).

The solution provider must register users by exchanging credentials with them. These must include an id (aka client_id / username) and a secret (aka client_secret / username). The solution provider is free to manage credentials as they please. (As a suggestion, we propose that for the time being these are exchanged via e-mail, with the user sending the solution provider what they wish to use as their id and secret and the solution provider confirming them.)

3.1.1.1. Authentication Flow

The Authentication Flow was updated from v. 2.0.1 to v. 2.1.0 of the Technical Specifications.

In v. 2.0.1, access tokens had to be obtained through a POST request to the /auth/token endpoint.

In v.2.1.0, the endpoint to retrieve an access token can be chosen by the solution provider (in accordance with RFC6749), provided that:

  1. They still expose the /auth/token endpoint (even if returning an error);

  2. They provide an OpenId Provider Configuration Document with the token_endpoint field set to the endpoint they chose.

If no OpenId Provider Configuration Document is provided or the token_endpoint field is not correctly set, the AuthEndpoint (i.e. the endpoint to retrieve an access token) is assumed to be /auth/token.

Once the user knows the AuthEndpoint, they must send their credentials as Basic Authentication in the Authorization header.

In case of a 200 (OK) response, they will get back back an object which includes the access_token. (See RFC6749, Section 4.4.3 and RFC6749, Section 5.1 for further details.) This token must be used in all further calls to the API, being sent as Bearer authentication in the Authorization header.

3.1.1.2. Request Syntax (HTTP/1.1)
POST AuthSubpath/AuthEndpoint HTTP/1.1
host: AuthHostname
accept: application/json
content-type: application/x-www-form-urlencoded
authorization: Basic BasicAuth
content-length: ContentLength

AuthBody
3.1.1.3. Response Syntax
HTTP/1.1 AuthStatusCode OK
content-type: application/json
content-length: ContentLength

AuthResponseBody

3.1.2. ListFootprints

The ListFootprints action is mandatory and provides the authenticated user with the list of ProductFootprints available to them.

This action needs to support one optional parameter:

limit

A positive integer limiting the number of results displayed

An API can, but is not required to, additionally support the following parameter:

filter

A string to filter the results (details can be found here)

Pagination of the results should follow the Section 6.6.1 of the Technical Specification.

3.1.2.1. Request Syntax (HTTP/1.1)
GET Subpath/2/footprints?Filter&Limit HTTP/1.1
host: Hostname
authorization: Bearer BearerToken
3.1.2.2. Response Syntax
HTTP/1.1 ListStatusCode ListStatusText
content-type: application/json
content-length: ContentLength

ListResponseBody

3.1.3. GetFootprint

The GetFootprint action is mandatory and returns a specific ProductFootprint, identified by its unique id. This can be used to retrieve the latest version of that ProductFootprint.

3.1.3.1. Request Syntax (HTTP/1.1)
GET Subpath/2/footprints/GetPfId HTTP/1.1
host: Hostname
authorization: Bearer BearerToken
3.1.3.2. Response Syntax
HTTP/1.1 GetStatusCode GetStatusText
content-type: application/json
content-length: ContentLength

GetResponseBody

3.2. Optional functionality

Note: Although the Events action is optional, if it is not yet implemented, the HTTP REST API must return an error response with the NotImplemented code. See § 3.3 Error Responses.

3.2.1. Events

The Events action is optional and fulfills two purposes, depending on the body of the HTTP request:

3.2.1.1. Request Syntax (HTTP/1.1)
POST Subpath/2/events HTTP/1.1
host: Hostname
authorization: Bearer BearerToken
content-type: application/cloudevents+json; charset=UTF-8

EventBody

An EventBody must be (i) a CloudEvents event, (ii) encoded as a JSON object, (iii) using "Structured Content Mode". In the context of this HTTP REST API, it can be a PF Update Event, a PF Request Event, a PF Response Event, or a PF Response Error Event

PF Update Event

Through a PF Update Event, the data owner notifies the data recipient that a certain ProductFootprint was updated. A PF Update Event has the following syntax (see the Technical Specifications for further details):

{
  "type": "org.wbcsd.pathfinder.ProductFootprint.Published.v1",
  "specversion": "1.0",
  "id": "EventId",
  "source": "//EventHostname/EventSubpath",
  "time": "2022-05-31T17:31:00Z",
  "data": {
    "pfIds": PfIds
  }
}

PF Request Event

Through a PF Request Event, the data recipient asks the data owner to be sent a fragment of a ProductFootprint. A PF Request Event has the following syntax (see the Technical Specifications for further details):

{
  "type": "org.wbcsd.pathfinder.ProductFootprintRequest.Created.v1",
  "specversion": "1.0",
  "id": "EventId",
  "source": "//EventHostname/EventSubpath",
  "time": "2022-05-31T17:31:00Z",
  "data": {
    "pf": ProductFootprintFragment,
    "comment": PFRequestComment
  }
}

PF Response Event

After having received a PF Request Event, if the request is fulfilled, the data owner should send a PF Response Event as an answer. A PF Response Event has the following syntax (see the Technical Specifications for further details):

{
  "type": "org.wbcsd.pathfinder.ProductFootprintRequest.Fulfilled.v1",
  "specversion": "1.0",
  "id": "EventId",
  "source": "//EventHostname/EventSubpath",
  "data": {
    "requestEventId": "ReqEventId",
    "pfs": Pfs
  }
}

PF Response Error Event

After having received a PF Request Event, if the request is not fulfilled, the data owner should send a PF Response Error Event as an answer. A PF Response Error Event has the following syntax (see the Technical Specifications for further details):

{
  "type": "org.wbcsd.pathfinder.ProductFootprintRequest.Rejected.v1",
  "specversion": "1.0",
  "id": "EventId",
  "source": "...",
  "data": {
    "requestEventId": "ReqEventId",
    "error": ReqErrorResponse
  }
}
3.2.1.2. Response Syntax
HTTP/1.1 200 OK
content-length: 0

3.3. Error Responses

In case a request to the HTTP REST API is not successful, the response should be an error of one of the following types (for further details see Section 6.9 of the Technical Specification):

Error Response Code Example Message HTTP Status Code
AccessDenied Access denied 403
BadRequest Bad Request 400
NoSuchFootprint The specified footprint does not exist. 404
NotImplemented The specified Action or header you provided implies functionality that is not implemented 400
TokenExpired The specified access token has expired 401
InternalError An internal or unexpected error has occurred 500
Listing of error codes and their related error response codes.

4. Appendix

4.1. Terminology

Data recipient

The Supply Chain Actor (SCA) requesting and/or receiving Product Carbon Footprint data from another SCA.

Data owner

The Supply Chain Actor (SCA) exchanging PCF data with another SCA.

interoperable

The quality of being able to exchange data between solutions irrespective of the vendors of the host systems, without the need for translation or transformation of the data.

Greenhouse Gas (emissions) (GHG)

Gaseous constituents of the atmosphere, both natural and anthropogenic, that absorb and emit radiation at specific wavelengths within the spectrum of infrared radiation emitted by the Earth’s surface, its atmosphere and clouds. Green House Gases include CDCO₂, Methane (CH4), Nitrous Oxide(N₂O), Hydrofluoro-Carbons (HFCs), Perfluorocarbons (PFCs) and Sulfur Hexafluoride (SF6).

Pathfinder Framework Version 2.0 (Pathfinder Framework)

Guidance for the Accounting and Exchange of Product Life Cycle Emissions, building on existing standards and protocols, such as the GHG Protocol Product standard.

Pathfinder Network

An information network of and for supply chain actors to securely exchange environmental data with each other, with an initial focus on Product Carbon Footprint data.

Product Carbon Footprint (PCF)

The carbon (equivalent) emissions relating to a product. Products can be any kind of item exchanged between entities, including metric or volumetric quantities of a product, etc. The ProductFootprint data model is a digital representation of a PCF in accordance with the Pathfinder Framework.

4.2. Payload Examples

Access the sample payloads for the Pathfinder API endpoints here.

4.2.1. ProductFootprint Example

{
    "id": "d9be4477-e351-45b3-acd9-e1da05e6f633",
    "specVersion": "2.0.0",
    "version": 0,
    "created": "2022-05-22T21:47:32Z",
    "companyName": "My Corp",
    "companyIds": [
        "urn:uuid:51131FB5-42A2-4267-A402-0ECFEFAD1619",
        "urn:epc:id:sgln:4063973.00000.8"
    ],
    "productDescription": "Cote’d Or Ethanol",
    "productIds": [
        "urn:gtin:4712345060507"
    ],
    "productCategoryCpc": "3342",
    "productNameCompany": "Green Ethanol",
    "comment": "",
    "pcf": {
        "declaredUnit": "liter",
        "unitaryProductAmount": "12.0",
        "fossilGhgEmissions": "0.123",
        "biogenicEmissions": {
            "landUseEmissions": "0.001",
            "otherEmissions": "0"
        },
        "biogenicCarbonContent": "0.0",
        "reportingPeriodStart": "2021-01-01T00:00:00Z",
        "reportingPeriodEnd": "2022-01-01T00:00:00Z",
        "geographyCountry": "FR",
        "primaryDataShare": 56.12,
        "emissionFactorSources": [
            {
                "name": "Ecoinvent",
                "version":
                "1.2.3"
            }
        ],
        "boundaryProcessesDescription": "End-of-life included",
        "crossSectoralStandardsUsed": [
            "GHG Protocol Product standard"
        ],
        "productOrSectorSpecificRules": [
            {
                "operator": "EPD International",
                "ruleNames": [
                    "ABC 2021"
                ]
            }
        ]
    }
}

4.3. PACT Conformance Testing

Details about Bilateral Conformance Testing can be found here.

A checklist for Conformance testing is available here.

Access the sample PACT Conformance Test Cases Template here. Please Note - This is a template created with the intention to guide you on what possible test cases you need to consider, but we also encourage you to add any other test cases you feel are necessary for your test coverage.

Index

Terms defined by this specification