Skip to main content
GET
https://api.dcycle.io
/
api
/
v1
/
units
List Units
const options = {
  method: 'GET',
  headers: {
    'x-api-key': '<x-api-key>',
    'x-organization-id': '<x-organization-id>',
    'x-user-id': '<x-user-id>'
  }
};

fetch('https://api.dcycle.io/api/v1/units', options)
  .then(res => res.json())
  .then(res => console.log(res))
  .catch(err => console.error(err));
{
  "[]": [
    {
      "id": "<string>",
      "name": "<string>",
      "type": "<string>"
    }
  ]
}

List Units

Retrieve all measurement units available in the Dcycle system. These units are used when creating invoices, purchases, and other consumption records to specify quantities.
Units are reference data maintained by Dcycle. You cannot create or modify units through the API - this endpoint is read-only.

Request

Headers

x-api-key
string
required
Your API key for authenticationExample: sk_live_1234567890abcdef
x-organization-id
string
required
Your organization UUIDExample: ff4adcc7-8172-45fe-9cf1-e90a6de53aa9
x-user-id
string
required
Your user UUIDExample: a1b2c3d4-e5f6-7890-abcd-ef1234567890

Query Parameters

type
string
Filter units by type categoryValid values:
  • energy - Energy units (kWh, MWh, GJ, etc.)
  • gas - Gas volume units (m³, ft³, etc.)
  • liquid - Liquid volume units (L, m³, gal, etc.)
  • solid - Solid mass/volume units (kg, ton, m³, etc.)
  • fiat_currency - Currency units (EUR, USD, etc.)
  • dimensionless - Unitless quantities
  • substance - Chemical substance units
  • waste_water_treatment_dbo - Biochemical oxygen demand
  • waste_water_treatment_dbo_out - BOD output measurements
  • waste_water_treatment_ch4 - Methane measurements
  • waste_water_treatment_nitrogen - Nitrogen measurements
  • waste_water_treatments_flow_total - Flow rate measurements
  • area_time - Area-time combined units
  • toxicity - Toxicity measurements
  • radioactivity - Radioactivity measurements
  • purchases_supplier_specific - Supplier-specific purchase units
Example: "energy"

Response

Returns an array of unit objects (not paginated - all matching units are returned).
[]
array
Array of unit objects

Unit Object Fields:

id
string
Unique unit identifier (UUID v4)
name
string
Human-readable unit name (e.g., “kWh”, “m³”, “kg”)
type
string
Unit type category (see valid values above)

Example

curl -X GET "https://api.dcycle.io/api/v1/units?type=energy" \
  -H "Authorization: Bearer ${DCYCLE_API_KEY}" \
  -H "x-organization-id: ${DCYCLE_ORG_ID}" \
  -H "x-user-id: ${DCYCLE_USER_ID}"

Successful Response

[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "kWh",
    "type": "energy"
  },
  {
    "id": "b2c3d4e5-f6g7-8901-bcde-fg2345678901",
    "name": "MWh",
    "type": "energy"
  },
  {
    "id": "c3d4e5f6-g7h8-9012-cdef-gh3456789012",
    "name": "GJ",
    "type": "energy"
  },
  {
    "id": "d4e5f6g7-h8i9-0123-defg-hi4567890123",
    "name": "kWh HHV",
    "type": "energy"
  }
]

Common Errors

400 Bad Request - Invalid Type

{
  "detail": "Invalid unit type",
  "code": "VALIDATION_ERROR"
}
Solution: Verify that the type parameter matches one of the valid values listed above.

403 Forbidden

Cause: Organization ID doesn’t match your API key or user doesn’t belong to organization
{
  "detail": "Not authorized",
  "code": "FORBIDDEN"
}
Solution: Verify that x-organization-id matches your API key’s organization.

Use Cases

Get Energy Units for Invoice Creation

When creating an invoice, you need the unit ID for the base_quantity field:
def get_energy_units():
    """Get all energy units available"""
    response = requests.get(
        "https://api.dcycle.io/api/v1/units",
        headers=headers,
        params={"type": "energy"}
    )

    units = response.json()

    # Create lookup dictionary
    units_by_name = {unit['name']: unit['id'] for unit in units}

    return units_by_name

# Usage: Get kWh unit ID for invoice
energy_units = get_energy_units()
kwh_unit_id = energy_units.get('kWh')

# Now create invoice with this unit
invoice_data = {
    "type": "electricity",
    "base_quantity": 15000.0,
    "unit_id": kwh_unit_id,
    "start_date": "2024-01-01",
    "end_date": "2024-01-31",
    "uploaded_by": "energy_manager",
    "facility_percentages": [
        {
            "facility_id": "facility-uuid-here",
            "percentage": 1.0
        }
    ]
}

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

Get All Units for Dropdown Selector

Build a complete unit selector for your application:
def get_all_units():
    """Get all units organized by type"""
    response = requests.get(
        "https://api.dcycle.io/api/v1/units",
        headers=headers
    )

    all_units = response.json()

    # Organize by type
    units_by_type = {}
    for unit in all_units:
        unit_type = unit['type']
        if unit_type not in units_by_type:
            units_by_type[unit_type] = []
        units_by_type[unit_type].append(unit)

    return units_by_type

# Usage
units = get_all_units()
print(f"Available unit types: {list(units.keys())}")
print(f"Energy units: {[u['name'] for u in units.get('energy', [])]}")
print(f"Gas units: {[u['name'] for u in units.get('gas', [])]}")

Cache Units for Performance

Since units are reference data that rarely changes, cache them:
import functools
from datetime import datetime, timedelta

class DcycleUnitsCache:
    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 = None
        self.cache_duration = timedelta(hours=24)

    def get_units(self, unit_type=None):
        """Get units with caching"""
        # Check if cache is valid
        if (self._cache_time is None or
            datetime.now() - self._cache_time > self.cache_duration):
            self._refresh_cache()

        # Return cached data
        if unit_type:
            return [u for u in self._cache.values() if u['type'] == unit_type]
        return list(self._cache.values())

    def _refresh_cache(self):
        """Refresh the cache"""
        response = requests.get(
            "https://api.dcycle.io/api/v1/units",
            headers=self.headers
        )

        units = response.json()
        self._cache = {unit['id']: unit for unit in units}
        self._cache_time = datetime.now()

        print(f"✅ Units cache refreshed: {len(self._cache)} units loaded")

    def get_unit_by_id(self, unit_id):
        """Get a specific unit by ID"""
        if unit_id not in self._cache:
            self._refresh_cache()
        return self._cache.get(unit_id)

    def get_unit_by_name(self, name, unit_type=None):
        """Get a unit by name"""
        units = self.get_units(unit_type)
        for unit in units:
            if unit['name'].lower() == name.lower():
                return unit
        return None

# Usage
cache = DcycleUnitsCache(
    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
kwh_unit = cache.get_unit_by_name("kWh", "energy")

# Subsequent calls use cache (no API request)
mwh_unit = cache.get_unit_by_name("MWh", "energy")

Unit Types Breakdown

Most Common Types

Energy Units (type: "energy"):
  • Used for electricity invoices
  • Common units: kWh, MWh, GJ, kWh HHV, kWh LHV
  • Example: Electricity consumption from utility bills
Gas Units (type: "gas"):
  • Used for natural gas, propane, other gaseous fuels
  • Common units: m³, ft³, Nm³
  • Example: Natural gas heating consumption
Liquid Units (type: "liquid"):
  • Used for liquid fuels (diesel, gasoline, etc.)
  • Common units: L, m³, gal, bbl
  • Example: Diesel fuel for generators
Solid Units (type: "solid"):
  • Used for solid fuels and materials
  • Common units: kg, ton, tonne, lb
  • Example: Coal, biomass, waste materials

Specialized Types

Waste Water Treatment Units:
  • waste_water_treatment_dbo - Biochemical oxygen demand input
  • waste_water_treatment_dbo_out - BOD after treatment
  • waste_water_treatment_ch4 - Methane emissions from treatment
  • waste_water_treatment_nitrogen - Nitrogen content
  • waste_water_treatments_flow_total - Total flow rate
Other Specialized Units:
  • fiat_currency - For financial calculations (EUR, USD, etc.)
  • purchases_supplier_specific - Custom units from suppliers
  • substance - Chemical substances (kg CO2, kg NOx, etc.)
  • dimensionless - Ratios, percentages, counts
  • toxicity - Toxicity equivalents
  • radioactivity - Radioactive measurements

Best Practices

1. Cache Reference Data

Since units don’t change frequently, cache them in your application:
# Good - Cache for 24 hours
units_cache = cache.get_units()

# Bad - Fetch every time you need a unit
unit = requests.get(f"https://api.dcycle.io/api/v1/units?type=energy")

2. Use Type Filtering

Filter by type when you know the invoice category:
# Good - Only fetch energy units
energy_units = get_units(type="energy")

# Less efficient - Fetch all and filter client-side
all_units = get_units()
energy_units = [u for u in all_units if u['type'] == 'energy']

3. Store Unit IDs in Configuration

For common units, store their IDs in your configuration:
# config.py
COMMON_UNITS = {
    'kwh': 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
    'mwh': 'b2c3d4e5-f6g7-8901-bcde-fg2345678901',
    'm3_gas': 'c3d4e5f6-g7h8-9012-cdef-gh3456789012',
    'liters': 'd4e5f6g7-h8i9-0123-defg-hi4567890123'
}

# Usage - No API call needed
invoice_data = {
    "unit_id": COMMON_UNITS['kwh'],
    # ... other fields
}

4. Validate Units Before Invoice Creation

Check that the unit type matches the invoice type:
def validate_unit_for_invoice(unit_id, invoice_type):
    """Validate that unit matches invoice type"""

    # Define valid unit types for each invoice type
    valid_units = {
        'electricity': ['energy'],
        'heat': ['energy', 'gas'],
        'water': ['liquid'],
        'recharge': ['energy'],  # Electric vehicle charging
        'process': ['energy', 'gas', 'liquid', 'solid'],
        'wastes': ['solid', 'liquid'],
        'waste_water_treatment': [
            'waste_water_treatment_dbo',
            'waste_water_treatment_nitrogen',
            'waste_water_treatments_flow_total'
        ]
    }

    # Get unit details
    unit = cache.get_unit_by_id(unit_id)

    if unit['type'] not in valid_units.get(invoice_type, []):
        raise ValueError(
            f"Unit type '{unit['type']}' is not valid for invoice type '{invoice_type}'"
        )

    return True