Python SDK (Beta)

The Python SDK is an auto-generated client library for the EnergyCAP REST API. It provides typed methods for every API endpoint and handles JSON serialization, so you can work with EnergyCAP data as native Python objects.

Tip
The Python SDK is currently in beta. The API surface may change between releases. Pin your dependency version in production.

Installation

Install from PyPI:

pip install EnergyCapSdk
Package EnergyCapSdk
Current version 8.2309.4878
Dependency msrest >= 0.5.2
Distribution Universal wheel (py3-none-any)

Quick Start

1. Create a client and authenticate

from energycap.sdk import EnergyCapApi

# Create the client pointing to your environment
api = EnergyCapApi(base_url="https://app.energycap.com")

# Authenticate with your API key (recommended)
api.config.headers["ECI-ApiKey"] = "YOUR_API_KEY"

2. Make a request

# Get the first page of meters
meters = api.get_meters(page_size=10, page_number=1)

for meter in meters:
    print(f"{meter.meter_id}: {meter.meter_code}{meter.meter_info}")

Authentication

Set the ECI-ApiKey header on the client configuration:

from energycap.sdk import EnergyCapApi

api = EnergyCapApi(base_url="https://app.energycap.com")
api.config.headers["ECI-ApiKey"] = "YOUR_API_KEY"

See Authentication for how to create and manage API keys.

Credential-based (legacy)

Tip
Credential-based authentication is deprecated and will be removed in a future release. Migrate to API key authentication.
from energycap.sdk import EnergyCapApi, models

api = EnergyCapApi(base_url="https://implement.energycap.com")

# Log in with credentials to get a token
auth_request = models.LoginRequest("datasource", "password", "username")
auth_response = api.login(login_request=auth_request)

# Set the token for subsequent requests
api.config.headers["Authorization"] = "bearer " + auth_response.token

Base URL

Set the base URL to match your organization’s environment:

Environment Base URL
US East (Production) https://app.energycap.com
US West https://wce.energycap.com
EU https://app-eu.energycap.com
FedRAMP https://app.fed-energycap.com
Implementation https://implement.energycap.com

Common Operations

Retrieve a single resource

# Get a specific meter by ID
meter = api.get_meter(meter_id=1234)
print(f"{meter.meter_code}: {meter.meter_info}")

List resources with filters

# Get all electric accounts
accounts = api.get_accounts(filter="commodityCode equals 'ELECTRIC'")

for account in accounts:
    print(f"{account.account_id}: {account.account_code}")

See Filters for the full filter syntax.

Create a resource

# Create a new bill
bill_request = models.BillCreateRequest(
    account_id=1234,
    vendor_id=10,
    period_start="2025-01-01",
    period_end="2025-01-31",
    statement_date="2025-02-05"
)

bill = api.create_bill(body=bill_request)
print(f"Created bill {bill.bill_id}")

Update a resource

# Update an existing account
update_request = models.AccountEditRequest(
    account_code="ACCT-001-UPDATED",
    account_info="Updated Account Description"
)

account = api.edit_account(account_id=1234, body=update_request)

Delete a resource

api.delete_meter(meter_id=1234)

Pagination

List endpoints return one page of results at a time. Use page_number and page_size parameters to iterate through all records.

Basic iteration

all_meters = []
page = 1
page_size = 500

while True:
    meters = api.get_meters(page_size=page_size, page_number=page)

    if not meters:
        break

    all_meters.extend(meters)

    # If we got fewer results than page_size, we've reached the last page
    if len(meters) < page_size:
        break

    page += 1

print(f"Retrieved {len(all_meters)} meters")

Using response headers

To access pagination metadata (total pages, total records), use the raw HTTP response:

response = api.get_meters_with_http_info(page_size=500, page_number=1)

meters = response[0]           # Response body
status_code = response[1]      # HTTP status code
headers = response[2]          # Response headers

total_pages = int(headers.get("TotalPages", 1))
total_records = int(headers.get("TotalNumberOfRecords", 0))

print(f"Page 1 of {total_pages} ({total_records} total records)")

See Pagination for more details.

Field Reduction

Reduce response size by requesting only the fields you need:

# Only return meterId, meterCode, and meterInfo
meters = api.get_meters(field="meterId,meterCode,meterInfo")

See Field Reduction for include/exclude modes.

Error Handling

The SDK raises exceptions from the msrest library when the API returns an error:

from msrest.exceptions import HttpOperationError

try:
    meter = api.get_meter(meter_id=99999)
except HttpOperationError as e:
    print(f"Status: {e.response.status_code}")
    print(f"Body: {e.response.text}")

    # Common status codes:
    # 400 — Bad request (check your parameters)
    # 401 — Unauthorized (invalid API key)
    # 404 — Resource not found
    # 429 — Rate limited (wait and retry)

Handling rate limits

import time
from msrest.exceptions import HttpOperationError

def get_meters_with_retry(api, **kwargs):
    try:
        return api.get_meters(**kwargs)
    except HttpOperationError as e:
        if e.response.status_code == 429:
            print("Rate limited — waiting 10 seconds...")
            time.sleep(10)
            return api.get_meters(**kwargs)
        raise

Bulk Data Retrieval

Combine pagination, filters, and field reduction for efficient bulk operations:

def get_all_bills_for_account(api, account_id):
    """Retrieve all bills for a given account with minimal fields."""
    all_bills = []
    page = 1
    page_size = 1000

    while True:
        bills = api.get_bills(
            filter=f"accountId equals '{account_id}'",
            field="billId,totalCost,totalUse,periodStart,periodEnd",
            page_size=page_size,
            page_number=page
        )

        if not bills:
            break

        all_bills.extend(bills)

        if len(bills) < page_size:
            break

        page += 1

    return all_bills


bills = get_all_bills_for_account(api, account_id=1234)
print(f"Found {len(bills)} bills")
for bill in bills:
    print(f"  Bill {bill.bill_id}: ${bill.total_cost} ({bill.period_start}{bill.period_end})")

Configuration

Custom timeout

from msrest import Configuration

api = EnergyCapApi(base_url="https://app.energycap.com")
api.config.headers["ECI-ApiKey"] = "YOUR_API_KEY"

# Set timeout to 5 minutes for large operations
api.config.connection.timeout = 300

Custom session headers

# Add a custom user agent to identify your integration
api.config.headers["User-Agent"] = "MyIntegration/1.0"