Smp.Core.Encompass 2.0.3

dotnet add package Smp.Core.Encompass --version 2.0.3
                    
NuGet\Install-Package Smp.Core.Encompass -Version 2.0.3
                    
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="Smp.Core.Encompass" Version="2.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Smp.Core.Encompass" Version="2.0.3" />
                    
Directory.Packages.props
<PackageReference Include="Smp.Core.Encompass" />
                    
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 Smp.Core.Encompass --version 2.0.3
                    
#r "nuget: Smp.Core.Encompass, 2.0.3"
                    
#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 Smp.Core.Encompass@2.0.3
                    
#: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=Smp.Core.Encompass&version=2.0.3
                    
Install as a Cake Addin
#tool nuget:?package=Smp.Core.Encompass&version=2.0.3
                    
Install as a Cake Tool

Smp.Core.Encompass

A .NET client library for the Encompass API by ICE Mortgage Technology. Provides strongly-typed access to loan data, pipeline queries, document management, user administration, and more with built-in OAuth2 authentication, token caching, rate limiting, and automatic retry on 401 responses.

Installation

Install via NuGet:

dotnet add package Smp.Core.Encompass

Quick Start

1. Configure

Add an Encompass section to your appsettings.json:

{
  "Encompass": {
    "Username": "api_user",
    "Password": "your_password",
    "InstanceId": "BE11200822",
    "ClientId": "your_client_id",
    "ClientSecret": "your_client_secret",
    "TokenLifetime": "00:50:00",
    "RateLimit": {
      "TokenLimit": 20,
      "ReplenishmentPeriod": "00:00:01",
      "TokensPerPeriod": 20,
      "QueueLimit": 100
    }
  }
}

2. Register Services

Choose one of the registration patterns below based on your configuration needs.

Default Configuration (Configuration Section)

Use this pattern when all settings are in your configuration file:

builder.Services.AddEncompassClient();
Custom Configuration Section

Use this pattern if your Encompass configuration is under a different section path:

// For configuration at "Services:Encompass"
builder.Services.AddEncompassClient("Services:Encompass");
Inline/Programmatic Configuration

Use this pattern for fully programmatic configuration, useful in testing:

builder.Services.AddEncompassClient(options =>
{
    options.Username = Environment.GetEnvironmentVariable("ENCOMPASS_USERNAME")!;
    options.Password = Environment.GetEnvironmentVariable("ENCOMPASS_PASSWORD")!;
    options.InstanceId = "BE11200822";
    options.ClientId = Environment.GetEnvironmentVariable("ENCOMPASS_CLIENT_ID")!;
    options.ClientSecret = Environment.GetEnvironmentVariable("ENCOMPASS_CLIENT_SECRET")!;
});
Hybrid Configuration (Configuration + Override)

Use this pattern when you want to bind most settings from configuration but override sensitive values from secure sources like Azure Key Vault:

// appsettings.json has: Username, InstanceId, ClientId
builder.Services.AddEncompassClient("Encompass", async options =>
{
    // Override sensitive values from Key Vault
    var keyVaultUri = new Uri(builder.Configuration["KeyVault:Uri"]!);
    var credential = new DefaultAzureCredential();
    var client = new SecretClient(keyVaultUri, credential);
    
    options.Password = (await client.GetSecretAsync("EncompassPassword")).Value.Value;
    options.ClientSecret = (await client.GetSecretAsync("EncompassClientSecret")).Value.Value;
});
Custom HttpClient Configuration

Use this pattern to customize the underlying HttpClient (timeouts, headers, etc.):

builder.Services.AddEncompassClient(httpClient =>
{
    httpClient.Timeout = TimeSpan.FromSeconds(60);
    httpClient.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0");
});

3. Use the Client

Inject IEncompassClient into your services:

public class LoanService(IEncompassClient encompassClient)
{
    public async Task<string> GetLoanAsync(string loanGuid)
    {
        return await encompassClient.Loans.GetLoanRawAsync(loanGuid);
    }
}

API Reference

The EncompassClient exposes the following sub-clients:

Loans

Read and write loan data, field values, and disclosure tracking logs.

// Get raw loan JSON
string loanJson = await client.Loans.GetLoanRawAsync(loanGuid);

// Read specific fields
var fields = await client.Loans.FieldReaderAsync(loanGuid, ["4000", "1109"]);

// Write field values
await client.Loans.FieldWriterAsync(loanGuid, [
    new FieldValue { Id = "CX.CUSTOM.FIELD", Value = "NewValue" }
]);

// Get disclosure tracking logs
var logs = await client.Loans.GetDisclosureTrackingLogsAsync(loanGuid);

// Get loan associates
string associates = await client.Loans.GetLoanAssociatesRawAsync(loanGuid);

Loan Pipeline

Query and search the loan pipeline with filters, field selection, and pagination.

// Find a loan GUID by loan number
string guid = await client.LoanPipeline.FindLoanGuidByLoanNumberAsync("1234567890");

// Query the pipeline with filters
var items = await client.LoanPipeline.GetAllPipelineItemsAsync(new LoanPipelineQuery
{
    Fields = ["Loan.LoanNumber", "Loan.BorrowerName"],
    Filter = new Filter
    {
        Operator = "and",
        Terms =
        [
            new Filter { CanonicalName = "Loan.LoanFolder", Value = "My Pipeline", MatchType = "Exact" },
            new Filter { CanonicalName = "Loan.DateCreated", Value = "2024-01-01", MatchType = "GreaterThan" }
        ]
    }
});

// Paginated access
var page = await client.LoanPipeline.GetPipelinePageAsync(new LoanPipelineRequest
{
    LoanPipelineQuery = query,
    Start = 0
});

Documents

Retrieve loan document stacking order using Encompass stacking templates.

var stackingDocs = await client.Documents.GetLoanStackingDocumentsAsync(
    new LoanStackingDocumentsRequest
    {
        Loan = new Entity { EntityId = loanGuid, EntityType = "urn:elli:encompass:loan" },
        StackingTemplate = new Entity { EntityId = templateId }
    });

// Get all attachment IDs from the stacking order
var attachmentIds = stackingDocs.GetAttachmentIds();

Export Jobs

Create, monitor, and download eFolder export jobs.

// Create an export job
var job = await client.ExportJobs.CreateExportJobAsync(new ExportJobRequest
{
    Source = new Entity { EntityId = loanGuid, EntityType = "urn:elli:encompass:loan" },
    Entities = attachmentIds.Select(id => new Entity { EntityId = id }).ToList()
});

// Check status
var status = await client.ExportJobs.GetExportJobStatusAsync(job.JobId!);

// Download the file
using var stream = await client.ExportJobs.DownloadExportJobAsync(job.JobId!);

Users

Query and retrieve Encompass user accounts.

// Get all users
var allUsers = await client.Users.GetAllUsersAsync();

// Get a single user
var user = await client.Users.GetUserAsync("userId");

// Get multiple users by ID
var users = await client.Users.GetUsersByIdsAsync(["user1", "user2"]);

// Paginated access
var page = await client.Users.GetUsersPageAsync(start: 0, limit: 50);

Custom Data Objects

Manage custom data objects (CDOs) at the company, user, or loan level.

// List CDO names
var names = await client.CustomDataObjects.GetCustomDataObjectListAsync(CustomDataObjectTypes.Company);

// Get a CDO
var cdo = await client.CustomDataObjects.GetCustomDataObjectAsync(
    CustomDataObjectTypes.Loans, "MyCdo", entityId: loanGuid);

// Upsert a CDO from an object (auto-serialized to JSON and Base64-encoded)
await client.CustomDataObjects.UpsertCustomDataObjectAsync(
    CustomDataObjectTypes.Loans, "MyCdo", myObject, entityId: loanGuid);

// Delete a CDO
await client.CustomDataObjects.DeleteCustomDataObjectAsync(
    CustomDataObjectTypes.Company, "OldCdo");

Loan Batch Update

Apply field updates to multiple loans in a single batch operation.

// Batch update by loan GUIDs
var jobId = await client.LoanBatchUpdate.CreateBatchUpdateJobAsync(
    new LoanBatchUpdateRequest(
        loanGuids: ["guid1", "guid2"],
        jsonLoanData: """{"applications":[{"borrower":{"fullName":"Test"}}]}"""));

// Check batch update status
var status = await client.LoanBatchUpdate.GetBatchUpdateJobStatusAsync(jobId);

Settings

Retrieve Encompass system settings.

// Get all document stacking templates
var templates = await client.Settings.GetAllDocumentStackingTemplatesAsync();

// Get all eFolder document definitions
var docs = await client.Settings.GetAllEFolderDocumentsAsync();

Resource Locks

Manage exclusive locks on loans for safe concurrent access.

// Lock a loan
var resourceLock = await client.ResourceLocks.LockLoanAsync(loanGuid);

// Unlock by lock ID
await client.ResourceLocks.UnlockLoanAsync(resourceLock.Id!, loanGuid);

// Or unlock all locks on a loan
await client.ResourceLocks.UnlockLoanAsync(loanGuid);

// Check active locks
var locks = await client.ResourceLocks.GetResourceLocksAsync(loanGuid);

Configuration Options

EncompassClientOptions

Property Required Default Description
Username Yes - Encompass user account username
Password Yes - Encompass user account password
InstanceId Yes - Encompass instance identifier
ClientId Yes - OAuth2 client ID
ClientSecret Yes - OAuth2 client secret
TokenLifetime No 00:50:00 Token refresh interval (Encompass tokens expire at 60 min)
RateLimit No Enabled Rate limit configuration, set to null to disable

RateLimitOptions

Uses a token bucket algorithm for client-side rate limiting.

Property Default Description
TokenLimit 20 Maximum burst capacity
ReplenishmentPeriod 00:00:01 How often permits are added
TokensPerPeriod 20 Permits added per period
QueueLimit 100 Maximum queued requests

Key Features

  • OAuth2 Authentication - Automatic token acquisition, caching, and refresh with thread-safe semaphore protection
  • Automatic 401 Retry - Transparently refreshes expired tokens and retries failed requests
  • Rate Limiting - Built-in token bucket rate limiter to stay within API call limits
  • Pagination - Automatic iteration through all pages with GetAll*Async methods, or manual control with Get*PageAsync methods
  • Dependency Injection - Single-line registration via AddEncompassClient() with options validation on startup

Requirements

  • .NET 10.0+

Testing & Mocking

The library interfaces support dependency injection, making it easy to mock in unit tests:

Testing with Moq

using Moq;
using Xunit;

[Fact]
public async Task GetLoanAsync_WithMockedClient_ReturnsExpectedJson()
{
    // Arrange
    var mockEncompassClient = new Mock<IEncompassClient>();
    var mockLoans = new Mock<ILoans>();
    
    var expectedJson = """{"loanNumber":"123456","borrowerName":"John Doe"}""";
    mockLoans.Setup(l => l.GetLoanRawAsync("test-guid", null, default))
        .ReturnsAsync(expectedJson);
    
    mockEncompassClient.Setup(c => c.Loans).Returns(mockLoans.Object);
    
    var loanService = new LoanService(mockEncompassClient.Object);
    
    // Act
    var result = await loanService.GetLoanAsync("test-guid");
    
    // Assert
    Assert.Equal(expectedJson, result);
    mockLoans.Verify(l => l.GetLoanRawAsync("test-guid", null, default), Times.Once);
}

Testing with NSubstitute

using NSubstitute;
using Xunit;

[Fact]
public async Task GetUserAsync_WithMockedClient_ReturnsExpectedUser()
{
    // Arrange
    var mockEncompassClient = Substitute.For<IEncompassClient>();
    var mockUsers = Substitute.For<IUsers>();
    
    var expectedUser = new User { Id = "user123", Name = "Jane Smith" };
    mockUsers.GetUserAsync("user123", default).Returns(Task.FromResult(expectedUser));
    
    mockEncompassClient.Users.Returns(mockUsers);
    
    var userService = new UserService(mockEncompassClient);
    
    // Act
    var result = await userService.GetUserAsync("user123");
    
    // Assert
    Assert.Equal(expectedUser.Id, result.Id);
    await mockUsers.Received(1).GetUserAsync("user123", default);
}

Injecting Mocks in Dependency Injection

using Microsoft.Extensions.DependencyInjection;
using Moq;

[Fact]
public async Task Service_WithMockedDependencies()
{
    // Arrange
    var services = new ServiceCollection();
    
    var mockEncompassClient = new Mock<IEncompassClient>();
    mockEncompassClient.Setup(c => c.LoanPipeline.FindLoanGuidByLoanNumberAsync("1234567890", default))
        .ReturnsAsync("loan-guid-123");
    
    services.AddScoped(_ => mockEncompassClient.Object);
    services.AddScoped<ILoanService, LoanService>();
    
    var provider = services.BuildServiceProvider();
    var loanService = provider.GetRequiredService<ILoanService>();
    
    // Act
    var result = await loanService.FindLoanAsync("1234567890");
    
    // Assert
    Assert.NotNull(result);
}

Interface Contracts

All sub-clients are accessible through their respective interfaces:

  • IAuthenticationClient - Token management
  • ILoans - Loan data and field operations
  • ILoanPipeline - Pipeline querying and search
  • IDocuments - Document stacking
  • IExportJobs - eFolder exports
  • IUsers - User queries
  • ICustomDataObjects - CDO management
  • ILoanBatchUpdate - Batch operations
  • ISettings - System settings retrieval
  • IResourceLocks - Loan locking mechanisms
Product Compatible and additional computed target framework versions.
.NET 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. 
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
2.0.3 94 4/10/2026
2.0.2 97 4/10/2026
2.0.1 88 4/9/2026
2.0.0 95 4/9/2026