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

> Get a list of electricity and energy suppliers

# List Suppliers

Retrieve all electricity and energy suppliers available in the Dcycle system. Suppliers are required when creating invoices to track which company provided the energy or fuel.

<Note>
  Suppliers are **reference data** maintained by Dcycle. You cannot create or modify suppliers 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 suppliers by country using ISO 3166-1 alpha-2 country code

  **Supported country codes:**

  * `ES` - Spain (returns Spanish electricity suppliers)
  * Any other code returns generic GHG database suppliers

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

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

## Response

Returns an array of supplier objects (not paginated - all matching suppliers are returned).

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

  ### Supplier Object Fields:

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

  <ResponseField name="name" type="string">
    Supplier company name (e.g., "Iberdrola", "Endesa", "Naturgy")
  </ResponseField>

  <ResponseField name="country" type="string">
    ISO 3166-1 alpha-2 country code where supplier operates
  </ResponseField>

  <ResponseField name="type" type="string">
    Supplier type (e.g., "electricity", "gas", "heat")
  </ResponseField>
</ResponseField>

## Example

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X GET "https://api.dcycle.io/api/v1/suppliers?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 electricity suppliers
  params = {"country": "ES"}

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

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

  for supplier in suppliers:
      print(f"- {supplier['name']} ({supplier['type']})")
  ```

  ```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 electricity suppliers
  const params = { country: 'ES' };

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

      suppliers.forEach(supplier => {
        console.log(`- ${supplier.name} (${supplier.type})`);
      });
    })
    .catch(error => console.error(error));
  ```
</CodeGroup>

### Successful Response

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "Iberdrola",
    "country": "ES",
    "type": "electricity"
  },
  {
    "id": "b2c3d4e5-f6g7-8901-bcde-fg2345678901",
    "name": "Endesa",
    "country": "ES",
    "type": "electricity"
  },
  {
    "id": "c3d4e5f6-g7h8-9012-cdef-gh3456789012",
    "name": "Naturgy",
    "country": "ES",
    "type": "electricity"
  },
  {
    "id": "d4e5f6g7-h8i9-0123-defg-hi4567890123",
    "name": "Repsol",
    "country": "ES",
    "type": "electricity"
  }
]
```

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

### Get Suppliers for Invoice Creation

When creating an electricity invoice, you need the supplier ID:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def create_electricity_invoice_with_supplier(facility_id):
    """Create electricity invoice with Spanish supplier"""

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

    suppliers = response.json()

    # 2. Find Iberdrola supplier
    iberdrola = next(
        (s for s in suppliers if "Iberdrola" in s['name']),
        None
    )

    if not iberdrola:
        print("⚠️ Iberdrola supplier not found")
        return

    # 3. Create invoice with supplier
    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",
        "supplier_id": iberdrola['id'],  # Include supplier
        "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"✅ Invoice created with {iberdrola['name']}")
    return response.json()
```

### Build Supplier Dropdown Selector

Create a dropdown selector for your application:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def get_suppliers_for_dropdown(country_code):
    """Get suppliers organized for UI dropdown"""

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

    suppliers = response.json()

    # Organize by type
    suppliers_by_type = {}
    for supplier in suppliers:
        supplier_type = supplier['type']
        if supplier_type not in suppliers_by_type:
            suppliers_by_type[supplier_type] = []

        suppliers_by_type[supplier_type].append({
            'id': supplier['id'],
            'name': supplier['name']
        })

    return suppliers_by_type

# Usage
suppliers = get_suppliers_for_dropdown("ES")
electricity_suppliers = suppliers.get('electricity', [])

print("Electricity Suppliers:")
for s in electricity_suppliers:
    print(f"  - {s['name']}: {s['id']}")
```

### Cache Suppliers for Performance

Since suppliers are reference data that rarely changes, cache them:

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

class DcycleSuppliersCache:
    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_suppliers(self, country=None):
        """Get suppliers 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/suppliers",
            headers=self.headers,
            params=params
        )

        suppliers = response.json()

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

        print(f"✅ Suppliers cache refreshed for '{cache_key}': {len(suppliers)} suppliers")

    def get_supplier_by_id(self, supplier_id, country=None):
        """Get a specific supplier by ID"""

        suppliers = self.get_suppliers(country)

        for supplier in suppliers:
            if supplier['id'] == supplier_id:
                return supplier

        return None

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

        suppliers = self.get_suppliers(country)

        for supplier in suppliers:
            if name.lower() in supplier['name'].lower():
                return supplier

        return None

# Usage
cache = DcycleSuppliersCache(
    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
iberdrola = cache.get_supplier_by_name("Iberdrola", "ES")

# Subsequent calls use cache (no API request)
endesa = cache.get_supplier_by_name("Endesa", "ES")
```

### Get All Suppliers (No Country Filter)

Get all suppliers from all countries:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def get_all_suppliers():
    """Get all suppliers without country filter"""

    response = requests.get(
        "https://api.dcycle.io/api/v1/suppliers",
        headers=headers
        # No country param = all suppliers
    )

    suppliers = response.json()

    # Group by country
    by_country = {}
    for supplier in suppliers:
        country = supplier['country']
        if country not in by_country:
            by_country[country] = []
        by_country[country].append(supplier)

    # Display summary
    print("Suppliers by country:")
    for country, suppliers_list in by_country.items():
        print(f"  {country}: {len(suppliers_list)} suppliers")

    return suppliers

# Usage
all_suppliers = get_all_suppliers()
```

### Match Invoice Supplier to Your Data

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

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

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

    suppliers = response.json()

    # Try exact match first
    for supplier in suppliers:
        if supplier['name'].lower() == invoice_supplier_name.lower():
            return supplier['id']

    # Try partial match
    for supplier in suppliers:
        if invoice_supplier_name.lower() in supplier['name'].lower():
            return supplier['id']

    # Try reverse partial match
    for supplier in suppliers:
        if supplier['name'].lower() in invoice_supplier_name.lower():
            return supplier['id']

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

# Usage examples
supplier_names = [
    "Iberdrola Generación S.A.U.",
    "ENDESA ENERGIA S.A.",
    "Naturgy Energy Group"
]

for name in supplier_names:
    supplier_id = match_supplier_name(name, "ES")
    if supplier_id:
        print(f"✅ Matched '{name}' → {supplier_id}")
```

## Country-Specific Behavior

### Spain (ES)

Spain has a comprehensive database of electricity suppliers including:

* Major utilities (Iberdrola, Endesa, Naturgy)
* Regional suppliers
* Green energy providers
* Cooperative energy suppliers

When you filter by `country=ES`, you get accurate emission factors specific to each Spanish electricity supplier.

### Other Countries

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

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

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

## Supplier Types

The `type` field indicates what kind of energy the supplier provides:

| Type          | Description                | Used For                           |
| ------------- | -------------------------- | ---------------------------------- |
| `electricity` | Electrical power suppliers | Electricity invoices (most common) |
| `gas`         | Natural gas suppliers      | Gas heating invoices               |
| `heat`        | District heating suppliers | Heat/steam invoices                |
| `other`       | Other energy types         | Special cases                      |

## Best Practices

### 1. Cache Reference Data

Since suppliers don't change frequently, cache them in your application:

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

# Bad - Fetch every time you need a supplier
supplier = requests.get(f"https://api.dcycle.io/api/v1/suppliers?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 suppliers
spanish_suppliers = get_suppliers(country="ES")

# Less efficient - Fetch all and filter client-side
all_suppliers = get_suppliers()
spanish_suppliers = [s for s in all_suppliers if s['country'] == 'ES']
```

### 3. Validate Supplier Country Matches Facility

Ensure the supplier's country matches the facility's country:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def validate_supplier_for_facility(supplier_id, facility_country):
    """Validate that supplier country matches facility country"""

    supplier = cache.get_supplier_by_id(supplier_id)

    if not supplier:
        raise ValueError(f"Supplier {supplier_id} not found")

    if supplier['country'] != facility_country:
        raise ValueError(
            f"Supplier country '{supplier['country']}' "
            f"doesn't match facility country '{facility_country}'"
        )

    return True
```

### 4. Handle Missing Suppliers Gracefully

If a supplier isn't found, provide a fallback:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def get_or_create_generic_supplier(supplier_name, country):
    """Get supplier or suggest generic option"""

    # Try to find supplier
    supplier = cache.get_supplier_by_name(supplier_name, country)

    if supplier:
        return supplier

    # Use generic supplier
    print(f"⚠️ Supplier '{supplier_name}' not found in {country}")
    print(f"💡 Using generic GHG supplier for {country}")

    generic_suppliers = cache.get_suppliers("GHG")
    if generic_suppliers:
        return generic_suppliers[0]

    return None
```

## Emission Factors

Suppliers in the Dcycle database include **supplier-specific emission factors** that represent:

* **Location-based emissions**: Based on the regional electricity grid mix
* **Market-based emissions**: Based on the supplier's specific energy mix and renewable energy certificates
* **Scope 2 calculations**: Used for GHG Protocol Scope 2 reporting

<Info>
  Supplier-specific emission factors are updated annually based on official disclosures and regulatory reports.
</Info>

## Related Endpoints

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

  <Card title="List Invoices" icon="list" href="/api-docs/invoices/list">
    View invoices with their suppliers
  </Card>

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

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