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

> Retrieve the unit catalog and resolve the unit_id required by invoices, purchases, wastes and vehicle consumptions

Retrieve the catalog of measurement units. Every endpoint that accepts a `unit_id` expects an id from this catalog, so this is where you resolve it — without hardcoding ids or asking support for a list.

<Note>
  **Reference data.** The catalog is global: the same ids apply to every organization, and the response is not filtered by the organization you authenticate with. Fetch it once, cache it, and look ids up locally.
</Note>

## Request

### Headers

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

  **Format:** Your API key string
</ParamField>

<ParamField header="x-organization-id" type="string" required>
  UUID of the organization the API key belongs to. Required even though the catalog itself is global — the key is validated against this organization.

  **Format:** UUID
</ParamField>

### Query Parameters

<ParamField query="type" type="string">
  Restrict the response to the units accepted in one context of use. Omit it to get the whole catalog.

  Accepted values: `vehicle_consumptions`, `products`, `use_of_product_combustion`, `use_of_product_electricity`, `use_of_product_water`, `use_of_product_fugitive`, `stationary_combustion`, `recharge`, `custom_emission_factors_purchases`, `water`, `non_currency_purchases`, `electricity`, `process`, `travels`, `transport_distribution`, `wastes`, `hotel_stays`

  Each value maps to a curated list of units, so this filter answers *"which units may I send for a vehicle consumption?"* rather than *"which units are kilograms?"*.
</ParamField>

<Warning>
  **`type` means two different things**, and mixing them up is the most common mistake with this endpoint.

  As a **query parameter** it is a *context of use* — the seventeen values listed above. In the **response** it is the *physical family* of the unit: `fiat_currency`, `mass`, `energy`, `volume`, `time` and around two dozen others. The two vocabularies do not overlap, so a value you read from a response is rejected as a filter.

  In particular **there is no `fiat_currency` filter on `/v2`**. To resolve a currency, either request the catalog without `type` and match on `name`, or use the legacy `GET /api/v1/units?type=fiat_currency`, which filters server-side but additionally requires the `x-user-id` header.
</Warning>

## Response

<ResponseField name="array" type="array[object]">
  Array of unit objects, ordered by `name`. The whole catalog is 359 entries, of which 112 are currencies — interleaved alphabetically with everything else, not grouped, so filter by `type` on your side rather than expecting a block.

  <Expandable title="Unit Object">
    <ResponseField name="id" type="string">
      Unit id (UUID). This is the value to send as `unit_id`.
    </ResponseField>

    <ResponseField name="name" type="string">
      Unit name in snake\_case, with its symbol or ISO code in parentheses — `euros_(eur)`, `calorie_(cal)`, `british_thermal_unit_(BTU)`.

      Match on this field rather than on a bare code: searching for `EUR` finds nothing, searching for `(eur)` finds the euro. Note that the words are lowercased but **the symbol keeps its own casing**, so a case-sensitive search for `(gbtu)` misses `giga_british_thermal_unit_(GBTU)`. Compare case-insensitively.
    </ResponseField>

    <ResponseField name="type" type="string">
      Physical family of the unit — `fiat_currency`, `mass`, `energy`, `volume`, `time`, `distance`, `area`, `gas`, `percentage`, `dimensionless`, among others. Descriptive only: it is not a valid value for the `type` filter (see the warning above).
    </ResponseField>
  </Expandable>
</ResponseField>

## Example

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  # Whole catalog — the only way to reach currencies on /v2
  curl -X GET "https://api.dcycle.io/v2/units" \
    -H "x-api-key: YOUR_API_KEY" \
    -H "x-organization-id: YOUR_ORGANIZATION_ID"

  # Only the units accepted for a vehicle consumption
  curl -X GET "https://api.dcycle.io/v2/units?type=vehicle_consumptions" \
    -H "x-api-key: YOUR_API_KEY" \
    -H "x-organization-id: YOUR_ORGANIZATION_ID"
  ```

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

  response = requests.get(
      "https://api.dcycle.io/v2/units",
      headers={
          "x-api-key": "YOUR_API_KEY",
          "x-organization-id": "YOUR_ORGANIZATION_ID",
      },
      timeout=30,
  )
  units = response.json()

  # Resolve the euro once, then reuse the id
  euro = next(u for u in units if "(eur)" in u["name"].lower())
  print(euro["id"])  # d3e37f2b-0fc3-4532-82f8-3890ab56ad37
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const response = await fetch("https://api.dcycle.io/v2/units", {
    headers: {
      "x-api-key": "YOUR_API_KEY",
      "x-organization-id": "YOUR_ORGANIZATION_ID",
    },
  });
  const units = await response.json();

  const euro = units.find((u) => u.name.toLowerCase().includes("(eur)"));
  console.log(euro.id); // d3e37f2b-0fc3-4532-82f8-3890ab56ad37
  ```
</CodeGroup>

### Successful Response

Returns `200 OK` with the unit array.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
[
  {
    "id": "d3e37f2b-0fc3-4532-82f8-3890ab56ad37",
    "name": "euros_(eur)",
    "type": "fiat_currency"
  },
  {
    "id": "5efe3139-4101-4fae-a29e-70c1e3d3495f",
    "name": "calorie_(cal)",
    "type": "energy"
  }
]
```

## Common Errors

### 401 Unauthorized

**Cause:** The `x-api-key` header is missing, or the key does not belong to the organization in `x-organization-id`.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "code": "INVALID_API_KEY",
  "detail": "Invalid API key for organization"
}
```

**Cause:** No credentials at all — neither an API key nor a JWT.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "code": "CREDENTIALS_REQUIRED",
  "detail": "Credentials required (API key or JWT token)"
}
```

### 422 Unprocessable Entity

**Cause:** `x-organization-id` is missing. This is the most common error on this endpoint: the catalog is global, but the header is still required.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": [
    {
      "loc": ["header", "x-organization-id"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}
```

**Cause:** `type` is not one of the seventeen accepted values. Note that the physical families you see in the response (`fiat_currency`, `mass`, …) are **not** accepted here.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": [
    {
      "loc": ["query", "type"],
      "msg": "value is not a valid enumeration member; permitted: 'vehicle_consumptions', 'products', 'use_of_product_combustion'",
      "type": "type_error.enum",
      "ctx": {
        "enum_values": ["vehicle_consumptions", "products", "use_of_product_combustion"]
      }
    }
  ]
}
```

## Use Cases

### Resolve the currency for a purchase or an invoice

Purchases and invoices take `unit_id` as the **currency** of the amount, not as a physical unit. Fetch the catalog once, find the currency by its ISO code in parentheses, and send that id:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
euro_id = next(u["id"] for u in units if "(eur)" in u["name"].lower())

requests.post(
    "https://api.dcycle.io/v1/purchases",
    headers={"x-api-key": KEY, "x-organization-id": ORG},
    json={
        "expense_type": "opex",          # "capex" or "opex"
        "product_name": "Office paper",
        "purchase_date": "2026-01-31",
        "quantity": 1500.0,
        "unit_id": euro_id,
    },
    timeout=30,
)
```

`expense_type`, `product_name` and `purchase_date` are required, and the schema rejects unknown fields — so a `date` key instead of `purchase_date` fails validation rather than being ignored.

### Validate before you send

When you accept units from your own users, pull the list for that context (`type=wastes`, `type=travels`…) and offer only those. It turns a 422 at write time into a closed dropdown.

## Related Endpoints

<CardGroup cols={2}>
  <Card title="Create Purchase" icon="cart-shopping" href="/api-reference/purchases/create">
    Takes `unit_id` as the currency of the amount
  </Card>

  <Card title="Create Invoice" icon="file-invoice" href="/api-reference/invoices/create">
    Takes `unit_id` for the invoice amount
  </Card>

  <Card title="List Waste Emission Factors" icon="recycle" href="/api-reference/wastes/emission-factors">
    LER and RD code catalog, the other lookup you need before writing waste records
  </Card>

  <Card title="List Vehicle Fuels" icon="gas-pump" href="/api-reference/vehicle-fuels/list">
    Fuel catalog, with the units accepted for each fuel
  </Card>
</CardGroup>
