SuccessMortgagePartners.Encompass.Client 0.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package SuccessMortgagePartners.Encompass.Client --version 0.1.0
                    
NuGet\Install-Package SuccessMortgagePartners.Encompass.Client -Version 0.1.0
                    
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="SuccessMortgagePartners.Encompass.Client" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SuccessMortgagePartners.Encompass.Client" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="SuccessMortgagePartners.Encompass.Client" />
                    
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 SuccessMortgagePartners.Encompass.Client --version 0.1.0
                    
#r "nuget: SuccessMortgagePartners.Encompass.Client, 0.1.0"
                    
#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 SuccessMortgagePartners.Encompass.Client@0.1.0
                    
#: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=SuccessMortgagePartners.Encompass.Client&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=SuccessMortgagePartners.Encompass.Client&version=0.1.0
                    
Install as a Cake Tool

SuccessMortgagePartners.Encompass.Client

A .NET client for the ICE Mortgage Technology Encompass Developer Connect API.

  • OAuth endpoints: password grant, token exchange (act as another user), introspection, revocation
  • Cached API token that follows Encompass's lifetime rules (kept alive by use at least every 15 min, 24 h max)
  • IHttpClientFactory integration and options binding (AddEncompassClient)
  • API areas are added one at a time as each is verified against the live API (auth only today)
  • Targets net10.0 and netstandard2.0

Status: early. The surface area grows as we wrap more endpoints; see Extending.

Install

dotnet add package SuccessMortgagePartners.Encompass.Client

Configure

appsettings.json (or environment variables Encompass__ClientId, etc.):

{
  "Encompass": {
    "ClientId": "...",
    "ClientSecret": "...",
    "InstanceId": "BE11111111",
    "Username": "apiuser",
    "Password": "..."
  }
}

BaseAddress defaults to https://api.elliemae.com/; if you point it at a path (for example a proxy), end it with / (and note that a request path starting with / resolves to the host root, bypassing the prefix). Never commit real credentials; use user-secrets, Key Vault, or app settings.

Optional throttling settings: MaxConcurrentRequests (default: follow 80% of the limit Encompass reports, starting at 24) and ConcurrencyLimitRetries (default 3) control how the client stays under Encompass's concurrency limit; see "Concurrency" below.

Use

using SuccessMortgagePartners.Encompass.Client;
using SuccessMortgagePartners.Encompass.Client.DependencyInjection;

builder.Services.AddEncompassClient(builder.Configuration); // binds the "Encompass" section

// later, via DI
public sealed class WhoAmI(IEncompassClient encompass)
{
    public async Task<string?> CurrentUserAsync(CancellationToken ct)
    {
        var token = await encompass.Auth.RequestPasswordTokenAsync(ct);
        try
        {
            var info = await encompass.Auth.IntrospectAsync(token.AccessToken, ct);
            return info.UserName;
        }
        finally
        {
            // Not `ct`: a cancelled caller must still revoke the token it created.
            await encompass.Auth.RevokeAsync(token.AccessToken, CancellationToken.None);
        }
    }
}

This example requests a token explicitly because it exercises the OAuth endpoints themselves. API resource groups (added one area at a time) don't do this: they send requests through the registered IAccessTokenProvider, which caches one password-grant token and keeps it alive while it is in use.

encompass.Auth.ExchangeTokenAsync(actorToken, subjectUserId) returns a token that acts as another Encompass user, with that user's permissions.

IEncompassClient and the resource interfaces are meant to be consumed, not implemented, by applications: a new API area adds a member, which is a minor version bump. Mock the resource interfaces your code uses; a hand-written fake that implements IEncompassClient must expect new members on each update.

Failures throw EncompassApiException with StatusCode, ErrorCode (Encompass errorCode or OAuth error), CorrelationId (the X-Correlation-ID header, which ICE support asks for), and the raw ResponseBody.

Concurrency

Encompass allows a fixed number of concurrent API requests per environment (30 by default) and answers 429 Too Many Requests beyond it; the counter resets every second. Every API response reports the allowance in X-Concurrency-Limit-Limit and X-Concurrency-Limit-Remaining (OAuth responses don't). The client:

  • holds API requests in a gate so no more than MaxConcurrentRequests are in flight. By default the cap follows 80% of the reported limit, the share ICE recommends lenders stay within, starting at 24 until the first response;
  • retries a 429 after 1 s, 2 s, 4 s (or Retry-After), up to ConcurrencyLimitRetries times, then returns it to the caller;
  • retries once with a fresh token after a 401 (every token that gets a 401 is dropped from the cache, so a second 401 is returned to you without leaving a known-bad token behind);
  • exposes the last reported allowance as IEncompassClient.LastConcurrencyLimit.

Each 429 back-off is capped at 30 s (also when Retry-After asks for more) and adds up to 500 ms of random jitter. Redirects are never followed, so the bearer and Basic headers only ever go to BaseAddress. The cap is per process: if you run several instances against one Encompass environment (for example a scaled-out Azure Functions app), set MaxConcurrentRequests to roughly 80% of the limit divided by the instance count.

Extending

Add a resource group per API area (Loans, Documents, Pipeline, …), verified against the API reference and the integration tests:

  1. Interface in src/.../<Area>/I<Area>Resource.cs, implementation beside it (internal sealed).
  2. Expose it on IEncompassClient and construct it in EncompassClient.
  3. Send requests through EncompassClient.SendAsync (internal) and EnsureEncompassSuccessAsync, so the bearer token and error handling stay in one place.
  4. Unit tests in tests/…Client.Tests using FakeHttpMessageHandler (assert the exact URL, method, and body), and real calls in tests/…Client.IntegrationTests (see its README).

Return JsonElement until a payload is stable enough to deserve a model; typed models go in <Area>/Models/.

Build and test

dotnet build
dotnet test

CI and release

CI runs on Azure Pipelines from azure-pipelines.yml; the code stays on GitHub.

  • develop is the default branch. Pull requests target develop.
  • Every push and pull request to develop or main builds, tests and packs.
  • Every merge (push) to main also pushes the package to NuGet.org and creates the vX.Y.Z tag and GitHub release. The version is <Version> in src/SuccessMortgagePartners.Encompass.Client/SuccessMortgagePartners.Encompass.Client.csproj; a version with a suffix (1.2.0-preview.1) is published as a prerelease.
  • To release: bump <Version> on develop, then merge develop into main. If that version is already on NuGet.org from another commit, the run warns and publishes nothing (the pull request into main shows the same warning); if NuGet.org is still indexing it, the push fails instead, which is also safe. If a release run fails after the NuGet push, wait until the version shows on nuget.org, then use Rerun failed jobs on that run: it sees the package came from that commit and creates or updates the GitHub release. (A new run only does this while main still points at that commit; otherwise create the GitHub release by hand.) Don't push release tags by hand.

One-time setup in Azure DevOps:

  1. In the Development project, Pipelines → New pipeline → GitHub (YAML), pick this repo and the existing azure-pipelines.yml. Use the existing github.com_SuccessMortgagePartners connection.
  2. Library → Variable group encompass-client-release with secret variable NuGetApiKey (a NuGet.org key with Push new packages and package versions for the glob SuccessMortgagePartners.*; 0.1.0 creates the package). Allow the pipeline to use it, and add a Branch control check that allows only refs/heads/main, so no other branch can read the key.
  3. Service connection (GitHub) named github-releases-encompass-client, for creating the tag and GitHub release. GitHubRelease@1 only accepts OAuth ("Grant authorization") or personal access token connections, so the existing GitHub App connection github.com_SuccessMortgagePartners can't be used. With a token, use a fine-grained one limited to this repo with Contents: read and write. Either way, add a Branch control check allowing only refs/heads/main. Tokens expire and OAuth grants follow their user's access: when it stops working, the release step fails after the NuGet push; renew the token, update the connection, then use Rerun failed jobs.
  4. Environment encompass-client-nuget, with a Branch control check for refs/heads/main (the Release stage's lockBehavior: sequential already makes two quick merges publish one at a time). Add an approval check too if you want a person to confirm each publish.
  5. Set releaseEnabled: 'true' in azure-pipelines.yml. Until then, runs on main build and pack but don't publish.

License

MIT — see LICENSE.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  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 was computed.  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 was computed.  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 is compatible.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos 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
0.7.0 53 11/9/2026
0.6.0 134 11/4/2026
0.5.0 94 11/4/2026
0.4.0 136 11/3/2026
0.3.0 113 11/2/2026
0.2.0 87 11/2/2026
0.1.0 105 11/1/2026