WexHealth 1.0.0-beta.1

This is a prerelease version of WexHealth.
dotnet add package WexHealth --version 1.0.0-beta.1
                    
NuGet\Install-Package WexHealth -Version 1.0.0-beta.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="WexHealth" Version="1.0.0-beta.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="WexHealth" Version="1.0.0-beta.1" />
                    
Directory.Packages.props
<PackageReference Include="WexHealth" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add WexHealth --version 1.0.0-beta.1
                    
#r "nuget: WexHealth, 1.0.0-beta.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package WexHealth@1.0.0-beta.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=WexHealth&version=1.0.0-beta.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=WexHealth&version=1.0.0-beta.1&prerelease
                    
Install as a Cake Tool

WexHealth

WexHealth is the official .NET SDK for the Wex Health and Benefits APIs.

All external APIs merged for documentation and discovery

  • API version: 1.0.22
  • SDK version: 1.0.0-beta.1

Features

  • Typed clients for every endpoint defined in the OpenAPI specification.
  • OAuth2 Client Credentials authentication with automatic token acquisition, refresh, and thread-safe caching. Compatible with static bearer tokens for migration scenarios.
  • Resilience built in: timeout + retry pipeline (Polly v8) with exponential backoff, jitter, and Retry-After support.
  • First-class ASP.NET Core integration through AddWexHealthSdk(...) and IHttpClientFactory.
  • Multi-targeting: net6.0, net7.0, and net8.0 assemblies in a single package; NuGet selects the right one for your project.
  • Strong-named, signed, and timestamped package on NuGet.org.

Installation

.NET CLI

dotnet add package WexHealth

Package Manager Console

Install-Package WexHealth

PackageReference

<PackageReference Include="WexHealth" Version="1.0.0-beta.1" />

Dependencies

The package brings the following runtime dependencies:


Quick Start

using System;
using WexHealth.Api;
using WexHealth.Models;
using WexHealth.Client;

// 1. Provide OAuth2 credentials via environment variables (see "Authentication" below):
//    WEX_OAUTH2_TOKEN_URL, WEX_OAUTH2_CLIENT_ID, WEX_OAUTH2_CLIENT_SECRET

var config = new Configuration
{
    BasePath = "https://api.example.com" // production base URL provided by Wex
};

var claims = new ClaimsApi(config);

var personId    = Guid.Parse("550e8400-e29b-41d4-a716-446655440000");
var claimNumber = "11BPEB1210513P0000101";

Models.ClaimDTO claim = claims.GetClaim(personId, claimNumber);
Console.WriteLine(claim);

async overloads (GetClaimAsync, GetClaimsForParticipantAsync, …) are available for every operation.


Authentication

The SDK supports two authentication modes against the Bearer-protected API:

  1. OAuth2 Client Credentials (recommended) — the SDK acquires, caches, and refreshes access tokens automatically.
  2. Static Bearer Token — supply a long-lived token yourself for migration or testing.
Option 1 — Environment variables (zero-code)

The SDK detects OAuth2 credentials from environment variables and configures itself on first use:

Variable Required Purpose
WEX_OAUTH2_TOKEN_URL Yes Token endpoint URL — must be HTTPS.
WEX_OAUTH2_CLIENT_ID Yes OAuth2 client ID issued for your application.
WEX_OAUTH2_CLIENT_SECRET Yes OAuth2 client secret. Treat as a secret.
WEX_OAUTH2_AUDIENCE No Optional audience parameter.
# Linux / macOS
export WEX_OAUTH2_TOKEN_URL="https://auth.example.com/oauth/token"
export WEX_OAUTH2_CLIENT_ID="your-client-id"
export WEX_OAUTH2_CLIENT_SECRET="your-client-secret"
export WEX_OAUTH2_AUDIENCE="https://api.example.com"   # optional
# Windows PowerShell
$env:WEX_OAUTH2_TOKEN_URL    = "https://auth.example.com/oauth/token"
$env:WEX_OAUTH2_CLIENT_ID    = "your-client-id"
$env:WEX_OAUTH2_CLIENT_SECRET = "your-client-secret"
$env:WEX_OAUTH2_AUDIENCE     = "https://api.example.com"   # optional
var config = new Configuration { BasePath = "https://api.example.com" };

// Authentication is auto-configured from environment variables.
var claims = new ClaimsApi(config);
Option 2 — Programmatic configuration
using WexHealth.Api;
using WexHealth.Auth;
using WexHealth.Client;

var oauth = new OAuth2ClientCredentialsAuth(
    tokenUrl:     "https://auth.example.com/oauth/token",
    clientId:     "your-client-id",
    clientSecret: "your-client-secret",
    audience:     "https://api.example.com"); // optional

var config = new Configuration { BasePath = "https://api.example.com" };
var claims = new ClaimsApi(config);
claims.ApiClient.SetAuthentication("bearerAuth", oauth);

Token-management defaults:

  • Refresh buffer: tokens are renewed 60 seconds before expiry.
  • Token retry: up to 3 attempts with exponential backoff on token-endpoint failures.
  • Concurrency: thread-safe; concurrent API calls share a single in-memory token.
  • Transport: the token endpoint must use HTTPS (constructor throws otherwise).

Static Bearer Token

var config = new Configuration
{
    BasePath    = "https://api.example.com",
    AccessToken = "YOUR_BEARER_TOKEN"
};

var claims = new ClaimsApi(config);

Static tokens do not refresh. Renew the token in your application code before it expires.


ASP.NET Core Integration

For ASP.NET Core, use AddWexHealthSdk(...) to register typed clients with IHttpClientFactory. The SDK provides the API surface; your application owns the base URL, authentication handler, and resilience overrides.

using WexHealth.Api;
using WexHealth.DependencyInjection;

builder.Services.AddTransient<MyTokenHandler>();

builder.Services.AddWexHealthSdk(sdk =>
{
    sdk.AddApi<IClaimsApi, ClaimsApi>(
        configureClient: client =>
        {
            // Required: BaseAddress must be set or AddApi will throw.
            client.BaseAddress = new Uri(builder.Configuration["WexHealth:BaseUrl"]!);
        },
        configureHttpClientBuilder: http =>
        {
            // Optional: attach auth, telemetry, or extra delegating handlers.
            http.AddHttpMessageHandler<MyTokenHandler>();
        });
});

Notes:

  • HttpClient.BaseAddress is required — InvalidOperationException if not set.
  • Authentication is the application's responsibility through delegating handlers (or Configuration.AccessToken for a static bearer token).
  • Resilience (timeouts, retries) can be overridden per registration through the IHttpClientBuilder callback.
  • Multiple AddApi<>() calls inside a single AddWexHealthSdk(...) register multiple typed clients; duplicate registrations of the same interface are no-ops.
  • Resolved API instances are safe for concurrent use within a DI scope.

Resilience (Retry & Timeout)

Every HTTP request goes through a Polly v8 resilience pipeline composed as Timeout → Retry → HTTP Request.

Defaults

Setting Value Notes
Max retry attempts 3 4 total attempts including the initial request.
Per-request timeout 30 s Set to 0 or negative to disable.
Backoff base delay 500 ms 500 ms × 2^attempt exponential growth.
Backoff cap 2 s Upper bound for exponential backoff.
Retry-After cap 30 s Upper bound when honoring server-supplied Retry-After.
Jitter Full Random 0–100 % of base delay to avoid synchronized retry storms.

Retries trigger on:

  • 5xx server errors;
  • network/IO failures and timeout exceptions;
  • HTTP 408 (Request Timeout);
  • HTTP 429 (Too Many Requests) — only when a Retry-After header is present.

Retries are not issued for other 4xx client errors.

Customization

using WexHealth.Client;

RetryConfiguration.HttpPipeline = RetryConfiguration.CreatePipeline(
    maxRetries:                   5,
    timeoutSeconds:               60,
    zeroDelay:                    false,
    maxExponentialBackoffSeconds: 2,
    maxRetryAfterSeconds:         30);

For full control, assign your own ResiliencePipeline<HttpResponseMessage>:

using Polly;
using Polly.Retry;
using WexHealth.Client;

RetryConfiguration.HttpPipeline = new ResiliencePipelineBuilder<HttpResponseMessage>()
    .AddTimeout(TimeSpan.FromSeconds(45))
    .AddRetry(new RetryStrategyOptions<HttpResponseMessage>
    {
        MaxRetryAttempts = 3,
        Delay            = TimeSpan.FromSeconds(2),
        ShouldHandle     = new PredicateBuilder<HttpResponseMessage>()
            .Handle<HttpRequestException>()
            .HandleResult(r => (int)r.StatusCode >= 500)
    })
    .Build();

Logging

The SDK integrates with Microsoft.Extensions.Logging. When a logger is wired into the ApiClient, the SDK emits structured log entries for retries, timeouts, and request outcomes; the resilience pipeline manages its own context internally, so consumers do not need to interact with Polly directly.

For direct (non-DI) usage, pass an ILogger<ApiClient> to ApiClient and reuse that instance across the typed API classes:

using Microsoft.Extensions.Logging;
using WexHealth.Api;
using WexHealth.Client;

using var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
var logger = loggerFactory.CreateLogger<ApiClient>();

var config    = new Configuration { BasePath = "https://api.example.com" };
var apiClient = new ApiClient(config.BasePath, logger);
var claims    = new ClaimsApi(apiClient, apiClient, config);

For ASP.NET Core, register your logger normally — IHttpClientFactory forwards request/response logging through the configured providers, and DI-resolved typed clients pick up the application's ILogger automatically.

For correlation IDs, log levels, and field redaction, configure Microsoft.Extensions.Logging filters and providers as you would for any other typed-client library — the SDK does not impose its own log format.


Error Handling

The SDK surfaces three categories of exceptions:

Exception Source When it is thrown
WexHealth.Client.ApiException API call Non-success HTTP status code returned by the server.
WexHealth.Auth.OAuth2TokenException OAuth2 token endpoint Token acquisition or refresh failed (network, HTTP, or parse error).
System.ArgumentException Constructor / config Required parameter missing, or non-HTTPS token URL.
using Microsoft.Extensions.Logging;
using WexHealth.Api;
using WexHealth.Auth;
using WexHealth.Client;

// Inputs and dependencies (see the Quick Start and Logging sections):
//   ILogger    logger      — resolved from your DI container or LoggerFactory
//   ClaimsApi  claims      — configured per Quick Start
//   Guid       personId    — domain identifier from your application
//   string     claimNumber — domain identifier from your application

try
{
    var claim = await claims.GetClaimAsync(personId, claimNumber);
}
catch (OAuth2TokenException ex)
{
    // Token endpoint failed — check credentials, audience, and connectivity.
    logger.LogError(ex, "OAuth2 token acquisition failed");
}
catch (ApiException ex) when (ex.ErrorCode == 404)
{
    // Resource not found — surface a domain-specific error to the caller.
}
catch (ApiException ex)
{
    // Other API errors — inspect ex.ErrorCode, ex.ErrorContent, ex.Headers.
    logger.LogError(ex, "Wex Health API call failed: {Status}", ex.ErrorCode);
}

Common OAuth2 errors:

Message Cause Resolution
OAuth2 token URL is required WEX_OAUTH2_TOKEN_URL not set Set the variable, or pass tokenUrl to the constructor.
OAuth2 token URL must use HTTPS protocol Token URL is HTTP Use the HTTPS endpoint.
Failed to obtain OAuth2 access token Bad credentials or transport failure Verify client ID/secret, audience, and network reachability.
Invalid OAuth2 token response Malformed JSON returned from endpoint Verify the token endpoint conforms to RFC 6749.

API Reference

The SDK exposes one typed client per tag in the OpenAPI specification. Method names match the operation IDs; XML documentation is shipped with the package, so IntelliSense will surface parameters and return types directly in your IDE.

All API paths are relative to Configuration.BasePath.

Endpoints

Class Method HTTP request Description
AccountingApi ArchiveBankAccount DELETE /v1/bank-accounts/{bank_account_id} Archive a bank account
AccountingApi GetCardById GET /v1/cards/{card_id} Retrieve Card Details by ID
AccountingApi GetCards GET /v1/cards Retrieve Cards by Consumer or Filters
AccountingApi ListBankAccounts GET /v1/bank-accounts List Bank Accounts
AccountingApi UpdateCardStatus PATCH /v1/cards/{card_id} Update Card Status
BusinessesApi BusinessesSearch GET /v2/businesses Search for businesses
BusinessesApi BusinessesUpdate PUT /v2/businesses/{id} Update a business
ClaimsApi DownloadFileFromCloudWithPersonId GET /v1/claims/receipts/download-file-from-cloud/{external_id} Download a file from cloud storage with PersonId.
ClaimsApi GetClaimByClaimNumber GET /v1/claims/{claim_number} Retrieves a claim by claim number
ClaimsApi GetClaims GET /v1/claims Get Claims
ClaimsApi GetExpenseCategoriesAndTypes GET /v1/claims/expense-categories-and-types Retrieves expense categories and types for a specific person.
ClaimsApi GetPayeesForParticipant GET /v1/claims/payees Get Payees by Person ID
ClaimsApi GetReceiptForParticipant GET /v1/claims/receipts/{receipt_id} Get Receipt
ClaimsApi GetReceiptsForParticipant GET /v1/claims/{claim_number}/receipts Get Receipts for a Claim
ClaimsApi UpdateDenial PATCH /v1/claims/{claim_number}/denials/{denial_id} Update a Denial
ClaimsApi UploadFileToCloudWithPersonId POST /v1/claims/receipts/upload-file-to-cloud Upload a file to cloud storage with PersonId.
ClaimsFinancialOperationsApi ArchiveBankAccount DELETE /v1/bank-accounts/{bank_account_id} Archive a bank account
ClaimsFinancialOperationsApi DownloadFileFromCloudWithPersonId GET /v1/claims/receipts/download-file-from-cloud/{external_id} Download a file from cloud storage with PersonId.
ClaimsFinancialOperationsApi GetCardById GET /v1/cards/{card_id} Retrieve Card Details by ID
ClaimsFinancialOperationsApi GetCards GET /v1/cards Retrieve Cards by Consumer or Filters
ClaimsFinancialOperationsApi GetClaimByClaimNumber GET /v1/claims/{claim_number} Retrieves a claim by claim number
ClaimsFinancialOperationsApi GetClaims GET /v1/claims Get Claims
ClaimsFinancialOperationsApi GetExpenseCategoriesAndTypes GET /v1/claims/expense-categories-and-types Retrieves expense categories and types for a specific person.
ClaimsFinancialOperationsApi GetPayeesForParticipant GET /v1/claims/payees Get Payees by Person ID
ClaimsFinancialOperationsApi GetReceiptForParticipant GET /v1/claims/receipts/{receipt_id} Get Receipt
ClaimsFinancialOperationsApi GetReceiptsForParticipant GET /v1/claims/{claim_number}/receipts Get Receipts for a Claim
ClaimsFinancialOperationsApi ListBankAccounts GET /v1/bank-accounts List Bank Accounts
ClaimsFinancialOperationsApi ListReimbursementMethods GET /v1/reimbursement-methods List all reimbursement methods
ClaimsFinancialOperationsApi ListSpendingAccounts GET /v1/spending-accounts List all spending accounts
ClaimsFinancialOperationsApi ListTransactions GET /v1/transactions/{consumer_id} List transactions by plan and consumer
ClaimsFinancialOperationsApi UpdateCardStatus PATCH /v1/cards/{card_id} Update Card Status
ClaimsFinancialOperationsApi UpdateDenial PATCH /v1/claims/{claim_number}/denials/{denial_id} Update a Denial
ClaimsFinancialOperationsApi UploadFileToCloudWithPersonId POST /v1/claims/receipts/upload-file-to-cloud Upload a file to cloud storage with PersonId.
CommunicationsContentApi GetMessage GET /v2/messages/{message_id} Retrieve message
CommunicationsContentApi GetMessages GET /v2/messages List messages
CommunicationsContentApi UpdateMessage PUT /v2/messages/{message_id} Update message
ElectionsApi GetElection GET /v1/elections/{election_id} Get a specific election
ElectionsApi ListElections GET /v1/elections List all elections
EnrollmentsApi GetEnrollment GET /v1/enrollments/{enrollment_id} Get a specific enrollment
EnrollmentsApi ListEnrollments GET /v1/enrollments List all enrollments
LifecycleActionsApi CreateTerminationRequest POST /v1/termination-requests Create or preview a termination request
MessagesApi GetMessage GET /v2/messages/{message_id} Retrieve message
MessagesApi GetMessages GET /v2/messages List messages
MessagesApi UpdateMessage PUT /v2/messages/{message_id} Update message
NotificationPreferenceApi GetExternalNotificationPreferences GET /v2/external-notification-preferences List external notification preferences
NotificationPreferenceApi GetNotificationPreferences GET /v2/notification-preferences List notification preferences
NotificationPreferenceApi UpdateExternalNotificationPreferences PUT /v2/external-notification-preferences Update external notification preferences
NotificationPreferenceApi UpdateNotificationPreferences PUT /v2/notification-preferences Update notification preferences
PersonApi GetAuthorizedSigners GET /v1/authorized-signers Get Authorized Signers
PersonApi GetConsumer GET /v1/consumers/{consumer_id} Get Consumer
PersonApi GetDependents GET /v1/dependents Get Dependents
PersonApi GetPerson GET /v1/persons/{person_id} Get Person
PlanYearsApi CreatePlanYear POST /v1/plan-years Create a new plan year
PlanYearsApi GetPlanYear GET /v1/plan-years/{plan_year_id} Get a specific plan year
PlanYearsApi ListPlanYears GET /v1/plan-years List all plan years
PlanYearsApi UpdatePlanYear PUT /v1/plan-years/{plan_year_id} Update a plan year (full replacement)
PlansApi CreatePlan POST /v1/plans Create a new plan
PlansApi GetPlan GET /v1/plans/{plan_id} Get a specific plan
PlansApi ListPlans GET /v1/plans List all plans
PlansApi UpdatePlan PUT /v1/plans/{plan_id} Update a plan (full replacement)
PlansEnrollmentElectionsApi CreatePlan POST /v1/plans Create a new plan
PlansEnrollmentElectionsApi CreatePlanYear POST /v1/plan-years Create a new plan year
PlansEnrollmentElectionsApi GetElection GET /v1/elections/{election_id} Get a specific election
PlansEnrollmentElectionsApi GetEnrollment GET /v1/enrollments/{enrollment_id} Get a specific enrollment
PlansEnrollmentElectionsApi GetPlan GET /v1/plans/{plan_id} Get a specific plan
PlansEnrollmentElectionsApi GetPlanYear GET /v1/plan-years/{plan_year_id} Get a specific plan year
PlansEnrollmentElectionsApi ListElections GET /v1/elections List all elections
PlansEnrollmentElectionsApi ListEnrollments GET /v1/enrollments List all enrollments
PlansEnrollmentElectionsApi ListPlanYears GET /v1/plan-years List all plan years
PlansEnrollmentElectionsApi ListPlans GET /v1/plans List all plans
PlansEnrollmentElectionsApi UpdatePlan PUT /v1/plans/{plan_id} Update a plan (full replacement)
PlansEnrollmentElectionsApi UpdatePlanYear PUT /v1/plan-years/{plan_year_id} Update a plan year (full replacement)
ReimbursementMethodsApi ListReimbursementMethods GET /v1/reimbursement-methods List all reimbursement methods
SpendingAccountsApi ListSpendingAccounts GET /v1/spending-accounts List all spending accounts
TerminationApi CreateTerminationRequest POST /v1/termination-requests Create or preview a termination request
TransactionsApi ListTransactions GET /v1/transactions/{consumer_id} List transactions by plan and consumer
UsersIdentityApi BusinessesSearch GET /v2/businesses Search for businesses
UsersIdentityApi BusinessesUpdate PUT /v2/businesses/{id} Update a business
UsersIdentityApi GetAuthorizedSigners GET /v1/authorized-signers Get Authorized Signers
UsersIdentityApi GetConsumer GET /v1/consumers/{consumer_id} Get Consumer
UsersIdentityApi GetDependents GET /v1/dependents Get Dependents
UsersIdentityApi GetExternalNotificationPreferences GET /v2/external-notification-preferences List external notification preferences
UsersIdentityApi GetNotificationPreferences GET /v2/notification-preferences List notification preferences
UsersIdentityApi GetPerson GET /v1/persons/{person_id} Get Person
UsersIdentityApi UpdateExternalNotificationPreferences PUT /v2/external-notification-preferences Update external notification preferences
UsersIdentityApi UpdateNotificationPreferences PUT /v2/notification-preferences Update notification preferences

For request and response schemas, refer to the official API reference at the Wex Developer Portal or to the type definitions exposed by the WexHealth.Models namespace.


Framework Compatibility

Target framework Supported
.NET 8.0 ✅ (LTS)
.NET 7.0 ✅
.NET 6.0 ✅ (LTS)
.NET Standard ❌
.NET Framework ❌

NuGet automatically selects the correct assembly based on your project's <TargetFramework>.


SDK Tracking Headers

The SDK adds a User-Agent header to every request to aid server-side diagnostics and rate-limit accounting. The format is:

WexHealth/Health-SDK/<sdk-version> (C#/<runtime-version>; <os-version>)

This header contains no personal data and cannot be disabled by configuration.


Versioning

WexHealth follows Semantic Versioning 2.0:

  • MAJOR — incompatible changes to the public API surface.
  • MINOR — new endpoints or optional fields, fully backward compatible.
  • PATCH — documentation or non-API changes.

Release notes for each version are available on the package page at https://www.nuget.org/packages/WexHealth.


Support

  • API documentation: Wex Developer Portal
  • Email:

Report security vulnerabilities by email to the address above. Please do not disclose security issues in public channels until they have been acknowledged and a remediation plan is in place.


License

Released under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0-beta.1 89 5/21/2026

Minor update