> ## 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.

# List Facility Fuels

> Get a list of fuels available for facility consumption

# List Facility Fuels

Retrieve all facility fuels available in the Dcycle system. Facility fuels represent different types of energy sources consumed at facilities (natural gas, diesel, heating oil, LPG, etc.) and are used when creating process-type invoices.

<Note>
  Facility fuels are **reference data** maintained by Dcycle. You cannot create or modify fuels through the API - this endpoint is read-only.
</Note>

## Request

### Headers

<ParamField header="x-api-key" type="string" required>
  Your API key for authentication

  **Example:** `sk_live_1234567890abcdef`
</ParamField>

<ParamField header="x-organization-id" type="string" required>
  Your organization UUID

  **Example:** `ff4adcc7-8172-45fe-9cf1-e90a6de53aa9`
</ParamField>

<ParamField header="x-user-id" type="string" required>
  Your user UUID

  **Example:** `a1b2c3d4-e5f6-7890-abcd-ef1234567890`
</ParamField>

### Query Parameters

<ParamField query="country" type="string">
  Filter facility fuels by country using ISO 3166-1 alpha-2 country code

  **Supported country codes:**

  * `ES` - Spain (returns Spanish facility fuels)
  * Any other code returns generic GHG database fuels

  <Info>
    Country-specific facility fuels are currently only available for Spain (`ES`). Other countries will receive generic fuels from the GHG Protocol database.
  </Info>

  **Example:** `"ES"`
</ParamField>

## Response

Returns an array of facility fuel objects (not paginated - all matching fuels are returned).

<ResponseField name="[]" type="array">
  Array of facility fuel objects

  ### Facility Fuel Object Fields:

  <ResponseField name="id" type="string">
    Unique fuel identifier (UUID v4)
  </ResponseField>

  <ResponseField name="name" type="string">
    Fuel name (e.g., "Natural gas", "Diesel", "Propane", "Heating oil")
  </ResponseField>

  <ResponseField name="country" type="string">
    ISO 3166-1 alpha-2 country code where fuel data applies
  </ResponseField>

  <ResponseField name="type" type="string">
    Fuel type classification (e.g., "gas", "liquid", "solid")
  </ResponseField>

  <ResponseField name="ghg_type" type="integer">
    GHG type classification for emissions calculations

    Common values:

    * `1` - Fossil fuels
    * `2` - Biofuels
    * `3` - Mixed sources
  </ResponseField>

  <ResponseField name="units" type="array">
    Array of available measurement units for this fuel

    Each unit object contains:

    * `id` (string) - Unit UUID
    * `name` (string) - Unit name (e.g., "m³", "L", "kWh")
    * `type` (string) - Unit type (e.g., "gas", "liquid", "energy")
  </ResponseField>
</ResponseField>

## Example

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X GET "https://api.dcycle.io/api/v1/facility_fuels?country=ES" \
    -H "Authorization: Bearer ${DCYCLE_API_KEY}" \
    -H "x-organization-id: ${DCYCLE_ORG_ID}" \
    -H "x-user-id: ${DCYCLE_USER_ID}"
  ```

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

  api_key = os.getenv("DCYCLE_API_KEY")
  org_id = os.getenv("DCYCLE_ORG_ID")
  user_id = os.getenv("DCYCLE_USER_ID")

  headers = {
      "Authorization": f"Bearer {api_key}",
      "x-organization-id": org_id,
      "x-user-id": user_id
  }

  # Get Spanish facility fuels
  params = {"country": "ES"}

  response = requests.get(
      "https://api.dcycle.io/api/v1/facility_fuels",
      headers=headers,
      params=params
  )

  fuels = response.json()
  print(f"Found {len(fuels)} facility fuels in Spain:")

  for fuel in fuels:
      units_str = ", ".join([u['name'] for u in fuel['units']])
      print(f"- {fuel['name']} ({fuel['type']}): {units_str}")
  ```

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

  const apiKey = process.env.DCYCLE_API_KEY;
  const orgId = process.env.DCYCLE_ORG_ID;
  const userId = process.env.DCYCLE_USER_ID;

  const headers = {
    'Authorization': `Bearer ${apiKey}`,
    'x-organization-id': orgId,
    'x-user-id': userId
  };

  // Get Spanish facility fuels
  const params = { country: 'ES' };

  axios.get('https://api.dcycle.io/api/v1/facility_fuels', { headers, params })
    .then(response => {
      const fuels = response.data;
      console.log(`Found ${fuels.length} facility fuels in Spain:`);

      fuels.forEach(fuel => {
        const unitsStr = fuel.units.map(u => u.name).join(', ');
        console.log(`- ${fuel.name} (${fuel.type}): ${unitsStr}`);
      });
    })
    .catch(error => console.error(error));
  ```
</CodeGroup>

### Successful Response

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "Natural gas",
    "country": "ES",
    "type": "gas",
    "ghg_type": 1,
    "units": [
      {
        "id": "unit-1-uuid",
        "name": "m³",
        "type": "gas"
      },
      {
        "id": "unit-2-uuid",
        "name": "kWh",
        "type": "energy"
      },
      {
        "id": "unit-3-uuid",
        "name": "kWh HHV",
        "type": "energy"
      }
    ]
  },
  {
    "id": "b2c3d4e5-f6g7-8901-bcde-fg2345678901",
    "name": "Diesel",
    "country": "ES",
    "type": "liquid",
    "ghg_type": 1,
    "units": [
      {
        "id": "unit-4-uuid",
        "name": "L",
        "type": "liquid"
      },
      {
        "id": "unit-5-uuid",
        "name": "kWh",
        "type": "energy"
      }
    ]
  },
  {
    "id": "c3d4e5f6-g7h8-9012-cdef-gh3456789012",
    "name": "Propane (LPG)",
    "country": "ES",
    "type": "gas",
    "ghg_type": 1,
    "units": [
      {
        "id": "unit-6-uuid",
        "name": "kg",
        "type": "solid"
      },
      {
        "id": "unit-7-uuid",
        "name": "L",
        "type": "liquid"
      }
    ]
  }
]
```

## Common Errors

### 400 Bad Request - Invalid Country Code

**Cause:** Invalid country code format

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": "Invalid country code format",
  "code": "VALIDATION_ERROR"
}
```

**Solution:** Use a valid ISO 3166-1 alpha-2 country code (2 letters, e.g., "ES", "FR", "DE").

### 403 Forbidden

**Cause:** Organization ID doesn't match your API key or user doesn't belong to organization

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": "Not authorized",
  "code": "FORBIDDEN"
}
```

**Solution:** Verify that `x-organization-id` matches your API key's organization.

## Use Cases

### Create Process Invoice with Facility Fuel

When creating a process invoice for fuel consumption at a facility:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def create_natural_gas_invoice(facility_id, consumption_m3):
    """Create invoice for natural gas consumption"""

    # 1. Get Spanish facility fuels
    response = requests.get(
        "https://api.dcycle.io/api/v1/facility_fuels",
        headers=headers,
        params={"country": "ES"}
    )

    fuels = response.json()

    # 2. Find natural gas fuel
    natural_gas = next(
        (f for f in fuels if "Natural gas" in f['name']),
        None
    )

    if not natural_gas:
        print("⚠️ Natural gas fuel not found")
        return

    # 3. Find m³ unit for this fuel
    m3_unit = next(
        (u for u in natural_gas['units'] if u['name'] == 'm³'),
        None
    )

    if not m3_unit:
        print("⚠️ m³ unit not available for natural gas")
        return

    # 4. Create process invoice
    invoice_data = {
        "type": "process",
        "base_quantity": consumption_m3,
        "unit_id": m3_unit['id'],
        "facility_fuel_id": natural_gas['id'],  # Critical: Include fuel ID
        "start_date": "2024-01-01",
        "end_date": "2024-01-31",
        "uploaded_by": "facility_manager",
        "facility_percentages": [
            {
                "facility_id": facility_id,
                "percentage": 1.0
            }
        ]
    }

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

    print(f"✅ Natural gas invoice created: {consumption_m3} m³")
    return response.json()

# Usage: Register 15,000 m³ of natural gas consumption
create_natural_gas_invoice(
    facility_id="facility-uuid",
    consumption_m3=15000.0
)
```

### Build Fuel Selector by Type

Create a UI selector organized by fuel type:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def get_fuels_by_type(country_code):
    """Get facility fuels organized by type"""

    response = requests.get(
        "https://api.dcycle.io/api/v1/facility_fuels",
        headers=headers,
        params={"country": country_code}
    )

    fuels = response.json()

    # Organize by type
    fuels_by_type = {}
    for fuel in fuels:
        fuel_type = fuel['type']
        if fuel_type not in fuels_by_type:
            fuels_by_type[fuel_type] = []

        fuels_by_type[fuel_type].append({
            'id': fuel['id'],
            'name': fuel['name'],
            'units': fuel['units']
        })

    return fuels_by_type

# Usage
fuels = get_fuels_by_type("ES")

print("Gas fuels:")
for fuel in fuels.get('gas', []):
    print(f"  - {fuel['name']}")

print("\nLiquid fuels:")
for fuel in fuels.get('liquid', []):
    print(f"  - {fuel['name']}")

print("\nSolid fuels:")
for fuel in fuels.get('solid', []):
    print(f"  - {fuel['name']}")
```

### Cache Fuels with Units

Cache facility fuels and their units for performance:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from datetime import datetime, timedelta

class DcycleFacilityFuelsCache:
    def __init__(self, api_key, org_id, user_id):
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "x-organization-id": org_id,
            "x-user-id": user_id
        }
        self._cache = {}
        self._cache_time = {}
        self.cache_duration = timedelta(hours=24)

    def get_fuels(self, country=None):
        """Get facility fuels with caching"""

        cache_key = country or 'all'

        # Check if cache is valid
        if (cache_key not in self._cache_time or
            datetime.now() - self._cache_time[cache_key] > self.cache_duration):
            self._refresh_cache(country)

        return self._cache.get(cache_key, [])

    def _refresh_cache(self, country=None):
        """Refresh the cache for a specific country"""

        params = {"country": country} if country else {}

        response = requests.get(
            "https://api.dcycle.io/api/v1/facility_fuels",
            headers=self.headers,
            params=params
        )

        fuels = response.json()

        cache_key = country or 'all'
        self._cache[cache_key] = fuels
        self._cache_time[cache_key] = datetime.now()

        print(f"✅ Facility fuels cache refreshed for '{cache_key}': {len(fuels)} fuels")

    def get_fuel_by_id(self, fuel_id, country=None):
        """Get a specific fuel by ID"""

        fuels = self.get_fuels(country)

        for fuel in fuels:
            if fuel['id'] == fuel_id:
                return fuel

        return None

    def get_fuel_by_name(self, name, country=None):
        """Get a fuel by name (case-insensitive partial match)"""

        fuels = self.get_fuels(country)

        for fuel in fuels:
            if name.lower() in fuel['name'].lower():
                return fuel

        return None

    def get_unit_for_fuel(self, fuel_id, unit_name, country=None):
        """Get a specific unit for a fuel"""

        fuel = self.get_fuel_by_id(fuel_id, country)

        if not fuel:
            return None

        for unit in fuel.get('units', []):
            if unit['name'].lower() == unit_name.lower():
                return unit

        return None

# Usage
cache = DcycleFacilityFuelsCache(
    api_key=os.getenv("DCYCLE_API_KEY"),
    org_id=os.getenv("DCYCLE_ORG_ID"),
    user_id=os.getenv("DCYCLE_USER_ID")
)

# First call fetches from API
natural_gas = cache.get_fuel_by_name("Natural gas", "ES")
m3_unit = cache.get_unit_for_fuel(natural_gas['id'], "m³", "ES")

# Subsequent calls use cache (no API request)
diesel = cache.get_fuel_by_name("Diesel", "ES")
```

### Validate Unit Compatibility

Ensure selected unit is valid for the chosen fuel:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def validate_unit_for_fuel(fuel_id, unit_id, country):
    """Validate that a unit is available for a specific fuel"""

    # Get fuel details
    response = requests.get(
        "https://api.dcycle.io/api/v1/facility_fuels",
        headers=headers,
        params={"country": country}
    )

    fuels = response.json()

    # Find fuel
    fuel = next((f for f in fuels if f['id'] == fuel_id), None)

    if not fuel:
        raise ValueError(f"Fuel {fuel_id} not found")

    # Check if unit is available for this fuel
    unit_ids = [u['id'] for u in fuel['units']]

    if unit_id not in unit_ids:
        available_units = [u['name'] for u in fuel['units']]
        raise ValueError(
            f"Unit {unit_id} is not valid for fuel '{fuel['name']}'. "
            f"Available units: {', '.join(available_units)}"
        )

    return True

# Usage
try:
    validate_unit_for_fuel(
        fuel_id="natural-gas-uuid",
        unit_id="m3-unit-uuid",
        country="ES"
    )
    print("✅ Unit is valid for this fuel")
except ValueError as e:
    print(f"❌ Validation error: {e}")
```

### Match Fuel Name from Invoice

If you have invoices with fuel names that need to be matched:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def match_fuel_name(invoice_fuel_name, country):
    """Match an invoice fuel name to Dcycle fuel ID"""

    # Get fuels for country
    response = requests.get(
        "https://api.dcycle.io/api/v1/facility_fuels",
        headers=headers,
        params={"country": country}
    )

    fuels = response.json()

    # Normalize invoice name
    normalized_name = invoice_fuel_name.lower().strip()

    # Try exact match first
    for fuel in fuels:
        if fuel['name'].lower() == normalized_name:
            return fuel['id']

    # Try partial match
    for fuel in fuels:
        if normalized_name in fuel['name'].lower():
            return fuel['id']

    # Try reverse partial match
    for fuel in fuels:
        if fuel['name'].lower() in normalized_name:
            return fuel['id']

    # Try fuzzy matching for common variations
    fuel_aliases = {
        'gas natural': 'Natural gas',
        'gasoleo': 'Diesel',
        'gas oil': 'Diesel',
        'glp': 'Propane (LPG)',
        'fuel oil': 'Heating oil'
    }

    for alias, standard_name in fuel_aliases.items():
        if alias in normalized_name:
            for fuel in fuels:
                if standard_name.lower() in fuel['name'].lower():
                    return fuel['id']

    # No match found
    print(f"⚠️ Could not match fuel: '{invoice_fuel_name}'")
    return None

# Usage examples
fuel_names = [
    "Gas Natural",
    "Gasoleo C",
    "GLP Granel"
]

for name in fuel_names:
    fuel_id = match_fuel_name(name, "ES")
    if fuel_id:
        print(f"✅ Matched '{name}' → {fuel_id}")
```

## Country-Specific Behavior

### Spain (ES)

Spain has a comprehensive database of facility fuels including:

* **Natural gas** - With m³ and kWh units
* **Diesel** - For generators and heating
* **Heating oil** - For industrial heating
* **Propane (LPG)** - For cooking and heating
* **Biomass fuels** - Wood pellets, chips
* **Coal** - For industrial processes

Spanish facility fuels include country-specific emission factors based on national regulations.

### Other Countries

For countries other than Spain, the system returns generic fuels from the **GHG Protocol database**. These use standard emission factors suitable for:

* Initial carbon footprint calculations
* Countries where fuel-specific data is not yet available
* Approximate emissions estimates

<Warning>
  If you need country-specific facility fuels beyond Spain, contact Dcycle support. We're continuously expanding our fuel databases.
</Warning>

## Fuel Types

The `type` field indicates the physical state of the fuel:

| Type     | Description   | Examples                      |
| -------- | ------------- | ----------------------------- |
| `gas`    | Gaseous fuels | Natural gas, propane, butane  |
| `liquid` | Liquid fuels  | Diesel, heating oil, gasoline |
| `solid`  | Solid fuels   | Coal, biomass, wood pellets   |
| `energy` | Energy-based  | Electricity, steam, heat      |

## GHG Types

The `ghg_type` field classifies fuels for emissions calculations:

| GHG Type | Description   | Biogenic CO2 Treatment           |
| -------- | ------------- | -------------------------------- |
| `1`      | Fossil fuels  | All CO2 counted as emissions     |
| `2`      | Biofuels      | Biogenic CO2 reported separately |
| `3`      | Mixed sources | Partially biogenic               |

<Info>
  Biogenic CO2 from biofuels (ghg\_type = 2) is reported separately in the `co2e_biomass` field and typically not counted toward carbon footprint totals per GHG Protocol standards.
</Info>

## Units per Fuel

Each fuel has specific units it can be measured in:

### Natural Gas Units

* **m³** (cubic meters) - Standard volumetric measurement
* **kWh** - Energy content
* **kWh HHV** - Higher heating value
* **kWh LHV** - Lower heating value

### Diesel/Liquid Fuel Units

* **L** (liters) - Volume measurement
* **kWh** - Energy content
* **kg** - Mass measurement

### LPG/Propane Units

* **kg** - Mass measurement (most common for LPG)
* **L** - Volume measurement
* **m³** - For gaseous phase

<Tip>
  Always check the `units` array for each fuel to see which units are available. Using an incompatible unit will result in an error when creating an invoice.
</Tip>

## Best Practices

### 1. Cache Reference Data

Since facility fuels don't change frequently, cache them:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Good - Cache for 24 hours
fuels_cache = cache.get_fuels("ES")

# Bad - Fetch every time
fuels = requests.get(f"https://api.dcycle.io/api/v1/facility_fuels?country=ES")
```

### 2. Use Country Filtering

Always filter by country when you know the facility's location:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Good - Only fetch Spanish fuels
spanish_fuels = get_fuels(country="ES")

# Less efficient - Fetch all and filter client-side
all_fuels = get_fuels()
spanish_fuels = [f for f in all_fuels if f['country'] == 'ES']
```

### 3. Validate Unit Before Invoice Creation

Check that the unit is in the fuel's units array:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def validate_invoice_data(fuel_id, unit_id):
    fuel = cache.get_fuel_by_id(fuel_id)
    unit_ids = [u['id'] for u in fuel['units']]

    if unit_id not in unit_ids:
        raise ValueError(f"Invalid unit for fuel '{fuel['name']}'")

    return True
```

### 4. Store Common Fuel IDs

For frequently used fuels, store their IDs in configuration:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# config.py
COMMON_FUELS_ES = {
    'natural_gas': 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
    'diesel': 'b2c3d4e5-f6g7-8901-bcde-fg2345678901',
    'propane': 'c3d4e5f6-g7h8-9012-cdef-gh3456789012'
}

# Usage - No API call needed
invoice_data = {
    "facility_fuel_id": COMMON_FUELS_ES['natural_gas'],
    # ... other fields
}
```

## Related Endpoints

<CardGroup cols={2}>
  <Card title="Create Invoice" icon="file-invoice" href="/api-docs/invoices/create">
    Create process invoices with facility fuels
  </Card>

  <Card title="List Units" icon="ruler" href="/api-docs/units/list">
    Get measurement units
  </Card>

  <Card title="List Facilities" icon="building" href="/api-docs/facilities/list">
    View your facilities
  </Card>

  <Card title="Authentication" icon="key" href="/api-docs/authentication">
    Learn about API authentication
  </Card>
</CardGroup>
