C# SDK

The C# SDK is a strongly-typed client library for the EnergyCAP REST API. It provides auto-generated methods for every API endpoint, typed request/response models, and built-in JSON serialization — so you can work with EnergyCAP data as native C# objects.

Installation

Install from NuGet:

dotnet add package EnergyCap.Sdk

Or via the Package Manager Console:

Install-Package EnergyCap.Sdk
Package EnergyCap.Sdk
Current version 8.2512.6600
Target framework .NET Standard 2.0
Dependency Microsoft.Rest.ClientRuntime >= 2.3.11

Compatibility

The SDK targets .NET Standard 2.0, which means it works with:

  • .NET 6, 7, 8, 9, 10+
  • .NET Core 2.0+
  • .NET Framework 4.6.1+

Namespaces

Namespace Contains
EnergyCap.Sdk The EnergyCapApi client class and interface
EnergyCap.Sdk.Models All request body and response model classes
EnergyCap.Sdk.Extensions EnergyCapApiClientFactory, EnergyCapEnvironments, and helper extensions

Quick Start

1. Create a client

Use EnergyCapApiClientFactory to create an authenticated client. This factory configures the underlying HttpClient with the correct authorization headers and JSON serialization settings.

using EnergyCap.Sdk;
using EnergyCap.Sdk.Models;
using EnergyCap.Sdk.Extensions;

var settings = new EnergyCapClientSettingsApiKeyAuth
{
    ApiKey = "YOUR_API_KEY"
};

var client = await EnergyCapApiClientFactory.CreateClientAsync(settings);

2. Make a request

// Get the first page of meters
var response = await client.GetMetersWithHttpMessagesAsync(
    pageSize: 10, pageNumber: 1);

foreach (var meter in response.Body)
{
    Console.WriteLine($"{meter.MeterId}: {meter.MeterCode} — {meter.MeterInfo}");
}

Client Configuration

EnergyCapClientSettingsApiKeyAuth supports the following options:

Property Type Default Description
ApiKey string required Your EnergyCAP API key
EnvironmentUrl string Encoded in the API key Override the target environment URL. Not recommended for hosted customers — the API key already encodes the correct environment.
TimeoutSeconds int 100 Seconds before a request times out. Increase for bulk operations or large exports.
UserAgentSuffix string null Appended to the User-Agent header on all requests. Useful for identifying your integration in server logs.
HttpClientHandler HttpClientHandler null Custom handler for the underlying HttpClient (e.g. for proxy configuration).
DelegatingHandlers DelegatingHandler[] null Pipeline handlers for logging, retry logic, or other cross-cutting concerns.

Environment URLs

The SDK provides environment constants in EnergyCapEnvironments:

// Use a specific environment
var settings = new EnergyCapClientSettingsApiKeyAuth
{
    ApiKey = "YOUR_API_KEY",
    EnvironmentUrl = EnergyCapEnvironments.Implementation
};

See Environments for the full list of available environments.

Common Operations

Retrieve a single resource

// Get a specific meter by ID
var meter = await client.GetMeterAsync(meterId: 1234);
Console.WriteLine($"{meter.MeterCode}: {meter.MeterInfo}");

List resources with filters

// Get all electric meters
var meters = await client.GetMetersAsync(
    filter: "commodityCode equals 'ELECTRIC'");

foreach (var meter in meters)
{
    Console.WriteLine($"{meter.MeterId}: {meter.MeterCode}");
}

See Filters for the full filter syntax.

Create a resource

// Create a new account
var request = new AccountCreateRequest
{
    AccountCode = "ACCT-NEW-001",
    AccountInfo = "New Office Account",
    VendorId = 10,
    AccountTypeId = 1
};

var account = await client.CreateAccountAsync(body: request);
Console.WriteLine($"Created account {account.AccountId}");

Update a resource

// Update an existing meter
var update = new MeterEditRequest
{
    MeterCode = "MTR-001-UPDATED",
    MeterInfo = "Updated Meter Description"
};

var meter = await client.EditMeterAsync(meterId: 1234, body: update);

Delete a resource

await client.DeleteMeterAsync(meterId: 1234);

Pagination

List endpoints return paginated results. The SDK has two method variants for each list endpoint:

Method Returns Use when
GetMetersAsync(...) IList<MeterResponse> You only need the data and don’t care about page count
GetMetersWithHttpMessagesAsync(...) HttpOperationResponse with .Body and .Headers You need pagination metadata (TotalPages, TotalNumberOfRecords, etc.)

Iterating through all pages

var allMeters = new List<MeterResponse>();
int page = 1;
int totalPages = 1;
int pageSize = 500;

while (page <= totalPages)
{
    var response = await client.GetMetersWithHttpMessagesAsync(
        pageSize: pageSize, pageNumber: page);

    allMeters.AddRange(response.Body);
    totalPages = response.Headers.TotalPages.Value;
    page++;
}

Console.WriteLine($"Retrieved {allMeters.Count} meters across {totalPages} pages");

Pagination headers

The WithHttpMessagesAsync response headers include:

Header Type Description
PageNumber int? Current page number
PageSize int? Items per page
TotalPages int? Total number of pages
TotalNumberOfRecords int? Total matching records

Parallel page fetching

Once you know the total page count from the first request, fetch remaining pages concurrently:

// Get first page to determine total pages
var firstResponse = await client.GetMetersWithHttpMessagesAsync(
    pageSize: 500, pageNumber: 1);

var allMeters = new List<MeterResponse>(firstResponse.Body);
int totalPages = firstResponse.Headers.TotalPages.Value;

// Fetch remaining pages in parallel (limit concurrency to 5)
var semaphore = new SemaphoreSlim(5);
var tasks = Enumerable.Range(2, totalPages - 1).Select(async pageNum =>
{
    await semaphore.WaitAsync();
    try
    {
        var response = await client.GetMetersWithHttpMessagesAsync(
            pageSize: 500, pageNumber: pageNum);
        return response.Body;
    }
    finally
    {
        semaphore.Release();
    }
});

var pages = await Task.WhenAll(tasks);
foreach (var page in pages)
{
    allMeters.AddRange(page);
}

Console.WriteLine($"Retrieved {allMeters.Count} meters");

See Pagination for more details.

Field Reduction

Reduce response payload size by requesting only the fields you need:

// Only return meterId, meterCode, and meterInfo
var meters = await client.GetMetersAsync(
    field: "meterId,meterCode,meterInfo");

See Field Reduction for include/exclude modes and more examples.

Error Handling

The SDK throws HttpOperationException when the API returns a non-success status code. The exception includes the full HTTP response for debugging:

using Microsoft.Rest;

try
{
    var meter = await client.GetMeterAsync(meterId: 99999);
}
catch (HttpOperationException ex)
{
    Console.WriteLine($"Status: {ex.Response.StatusCode}");
    Console.WriteLine($"Body: {ex.Response.Content}");

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

Handling rate limits

try
{
    var meters = await client.GetMetersAsync();
}
catch (HttpOperationException ex) when (ex.Response.StatusCode == System.Net.HttpStatusCode.TooManyRequests)
{
    // Wait and retry after a delay
    await Task.Delay(TimeSpan.FromSeconds(10));
    var meters = await client.GetMetersAsync();
}

Advanced Configuration

Custom timeout for long-running operations

var settings = new EnergyCapClientSettingsApiKeyAuth
{
    ApiKey = "YOUR_API_KEY",
    TimeoutSeconds = 600  // 10 minutes for large bill imports
};

Adding a delegating handler for logging

public class LoggingHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        Console.WriteLine($"{request.Method} {request.RequestUri}");
        var response = await base.SendAsync(request, cancellationToken);
        Console.WriteLine($"  → {(int)response.StatusCode} {response.StatusCode}");
        return response;
    }
}

var settings = new EnergyCapClientSettingsApiKeyAuth
{
    ApiKey = "YOUR_API_KEY",
    DelegatingHandlers = new DelegatingHandler[] { new LoggingHandler() }
};

Proxy configuration

var handler = new HttpClientHandler
{
    Proxy = new WebProxy("http://proxy.example.com:8080"),
    UseProxy = true
};

var settings = new EnergyCapClientSettingsApiKeyAuth
{
    ApiKey = "YOUR_API_KEY",
    HttpClientHandler = handler
};

Legacy: Credential Authentication

Tip
Credential-based authentication is deprecated. Migrate to API key authentication as soon as possible. See Authentication for details.
var settings = new EnergyCapClientSettingsCredentialAuth
{
    DataSource = "your_datasource",
    Username = "your_username",
    Password = "your_password",
    EnvironmentUrl = EnergyCapEnvironments.Implementation,
    TimeoutSeconds = 300
};

var client = await EnergyCapApiClientFactory.CreateClientAsync(settings);

With credential auth, you must set EnvironmentUrl explicitly because there is no API key to derive it from.