> ## Documentation Index
> Fetch the complete documentation index at: https://code.dcycle.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Category 4.3: Purchased Goods and Services

> Calculate emissions from purchased goods and services using spend-based, activity-based, and supplier-specific methods under ISO 14064-1

## Understanding Purchased Goods Emissions

**Purchased goods and services** emissions are indirect greenhouse gas emissions from the extraction, production, and transportation of goods and services acquired by your organization. Under ISO 14064-1 Category 4, this typically represents:

* **Raw materials**: Metals, plastics, chemicals, wood, textiles
* **Intermediate products**: Components, parts, packaging materials
* **Services**: Professional services, IT services, maintenance, consulting

```
┌─────────────────────────────────────────────────────────────────────────────┐
│          ISO 14064-1 CATEGORY 4.3: Purchased Goods & Services               │
├─────────────────────┬─────────────────────┬─────────────────────────────────┤
│  Raw Materials      │  Intermediate       │  Services                       │
│                     │  Products           │                                 │
├─────────────────────┼─────────────────────┼─────────────────────────────────┤
│  • Metals           │  • Components       │  • IT services                  │
│  • Plastics         │  • Packaging        │  • Professional services        │
│  • Chemicals        │  • Semi-finished    │  • Maintenance                  │
│  • Textiles         │  • Electronics      │  • Consulting                   │
└─────────────────────┴─────────────────────┴─────────────────────────────────┘
```

<Note>
  **Why Category 4.3 Matters**

  For most organizations, **purchased goods and services represent 40-80% of total emissions**. This makes Category 4.3 the single most important area for understanding and reducing your carbon footprint.

  **Typical Category 4.3 Contribution**:

  * Manufacturing: 60-80% of indirect emissions
  * Retail: 70-90% of indirect emissions
  * Services: 30-50% of indirect emissions
</Note>

## Prerequisites

Before starting, ensure you have:

* Dcycle API credentials ([get them here](/docs/quickstart#step-1-get-your-api-key))
* Purchase data: invoices, procurement records, or ERP exports
* Knowledge of your spending categories (for spend-based method) or physical quantities (for activity-based method)

<Tip>
  **Using the Dcycle App?**

  You can also manage purchases through our web interface:

  * [Upload purchases manually](https://scribehow.com/shared/Upload_your_purchases_manually__8h4StuskTYC90g8g1s0SPw) ([ES](https://scribehow.com/shared/Sube_tus_compras_manualmente__fJG4jcu-SamP2bekdZFb0A)) - Individual purchase tracking
  * [Upload purchases automatically](https://scribehow.com/shared/How_to_Upload_Purchases_Automatically__eW_8NvwfTG6VCT96YX1Qpg) ([ES](https://scribehow.com/shared/Sube_tus_compras_automaticamente__4fz0eldlQSK3JRs_2VK_pw)) - Bulk import from ERP
</Tip>

## Data Map: Purchased Goods & Services Requirements Overview

```
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│                   PURCHASED GOODS & SERVICES DATA REQUIREMENTS                          │
├─────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                         │
│  ┌─────────────────────────────────────────────────────────────────────────────────┐   │
│  │ SUPPLIER SETUP (Optional)                                                       │   │
│  ├─────────────────────────────────────────────────────────────────────────────────┤   │
│  │                                                                                 │   │
│  │  Required Fields           Optional Fields           For Custom EFs            │   │
│  │  ─────────────────         ───────────────           ─────────────────         │   │
│  │  • business_name           • contact_email           • EPD reference           │   │
│  │  • country                 • sector                  • Certification           │   │
│  │  • tax_id                  • supplier_code           • Verification date       │   │
│  │                                                                                 │   │
│  └─────────────────────────────────────────────────────────────────────────────────┘   │
│                                                                                         │
│  ┌─────────────────────────────────────────────────────────────────────────────────┐   │
│  │ PURCHASE DATA                                                                   │   │
│  ├─────────────────────────────────────────────────────────────────────────────────┤   │
│  │                                                                                 │   │
│  │  Spend-Based               Activity-Based            Supplier-Specific         │   │
│  │  ────────────────────      ────────────────          ─────────────────         │   │
│  │  • quantity (€)            • quantity (kg, units)    • quantity                │   │
│  │  • unit_id (€)             • unit_id (kg, m³, etc.)  • unit_id                 │   │
│  │  • sector                  • product_name            • custom_emission_        │   │
│  │  • product_name            • sector                    factor_id               │   │
│  │  • country                 • country                 • supplier_id             │   │
│  │  • purchase_date           • purchase_date           • purchase_date           │   │
│  │                            • supplier_id             • recycled (%)            │   │
│  │                                                                                 │   │
│  └─────────────────────────────────────────────────────────────────────────────────┘   │
│                                                                                         │
└─────────────────────────────────────────────────────────────────────────────────────────┘
```

## Calculation Methods

Dcycle supports three calculation methods for purchased goods and services, each with different accuracy levels:

### Data Quality Hierarchy

```
┌────────────────────────────────────────────────────────────────────────────────────────┐
│                            DATA QUALITY HIERARCHY                                       │
├────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                        │
│  Level 1: Supplier-Specific Data ─────────────────────────────────── HIGHEST ACCURACY │
│  ├─ EPDs, Product Carbon Footprints, Supplier PCFs                                    │
│  ├─ Accuracy: ±5-15%                                                                  │
│  └─ Use: custom_emission_factor_id                                                    │
│                                                                                        │
│  Level 2: Activity-Based Data ─────────────────────────────────────── MEDIUM ACCURACY │
│  ├─ Product category + physical quantity (kg, m³, units)                              │
│  ├─ Accuracy: ±20-40%                                                                 │
│  └─ Use: quantity + unit_id + sector/product_name                                     │
│                                                                                        │
│  Level 3: Spend-Based Data ─────────────────────────────────────────── LOWER ACCURACY │
│  ├─ Only monetary value + category                                                    │
│  ├─ Accuracy: ±50-100%                                                                │
│  └─ Use: quantity (€) + unit_id (€) + sector/product_name                             │
│                                                                                        │
└────────────────────────────────────────────────────────────────────────────────────────┘
```

<Tabs>
  <Tab title="Spend-Based Method">
    The **spend-based method** uses economic input-output (EEIO) emission factors based on the monetary value of purchases.

    ```
    Spend (€) → Sector/Product Category → Exiobase EF → CO₂e
         ↓              ↓                      ↓           ↓
    Invoice amount   Product mapping      kg CO₂e/€    Total emissions
    ```

    **Key characteristics:**

    * Uses Exiobase 3.8.2 input-output emission factors
    * Emission factors in kg CO₂e per € (or other currency)
    * Covers all economic sectors and product categories
    * Lower accuracy but broad coverage

    <AccordionGroup>
      <Accordion title="Emission Factor Sources - Spend-Based">
        For spend-based calculations, Dcycle uses emission factors from:

        * **Exiobase 3.8.2** - Multi-Regional Environmentally Extended Supply-Use Tables
        * Covers 44 countries and 200+ product categories
        * Source: [Exiobase](https://www.exiobase.eu/)

        Factors are automatically selected based on:

        * Sector/product category
        * Supplier country (or your organization's country)
        * Purchase year
      </Accordion>

      <Accordion title="Calculation Details - Spend-Based">
        Spend-based emissions are calculated as:

        **CO₂e = Spend Amount (€) × Economic Intensity Factor (kg CO₂e/€)**

        Where:

        * **Spend Amount**: Monetary value of the purchase
        * **Economic Intensity Factor**: Exiobase emission factor for the sector/product

        **Example (IT Services):**

        ```
        €15,000 × 0.15 kg CO₂e/€ = 2,250 kg CO₂e
        ```

        Note: Spend-based factors have high uncertainty (±50-100%) and should be used when physical quantities are unavailable.
      </Accordion>
    </AccordionGroup>
  </Tab>

  <Tab title="Activity-Based Method">
    The **activity-based method** uses physical quantities and product-specific emission factors.

    ```
    Quantity (kg) → Product Category → Activity-Based EF → CO₂e
          ↓               ↓                    ↓              ↓
    Physical amount   Product type        kg CO₂e/kg     Total emissions
    ```

    **Key characteristics:**

    * Uses physical quantities (mass, volume, units)
    * More accurate than spend-based
    * Requires detailed procurement data
    * Better for tracking reduction efforts

    <AccordionGroup>
      <Accordion title="Emission Factor Sources - Activity-Based">
        For activity-based calculations, Dcycle uses emission factors from:

        * **Ecoinvent** - Life cycle inventory database (latest version available)
        * **Industry-specific databases** - Sector-specific factors
        * Covers materials, components, and products

        Factors are automatically selected based on:

        * Product name/category
        * Material type
        * Country of origin
      </Accordion>

      <Accordion title="Calculation Details - Activity-Based">
        Activity-based emissions are calculated as:

        **CO₂e = Quantity × Emission Factor (kg CO₂e/unit)**

        Where:

        * **Quantity**: Physical amount (kg, m³, units, etc.)
        * **Emission Factor**: Product-specific factor from database

        **Example (Aluminum sheets):**

        ```
        1,000 kg × 8.5 kg CO₂e/kg = 8,500 kg CO₂e
        ```

        Note: Activity-based is 2-3× more accurate than spend-based.
      </Accordion>
    </AccordionGroup>
  </Tab>

  <Tab title="Supplier-Specific Method">
    The **supplier-specific method** uses verified emission data from your suppliers (EPDs, PCFs).

    ```
    Quantity → Supplier EPD/PCF → Verified EF → CO₂e
        ↓            ↓               ↓            ↓
    Physical     Third-party     kg CO₂e/kg   Total emissions
    amount       verified                     (most accurate)
    ```

    **Key characteristics:**

    * Uses Environmental Product Declarations (EPDs) or Product Carbon Footprints (PCFs)
    * Highest accuracy (±5-15%)
    * Enables supplier engagement and comparison
    * Reflects actual supplier practices (e.g., recycled content)

    <AccordionGroup>
      <Accordion title="Emission Factor Sources - Supplier-Specific">
        Supplier-specific emission factors come from:

        * **Environmental Product Declarations (EPDs)** - ISO 14025 compliant
        * **Product Carbon Footprints (PCFs)** - ISO 14067 compliant
        * **Supplier self-declarations** - Verified or unverified

        In Dcycle, these are stored as **Custom Emission Factors** and linked to purchases.
      </Accordion>

      <Accordion title="Calculation Details - Supplier-Specific">
        Supplier-specific emissions are calculated as:

        **CO₂e = Quantity × Custom Emission Factor (kg CO₂e/unit)**

        Where:

        * **Quantity**: Physical amount from purchase
        * **Custom Emission Factor**: Supplier-provided factor (from EPD/PCF)

        **Example (Recycled Aluminum from certified supplier):**

        ```
        1,000 kg × 2.15 kg CO₂e/kg = 2,150 kg CO₂e
        (vs 8,500 kg CO₂e with generic factor - 75% reduction!)
        ```

        This method enables:

        * Accurate supplier comparisons
        * Recognition of low-carbon suppliers
        * Data for supplier engagement programs
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

<Note>
  **Automatic Method Selection**

  Dcycle automatically selects the calculation method based on the data provided:

  * `custom_emission_factor_id` provided → Supplier-specific method
  * `quantity` + physical `unit_id` provided → Activity-based method
  * `quantity` in currency unit (€) → Spend-based method
</Note>

## Recording Purchases

### Data Flow

<Steps>
  <Step title="Set Up Suppliers (Optional)">
    Create supplier records to organize purchases and enable supplier-level reporting
  </Step>

  <Step title="Choose Calculation Method">
    Determine which method to use based on available data (spend-based, activity-based, or supplier-specific)
  </Step>

  <Step title="Create Purchases">
    Record purchases via API or bulk CSV upload with appropriate fields for chosen method
  </Step>

  <Step title="Automatic Calculation">
    Dcycle automatically calculates CO₂e using Exiobase (spend-based), activity factors, or custom EFs
  </Step>

  <Step title="Query and Analyze">
    View emissions by supplier, category, or period for hotspot identification
  </Step>
</Steps>

### Set Up Purchase Suppliers

<Accordion title="📋 Data Map: Purchase Supplier">
  | Field           | Type   | Required | Description                                | Example                  |
  | --------------- | ------ | -------- | ------------------------------------------ | ------------------------ |
  | `business_name` | string | ✅        | Supplier company name                      | `"Green Materials Co"`   |
  | `tax_id`        | string | ✅        | Tax identification number                  | `"B12345678"`            |
  | `country`       | string | ✅        | Supplier country (ISO code)                | `"ES"`, `"FR"`, `"DE"`   |
  | `sector`        | string | ❌        | Business sector                            | `"Manufacturing"`        |
  | `contact_email` | string | ❌        | Contact email                              | `"contact@supplier.com"` |
  | `supplier_code` | string | ❌        | Sectorial code (SIC (US 1987)/CNAE (2009)) | `"3331"`                 |

  **Where to get this data:**

  * **Business name/Tax ID**: From supplier invoices or contracts
  * **Country**: Supplier headquarters or production location
  * **Sector**: Industry classification (helps with reporting)
</Accordion>

Organize purchases by supplier to enable supplier-level emissions reporting and engagement:

<CodeGroup>
  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import requests
  import os

  headers = {
      "Authorization": f"Bearer {os.getenv('DCYCLE_API_KEY')}",
      "Content-Type": "application/json",
      "x-organization-id": os.getenv("DCYCLE_ORG_ID"),
      "x-user-id": os.getenv("DCYCLE_USER_ID"),
  }

  # Create a purchase supplier
  supplier_data = {
      "business_name": "Green Materials Co",
      "tax_id": "B12345678",
      "country": "ES",
      "sector": "Manufacturing",
      "contact_email": "procurement@greenmaterials.com",
  }

  response = requests.post(
      "https://api.dcycle.io/v1/purchase_suppliers",
      headers=headers,
      json=supplier_data,
  )

  supplier = response.json()
  print(f"✅ Supplier created: {supplier['id']}")
  print(f"   Name: {supplier['business_name']}")
  print(f"   Country: {supplier['country']}")
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const axios = require('axios');

  const headers = {
    Authorization: `Bearer ${process.env.DCYCLE_API_KEY}`,
    'Content-Type': 'application/json',
    'x-organization-id': process.env.DCYCLE_ORG_ID,
    'x-user-id': process.env.DCYCLE_USER_ID,
  };

  // Create a purchase supplier
  const supplierData = {
    business_name: 'Green Materials Co',
    tax_id: 'B12345678',
    country: 'ES',
    sector: 'Manufacturing',
    contact_email: 'procurement@greenmaterials.com',
  };

  const response = await axios.post(
    'https://api.dcycle.io/v1/purchase_suppliers',
    supplierData,
    { headers }
  );

  const supplier = response.data;
  console.log(`✅ Supplier created: ${supplier.id}`);
  console.log(`   Name: ${supplier.business_name}`);
  console.log(`   Country: ${supplier.country}`);
  ```
</CodeGroup>

<Tip>
  **Supplier Organization Best Practices**

  * Group purchases by supplier for better hotspot analysis
  * Include supplier country for accurate regional emission factors
  * Use consistent supplier codes across your ERP and Dcycle
</Tip>

### Create a Spend-Based Purchase

<Accordion title="📋 Data Map: Spend-Based Purchase">
  | Field           | Type   | Required | Description              | Example                               |
  | --------------- | ------ | -------- | ------------------------ | ------------------------------------- |
  | `description`   | string | ❌        | Purchase description     | `"IT consulting Q1"`                  |
  | `sector`        | string | ✅        | Economic sector          | `"Computer programming, consultancy"` |
  | `product_name`  | string | ✅        | Product/service category | `"Computer programming services"`     |
  | `quantity`      | number | ✅        | Monetary value spent     | `15000`                               |
  | `unit_id`       | UUID   | ✅        | Currency unit (€)        | `"eur-unit-uuid"`                     |
  | `country`       | string | ✅        | Supplier country         | `"ES"`                                |
  | `purchase_date` | date   | ✅        | Date of purchase         | `"2024-03-15"`                        |
  | `supplier_id`   | UUID   | ❌        | Linked supplier          | `"supplier-uuid"`                     |
  | `purchase_type` | string | ✅        | Must be `"spend_based"`  | `"spend_based"`                       |

  **Where to get this data:**

  * **Quantity**: From invoices, payment records, or ERP exports
  * **Sector/Product**: Map from your expense categories (see Exiobase mapping)
  * **Country**: Supplier's country of origin
</Accordion>

Use the spend-based method when you only have monetary values:

<CodeGroup>
  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import requests
  import os

  headers = {
      "Authorization": f"Bearer {os.getenv('DCYCLE_API_KEY')}",
      "Content-Type": "application/json",
      "x-organization-id": os.getenv("DCYCLE_ORG_ID"),
      "x-user-id": os.getenv("DCYCLE_USER_ID"),
  }

  # Get the EUR unit for spend-based purchases
  units = requests.get(
      "https://api.dcycle.io/v1/units",
      headers=headers,
      params={"page": 1, "size": 100}
  ).json()

  eur_unit = next(u for u in units['items'] if u['abbreviation'] == '€')

  # Create spend-based purchase (IT consulting services)
  purchase_data = {
      "description": "IT consulting services Q1 2024",
      "sector": "Computer programming, consultancy and related activities",
      "product_name": "Computer programming, consultancy and related services",
      "quantity": 15000,  # €15,000 spent
      "unit_id": eur_unit['id'],  # EUR unit
      "country": "ES",  # Supplier country
      "purchase_date": "2024-03-15",
      "supplier_id": "your-supplier-uuid",  # Optional
      "purchase_type": "spend_based",
  }

  response = requests.post(
      "https://api.dcycle.io/v1/purchases",
      headers=headers,
      json=purchase_data,
  )

  purchase = response.json()
  print(f"✅ Spend-based purchase created: {purchase['id']}")
  print(f"   Amount: €{purchase['quantity']:,.2f}")
  print(f"   CO₂e: {purchase.get('co2e', 'Calculating...')} kg")
  print(f"   Method: Spend-based (Exiobase 3.8.2)")
  print(f"   ISO 14064-1 Category: 4.3 (Purchased Goods)")
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const axios = require('axios');

  const headers = {
    Authorization: `Bearer ${process.env.DCYCLE_API_KEY}`,
    'Content-Type': 'application/json',
    'x-organization-id': process.env.DCYCLE_ORG_ID,
    'x-user-id': process.env.DCYCLE_USER_ID,
  };

  // Get the EUR unit for spend-based purchases
  const unitsResponse = await axios.get(
    'https://api.dcycle.io/v1/units',
    { headers, params: { page: 1, size: 100 } }
  );
  const units = unitsResponse.data;
  const eurUnit = units.items.find(u => u.abbreviation === '€');

  // Create spend-based purchase (IT consulting services)
  const purchaseData = {
    description: 'IT consulting services Q1 2024',
    sector: 'Computer programming, consultancy and related activities',
    product_name: 'Computer programming, consultancy and related services',
    quantity: 15000, // €15,000 spent
    unit_id: eurUnit.id, // EUR unit
    country: 'ES', // Supplier country
    purchase_date: '2024-03-15',
    supplier_id: 'your-supplier-uuid', // Optional
    purchase_type: 'spend_based',
  };

  const response = await axios.post(
    'https://api.dcycle.io/v1/purchases',
    purchaseData,
    { headers }
  );

  const purchase = response.data;
  console.log(`✅ Spend-based purchase created: ${purchase.id}`);
  console.log(`   Amount: €${purchase.quantity.toLocaleString()}`);
  console.log(`   CO₂e: ${purchase.co2e || 'Calculating...'} kg`);
  console.log(`   Method: Spend-based (Exiobase 3.8.2)`);
  console.log(`   ISO 14064-1 Category: 4.3 (Purchased Goods)`);
  ```
</CodeGroup>

<Warning>
  **Spend-Based Accuracy Limitations**

  Spend-based factors have high uncertainty (±50-100%) because:

  * Price ≠ emissions (expensive ≠ high emissions)
  * Doesn't account for specific products or supplier practices
  * Currency fluctuations affect results

  Use spend-based as a **starting point**, then improve data quality for high-impact categories.
</Warning>

### Create an Activity-Based Purchase

<Accordion title="📋 Data Map: Activity-Based Purchase">
  | Field           | Type   | Required | Description                  | Example                              |
  | --------------- | ------ | -------- | ---------------------------- | ------------------------------------ |
  | `description`   | string | ❌        | Purchase description         | `"Aluminum sheets for production"`   |
  | `sector`        | string | ✅        | Product sector               | `"Manufacture of basic metals"`      |
  | `product_name`  | string | ✅        | Specific product             | `"Aluminium and aluminium products"` |
  | `quantity`      | number | ✅        | Physical quantity            | `1000`                               |
  | `unit_id`       | UUID   | ✅        | Physical unit (kg, m³, etc.) | `"kg-unit-uuid"`                     |
  | `country`       | string | ✅        | Country of origin            | `"ES"`                               |
  | `purchase_date` | date   | ✅        | Date of purchase             | `"2024-03-15"`                       |
  | `supplier_id`   | UUID   | ❌        | Linked supplier              | `"supplier-uuid"`                    |
  | `purchase_type` | string | ✅        | Must be `"activity_based"`   | `"activity_based"`                   |
  | `recycled`      | number | ❌        | Recycled content (0-1)       | `0.3` (30% recycled)                 |

  **Where to get this data:**

  * **Quantity**: From delivery notes, bills of materials, or inventory systems
  * **Unit**: Match the physical unit of the product (kg for materials, m³ for liquids)
  * **Recycled**: Ask supplier for recycled content percentage
</Accordion>

Use the activity-based method when you have physical quantities:

<CodeGroup>
  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import requests
  import os

  headers = {
      "Authorization": f"Bearer {os.getenv('DCYCLE_API_KEY')}",
      "Content-Type": "application/json",
      "x-organization-id": os.getenv("DCYCLE_ORG_ID"),
      "x-user-id": os.getenv("DCYCLE_USER_ID"),
  }

  # Get the kg unit for activity-based purchases
  units = requests.get(
      "https://api.dcycle.io/v1/units",
      headers=headers,
      params={"page": 1, "size": 100}
  ).json()

  kg_unit = next(u for u in units['items'] if u['abbreviation'] == 'kg')

  # Create activity-based purchase (aluminum sheets)
  purchase_data = {
      "description": "Aluminum sheets for Q1 production",
      "sector": "Manufacture of basic metals",
      "product_name": "Aluminium and aluminium products",
      "quantity": 1000,  # 1,000 kg
      "unit_id": kg_unit['id'],  # kg unit
      "country": "ES",  # Country of origin
      "purchase_date": "2024-03-15",
      "supplier_id": "your-supplier-uuid",  # Recommended
      "purchase_type": "activity_based",
      "recycled": 0.0,  # 0% recycled content (optional)
  }

  response = requests.post(
      "https://api.dcycle.io/v1/purchases",
      headers=headers,
      json=purchase_data,
  )

  purchase = response.json()
  print(f"✅ Activity-based purchase created: {purchase['id']}")
  print(f"   Quantity: {purchase['quantity']:,.0f} kg")
  print(f"   CO₂e: {purchase.get('co2e', 'Calculating...')} kg")
  print(f"   Method: Activity-based")
  print(f"   ISO 14064-1 Category: 4.3 (Purchased Goods)")
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const axios = require('axios');

  const headers = {
    Authorization: `Bearer ${process.env.DCYCLE_API_KEY}`,
    'Content-Type': 'application/json',
    'x-organization-id': process.env.DCYCLE_ORG_ID,
    'x-user-id': process.env.DCYCLE_USER_ID,
  };

  // Get the kg unit for activity-based purchases
  const unitsResponse = await axios.get(
    'https://api.dcycle.io/v1/units',
    { headers, params: { page: 1, size: 100 } }
  );
  const units = unitsResponse.data;
  const kgUnit = units.items.find(u => u.abbreviation === 'kg');

  // Create activity-based purchase (aluminum sheets)
  const purchaseData = {
    description: 'Aluminum sheets for Q1 production',
    sector: 'Manufacture of basic metals',
    product_name: 'Aluminium and aluminium products',
    quantity: 1000, // 1,000 kg
    unit_id: kgUnit.id, // kg unit
    country: 'ES', // Country of origin
    purchase_date: '2024-03-15',
    supplier_id: 'your-supplier-uuid', // Recommended
    purchase_type: 'activity_based',
    recycled: 0.0, // 0% recycled content (optional)
  };

  const response = await axios.post(
    'https://api.dcycle.io/v1/purchases',
    purchaseData,
    { headers }
  );

  const purchase = response.data;
  console.log(`✅ Activity-based purchase created: ${purchase.id}`);
  console.log(`   Quantity: ${purchase.quantity.toLocaleString()} kg`);
  console.log(`   CO₂e: ${purchase.co2e || 'Calculating...'} kg`);
  console.log(`   Method: Activity-based`);
  console.log(`   ISO 14064-1 Category: 4.3 (Purchased Goods)`);
  ```
</CodeGroup>

<Tip>
  **Track Recycled Content**

  If your supplier provides recycled materials, use the `recycled` field (0-1) to indicate the percentage. This:

  * Improves calculation accuracy
  * Enables tracking of circular economy metrics
  * Supports supplier engagement on recycled content
</Tip>

### Create a Supplier-Specific Purchase

<Accordion title="📋 Data Map: Supplier-Specific Purchase">
  | Field                       | Type   | Required | Description                 | Example                              |
  | --------------------------- | ------ | -------- | --------------------------- | ------------------------------------ |
  | `description`               | string | ❌        | Purchase description        | `"Recycled aluminum (EPD verified)"` |
  | `quantity`                  | number | ✅        | Physical quantity           | `1000`                               |
  | `unit_id`                   | UUID   | ✅        | Physical unit               | `"kg-unit-uuid"`                     |
  | `purchase_date`             | date   | ✅        | Date of purchase            | `"2024-03-15"`                       |
  | `supplier_id`               | UUID   | ✅        | Linked supplier             | `"supplier-uuid"`                    |
  | `custom_emission_factor_id` | UUID   | ✅        | Custom EF from supplier EPD | `"custom-ef-uuid"`                   |
  | `country`                   | string | ❌        | Supplier country            | `"ES"`                               |

  **Where to get this data:**

  * **Custom Emission Factor**: Create from supplier EPD/PCF (see below)
  * **Quantity**: From delivery notes or purchase orders
  * **Supplier ID**: From your supplier setup
</Accordion>

For highest accuracy, use supplier-provided emission data (EPDs, PCFs):

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import requests
import os

headers = {
    "Authorization": f"Bearer {os.getenv('DCYCLE_API_KEY')}",
    "Content-Type": "application/json",
    "x-organization-id": os.getenv("DCYCLE_ORG_ID"),
    "x-user-id": os.getenv("DCYCLE_USER_ID"),
}

# Step 1: Create a custom emission factor group for the supplier
group_data = {
    "name": "Green Materials Co - 2024 Product Line",
    "description": "EPD-verified emission factors from Green Materials Co",
    "category": "purchases",
    "ghg_type": 1,  # 1 = Fossil
}

group = requests.post(
    "https://api.dcycle.io/v1/custom_emission_groups",
    headers=headers,
    json=group_data,
).json()

print(f"✅ Custom EF group created: {group['id']}")

# Step 2: Add emission factor values from the supplier's EPD
kg_unit_id = "61743a63-ff70-459c-9567-5eee8f7dfd5c"  # kg unit UUID

factor_data = {
    "ef_name": "Recycled Aluminum Sheet - Green Materials Co (EPD S-P-12345)",
    "unit_id": kg_unit_id,
    "factor_uploaded_by": "procurement@yourcompany.com",
    "tag": "advanced",
    "uncertainty_grade": 12,  # Low uncertainty (EPD-verified)
    "factor_start_date": "2024-01-01",
    "factor_end_date": "2024-12-31",
    "additional_docs": "EPD No. S-P-12345, Bureau Veritas verified",
    "emission_factor_values": [
        {"gas_type": "CO2", "value": 2.15},  # kg CO2 per kg
        {"gas_type": "CH4", "value": 0.008},  # kg CH4 per kg
        {"gas_type": "N2O", "value": 0.002},  # kg N2O per kg
    ],
}

factor = requests.post(
    f"https://api.dcycle.io/v1/custom_emission_factors/{group['id']}",
    headers=headers,
    json=factor_data,
).json()

print(f"✅ Custom emission factor created: {factor['id']}")

# Step 3: Create purchase using the custom emission factor
purchase_data = {
    "description": "Recycled aluminum sheets from Green Materials Co",
    "quantity": 1000,  # 1,000 kg
    "unit_id": kg_unit_id,
    "purchase_date": "2024-03-15",
    "supplier_id": "your-supplier-uuid",
    "custom_emission_factor_id": factor['id'],  # Use supplier's verified factor
}

response = requests.post(
    "https://api.dcycle.io/v1/purchases",
    headers=headers,
    json=purchase_data,
)

purchase = response.json()
print(f"✅ Supplier-specific purchase created: {purchase['id']}")
print(f"   Quantity: {purchase['quantity']:,.0f} kg")
print(f"   CO₂e: {purchase.get('co2e', 'Calculating...')} kg")
print(f"   Method: Supplier-specific (EPD S-P-12345)")
print(f"   ISO 14064-1 Category: 4.3 (Purchased Goods)")

# Compare with generic factor
generic_co2e = 1000 * 8.5  # Generic aluminum EF
supplier_co2e = 1000 * 2.15  # Supplier's recycled aluminum EF
savings = generic_co2e - supplier_co2e
print(f"\n📊 Emission savings vs generic: {savings:,.0f} kg CO₂e ({savings/generic_co2e*100:.0f}%)")
```

<Note>
  **Why Supplier-Specific Matters**

  Using supplier-specific data (EPDs, PCFs) provides:

  * **Higher accuracy** (±5-15% vs ±50-100% for spend-based)
  * **Recognition for low-carbon suppliers** (recycled materials, renewable energy)
  * **Data for supplier engagement** programs
  * **Credibility** for external reporting and audits

  Start with high-emission categories: typically metals, chemicals, electronics.
</Note>

## Bulk Upload Purchases

For large datasets from ERP systems:

### CSV Format for Purchases

```csv theme={"theme":{"light":"github-light","dark":"github-dark"}}
description,sector,product_name,quantity,unit_id,country,purchase_date,supplier_id,purchase_type,recycled
"Aluminum sheets Q1",Manufacture of basic metals,Aluminium and aluminium products,1000,kg-unit-uuid,ES,2024-03-01,supplier-uuid-1,activity_based,0.0
"Steel beams Q1",Manufacture of basic metals,Basic iron and steel,5000,kg-unit-uuid,DE,2024-03-05,supplier-uuid-2,activity_based,0.3
"IT consulting",Computer programming consultancy,Computer programming services,15000,eur-unit-uuid,ES,2024-03-10,supplier-uuid-3,spend_based,
```

### Upload Process

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Get presigned URL for bulk upload
upload_response = requests.post(
    "https://api.dcycle.io/v1/purchases/bulk/csv",
    headers=headers,
    json={"file_name": "q1_2024_purchases.csv"},
).json()

# Upload CSV to presigned URL
with open('q1_2024_purchases.csv', 'rb') as f:
    requests.put(upload_response['upload_url'], data=f)

print(f"✅ CSV uploaded, processing will begin automatically")
print(f"   Check processing status in the Dcycle App")
```

## Query Purchases and Emissions

### Get Purchases by Period

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Query purchases for a specific period
response = requests.get(
    "https://api.dcycle.io/v1/purchases",
    headers=headers,
    params={
        "page": 1,
        "size": 50,
        "start_date": "2024-01-01",
        "end_date": "2024-03-31",
    },
).json()

print(f"📊 Q1 2024 Purchases (Category 4.3):")
total_co2e = 0
for purchase in response["items"]:
    print(f"   {purchase['description']}")
    print(f"   Quantity: {purchase['quantity']} {purchase['unit']}")
    print(f"   CO₂e: {purchase['co2e']:.2f} kg")
    print(f"   Method: {purchase['purchase_type']}")
    print()
    total_co2e += purchase['co2e']

print(f"   Total CO₂e: {total_co2e:,.2f} kg")
```

### Get Supplier Emissions Report

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Get emissions by supplier
supplier_id = "your-supplier-uuid"

response = requests.get(
    f"https://api.dcycle.io/v1/purchase_suppliers/{supplier_id}",
    headers=headers,
    params={
        "start_date": "2024-01-01",
        "end_date": "2024-12-31",
    },
).json()

print(f"📊 Supplier Report: {response['business_name']}")
print(f"   Total purchases: {response['total_purchases']}")
print(f"   Total CO₂e: {response['total_co2e']:,.2f} kg")
```

<Tip>
  **Best Practice: Prioritize Data Quality Improvement**

  For complete Category 4.3 accounting:

  1. **Start with spend-based** for broad coverage
  2. **Identify hotspots** (top 10-20 categories by emissions)
  3. **Improve data quality** for hotspots (move to activity-based)
  4. **Engage key suppliers** for EPDs/PCFs (top 20% by emissions)

  Goal: Move from 100% spend-based to 50%+ activity/supplier-specific.
</Tip>

## Exiobase Sector and Product Mapping

Dcycle uses Exiobase 3.8.2 for spend-based emission factors. Here are the most common sectors:

| Sector                                  | Example Products               | Typical EF Range (kg CO₂e/€) |
| --------------------------------------- | ------------------------------ | ---------------------------- |
| **Manufacture of basic metals**         | Steel, aluminum, copper        | 0.8 - 2.5                    |
| **Manufacture of chemicals**            | Industrial chemicals, plastics | 0.5 - 1.5                    |
| **Manufacture of electrical equipment** | Electronics, components        | 0.3 - 0.8                    |
| **Computer programming, consultancy**   | IT services, software          | 0.1 - 0.3                    |
| **Manufacture of textiles**             | Fabrics, clothing              | 0.4 - 1.2                    |
| **Manufacture of paper**                | Packaging, office supplies     | 0.3 - 0.8                    |
| **Professional services**               | Consulting, legal              | 0.1 - 0.2                    |

<AccordionGroup>
  <Accordion title="Full Exiobase Sector List">
    Contact Dcycle support for the complete Exiobase sector and product mapping for your industry.

    The mapping includes:

    * 200+ product categories
    * 44 countries with regional factors
    * Annual updates based on economic data
  </Accordion>

  <Accordion title="Custom Sector Mapping">
    If your expense categories don't match Exiobase sectors directly, you can:

    1. Use the closest matching sector
    2. Create custom mappings via the API
    3. Contact Dcycle support for assistance

    Consistent mapping is key for year-over-year comparisons.
  </Accordion>
</AccordionGroup>

## Troubleshooting

### Issue: High Uncertainty in Spend-Based Calculations

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Check calculation method and improve data quality
purchase = requests.get(
    f"https://api.dcycle.io/v1/purchases/{purchase_id}",
    headers=headers,
).json()

if purchase['purchase_type'] == 'spend_based':
    print("⚠️  Using spend-based method (high uncertainty)")
    print("💡 Recommendations:")
    print("   1. Collect physical quantities from supplier")
    print("   2. Request product specifications")
    print("   3. Ask supplier for EPD/PCF data")
```

### Issue: Can't Find Appropriate Sector/Product

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Use the most specific category available
# If unsure, use broader category and refine later

# Too broad: "Manufacturing"
# Better: "Manufacture of basic metals"
# Best: "Aluminium and aluminium products"

# You can update the sector later:
requests.patch(
    f"https://api.dcycle.io/v1/purchases/{purchase_id}",
    headers=headers,
    json={
        "sector": "Manufacture of basic metals",
        "product_name": "Aluminium and aluminium products",
    },
)
```

### Issue: Supplier Data Not Available

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Track without supplier initially, link later
purchase_data = {
    "description": "Office supplies Q1",
    "sector": "Manufacture of paper and paper products",
    "product_name": "Paper and paper products",
    "quantity": 500,  # €500
    "unit_id": eur_unit_id,
    "purchase_date": "2024-03-15",
    "purchase_type": "spend_based",
    # supplier_id: omitted - can add later
}

# Later, link to supplier:
requests.patch(
    f"https://api.dcycle.io/v1/purchases/{purchase_id}",
    headers=headers,
    json={"supplier_id": "supplier-uuid"},
)
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Category 4.1: Capital Goods" icon="building" href="/guides/emissions/iso-14064-category-4-1-capital-goods">
    Track capital asset emissions
  </Card>

  <Card title="Category 4.2: Waste Disposal" icon="trash" href="/guides/emissions/iso-14064-category-4-2-waste">
    Track waste generated in operations
  </Card>

  <Card title="Custom Emission Factors" icon="chart-line" href="/guides/advanced/custom-emission-factors">
    Create and manage supplier EPDs/PCFs
  </Card>

  <Card title="Back to Category 4 Overview" icon="arrow-left" href="/guides/emissions/iso-14064-category-4-products-used">
    Return to Category 4 overview
  </Card>
</CardGroup>
