FaxCore.Ev6.RestClient 3.0.0

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

FaxCore EV6 REST Client

NuGet License: MIT

A .NET client for the FaxCore EV6 REST API. It handles OAuth sign-in, token refresh, HTTP calls and JSON, so you can send and manage faxes with plain C# calls.

Install

dotnet add package FaxCore.Ev6.RestClient
Framework Versions
.NET Framework 4.7, 4.7.1, 4.7.2, 4.8
.NET 8.0, 9.0, 10.0

.NET 6 and 7 are no longer supported in 3.0.0. .NET applications must target .NET 8 or later.

Microsoft lists .NET Framework 4.7, 4.7.1, 4.7.2 and 4.8 as Active as of October 8, 2026. Support follows the lifecycle of the Windows version on which the runtime is installed, so deployments must use a supported Windows version and current updates. See Microsoft's .NET Framework support policy.

Quick start

You need a FaxCore EV6 server and an OAuth client ID and secret set up on it.

using FaxCore.Ev6.RestClient;
using FaxCore.Ev6.RestClient.Models.Request;

using var client = new FaxClient("https://your-faxcore-server.com", "client-id", "client-secret");

// 1. Upload the document
var upload = await client.UploadFile("invoice.pdf");
var file = upload.Data.First();

// 2. Send it
var sent = await client.SendMessage(new SendMessageRequest<MessageRecipient>
{
    Message = new MessageRequest<MessageRecipient>
    {
        SenderName = "Accounts",
        Subject = "Invoice #1234",
        Priority = 70,
        Recipients = new List<MessageRecipient>
        {
            new MessageRecipient { Name = "Jane Smith", Address = "15551234567", IsRawFax = true }
        },
        Documents = new List<Document>
        {
            new Document { Name = file.Id, Path = file.FileName, IsMerge = false }
        },
        Agents = new List<Agent>(),
        Trackings = new List<Tracking> { new Tracking { Label = "Invoice", Value = "1234" } }
    }
});

// 3. Check on it
var status = await client.GetMessageStatus(sent.Data.MessageId);
Console.WriteLine(status.Data.Status);

Request types are in FaxCore.Ev6.RestClient.Models.Request, enums such as FileType, FilterOption and AddressType are in Models.Enumerators, and FaxCoreException is in Models. Both Models and Models.Request define Document, Agent and Tracking. When sending, use the Models.Request ones. If you import both namespaces, write those names in full.

Setting up the client

Create one FaxClient and reuse it. Each instance caches its OAuth token and refreshes it before it expires, and it is safe to use from many threads at once. If you create a new client per request, every request signs in again.

On .NET 8+ the client's own HttpClient closes pooled connections after 2 minutes, so a long-lived client still picks up DNS changes. On .NET Framework, the default ServicePointManager settings control connection reuse.

Dependency injection

services.AddSingleton<IFaxClient>(_ =>
    new FaxClient("https://your-faxcore-server.com", "client-id", "client-secret"));

To control the HTTP pipeline yourself (for example for retries, proxies or logging), pass in your own HttpClient. The singleton keeps that HttpClient for the life of the app, so IHttpClientFactory never gets to swap its handler. Let the connections expire on their own instead (UseSocketsHttpHandler needs Microsoft.Extensions.Http 8+):

services.AddHttpClient("FaxCore")
    .UseSocketsHttpHandler((handler, _) => handler.PooledConnectionLifetime = TimeSpan.FromMinutes(2))
    .SetHandlerLifetime(Timeout.InfiniteTimeSpan);

services.AddSingleton<IFaxClient>(provider =>
{
    var http = provider.GetRequiredService<IHttpClientFactory>().CreateClient("FaxCore");
    return new FaxClient("https://your-faxcore-server.com", "client-id", "client-secret", http);
});

FaxClient disposes an HttpClient it created itself. It never disposes one you passed in.

IFaxClientFactory / FaxClientFactory offer the same constructors behind an interface, for code that needs to create clients at runtime.

Timeouts and cancellation

The default timeout is 1 minute. You can change it when the client creates its own HttpClient:

var client = new FaxClient(url, clientId, clientSecret, httpClient: null, timeout: TimeSpan.FromMinutes(5));

If you pass your own HttpClient, set the timeout on it instead. The timeout argument is then ignored.

Every method takes an optional CancellationToken as its last argument.

Retries

The client retries only one thing: a single retry when getting a token fails with a network error or a 5xx response. It never retries API calls, because retrying SendMessage could send a fax twice. If you want retries, add them to the HttpClient you pass in, and only for calls that are safe to repeat.

Common tasks

Download a fax

byte[] pdf = await client.DownloadMessage(new DownloadMessageRequest
{
    MessageID = messageId,
    DownloadType = FileType.PDF
});
File.WriteAllBytes("fax.pdf", pdf);

List folders and messages

var folders = await client.GetMessageFolders();
foreach (var folder in folders.Data)
    Console.WriteLine(folder.Folder);

var inbox = await client.GetMessageList(new FolderListMessagesRequest
{
    FolderName = "Inbox",
    StartDate = DateTime.Today.AddDays(-7),
    EndDate = DateTime.Today.AddDays(1),
    Read = FilterOption.All,
    Downloaded = FilterOption.All,
    Pagination = new Pagination { Page = 1, MaxResults = 50 }
});

Search messages

var results = await client.SearchMessages(new MessageSearchRequest
{
    FromDate = DateTime.Today.AddDays(-30),
    ToDate = DateTime.Today.AddDays(1),
    IsFailed = FilterOption.Yes,
    Pagination = new Pagination { Page = 1, MaxResults = 25 }
});

foreach (var message in results.Data.Records)
    Console.WriteLine($"{message.MessageNo} {message.Subject} {message.Status}");

FromDate and ToDate are always sent, so set them. IncludeSubdomain defaults to false.

Create a contact

var book = await client.CreateAddressBook("Suppliers");

await client.CreateContact(new CreateContactRequest
{
    AddressBookId = book.Data.AddressBookId,
    DisplayName = "Acme Billing",
    PreferredAddressType = AddressType.Fax,
    Addresses = new List<ContactAddressRequest>
    {
        new ContactAddressRequest { AddressType = AddressType.Fax, Address = "15551234567" }
    }
});

Responses and errors

Most methods return FaxCoreResponse<T>, with Status, Message and Data. List methods return PagedResponse<T>. Its Data.Records holds the items and Data.Pagination holds the page info.

Failures throw FaxCoreException:

Property Contains
ErrorCode HTTP status code
HttpResponse Raw response body from the server
Message Short description ("Authentication failed" for bad credentials)
try
{
    await client.GetMessageDetails(messageId);
}
catch (FaxCoreException ex)
{
    Console.WriteLine($"{(int)ex.ErrorCode}: {ex.HttpResponse}");
}

A missing server URL, client ID or secret throws FaxCoreException from the constructor, with an ArgumentException inside.

API reference

Area Methods
Sending UploadFile, SendMessage, SendMessageInternal, DelegateMessage, GetCoverPageItems
Status & details GetMessageStatus, GetMessageDetails, GetMessageTracking, UpdateMessageTracking, GetMessageReadStatus, DeleteMessageStatus
Retrieving DownloadMessage, RetrieveImage, MarkMessageAsDownloaded, ToggleMessageRead
Folders & search GetMessageFolders, GetMessageList, SearchMessages, MoveMessageToFolder
Message actions UpdateMessageSubject, ForwardMessageToUsers, AssignMessage, ApproveMessage, RetryMessage, CancelMessage, DeleteMessage, DeleteTrashMessages
Users CreateUser, GetUserDetails, GetUserFaxSettings, UpdateUser, UpdateProfile, UpdateUserConfig, UserSearch, UserList, ActivateUsers, DeactivateUser, DeleteUser, ChangeUserDomain
Contacts CreateAddressBook, GetAddressBooks, UpdateAddressBook, DeleteAddressBook, CreateContact, GetContact, ListContacts, UpdateContact, DeleteContact
MFP GetMfpAddressBooks, GetMfpContacts
Printers GetPrinters, CreatePrinter, DeletePrinters
Domains GetDomains, CreateDomain
Inbound routes CreateRoutingRule, SearchRoutingRules, EnableRoutingRule, DisableRoutingRule, DeleteRoutingRule

Each method is documented with XML comments on IFaxClient, so your IDE shows the parameters and return types.

Upgrading from 2.x to 3.0

  • .NET 6 and 7 targets and support were removed. Upgrade .NET applications to .NET 8 or later. The existing .NET Framework targets remain available on supported Windows versions.
  • SearchMessages returns PagedResponse<MessageSearchItem>. Each item in Data.Records is a message; the MessageSearchResults wrapper is gone.
  • DelegationMessage.Trackings uses Models.Request.Tracking (Label, Value).
  • ContactAddressRequest.NotifyOnSend, NotifyOnReceive and IsPrimary were removed because the API has no such fields. Use NotifyOnSuccess and NotifyOnFailed on the contact.
  • UserSearchRequest has a Pagination property. Page size is now sent as maxResult, which the server expects.
  • HttpLoggingHandler was removed because it logged credentials and fax contents. Add your own logging to the HttpClient you pass in, and redact secrets.
  • Several request field names were fixed to match the API (message move, user move, route search, contact addresses, user creation, message search). Calls that the server used to ignore now take effect.

Contributing

You need the .NET 10 SDK. The tests run on .NET 8, 9 and 10, so install those runtimes too.

dotnet build src/FaxCoreRestClient.sln
dotnet test src/FaxCore.Tests/FaxCore.Tests.csproj

The default test run is offline. It checks request JSON, response parsing, authentication, cancellation and HttpClient ownership against a fake HTTP handler.

Live tests

Live tests send real faxes. Run them only with a dedicated test account and a fax number you control. They create their own messages and delete them afterwards.

export FAX_SERVER_URL="https://your-faxcore-server.com"
export FAX_SERVER_CLIENT="client-id"
export FAX_SERVER_SECRET="client-secret"
export FAX_TEST_RECIPIENT="15551234567"
export FAXCORE_RUN_INTEGRATION_TESTS="1"
dotnet test src/FaxCore.Tests/FaxCore.Tests.csproj

You can put these in a local_settings.sh in the repo root, which scripts/run_sandbox.sh also loads for the sandbox console app. Never commit that file.

Packing a release

dotnet build src/FaxCoreRestClient.sln -c Release
dotnet pack src/FaxCore.Ev6.RestClient/FaxCore.Ev6.RestClient.csproj -c Release --no-build -o artifacts

Layout

Path What it is
src/FaxCore.Ev6.RestClient The NuGet package. FaxClient is a partial class split by API area (MessageClient.cs, UserClient.cs, ...). HTTP and auth live in FaxCoreBaseClient.cs.
src/FaxCore.Tests Offline tests, plus live tests in FaxCoreClientTests/
src/FaxCore.Sandbox Console app for manual testing against a server
src/FaxCore.Functional.Core Small helpers used by the tests and sandbox
faxcore_api.json The FaxCore API specification used to check request field names

License

MIT

Product Compatible and additional computed target framework versions.
.NET 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 is compatible.  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 Framework net47 is compatible.  net471 is compatible.  net472 is compatible.  net48 is compatible.  net481 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
3.0.0 75 10/9/2026
2.0.1 251 3/25/2026
2.0.0 142 3/25/2026 2.0.0 is deprecated because it is no longer maintained.
1.0.3 289 1/31/2024 1.0.3 is deprecated because it is no longer maintained.
1.0.1 393 6/18/2023 1.0.1 is deprecated because it is no longer maintained.

v3.0.0 - Audit fixes and corrected API contracts.

BREAKING CHANGES:
- Removed .NET 6/7 targets and support; .NET applications must target .NET 8 or later
- SearchMessages now returns PagedResponse<MessageSearchItem>; removed the extra MessageSearchResults wrapper
- DelegationMessage.Trackings now uses Models.Request.Tracking (label/value)
- HttpLoggingHandler was removed because it exposed credentials and fax contents
- Removed ContactAddressRequest.NotifyOnSend, NotifyOnReceive and IsPrimary; use contact-level notification settings

FIXES:
- Atomically publish one token snapshot; expiry and bearer credentials cannot come from different refreshes
- Correct folder/user moves, route search, contact addresses, user creation, and message search request fields
- Send maxResult for pagination; add pagination to user searches
- Map user-search, contact-creation, and pagination response fields explicitly
- Preserve named search-filter encoding and the bool IncludeSubdomain API until numeric meanings are verified on a live server
- Remove duplicated factory validation; keep constructor validation
- Use framework-provided HTTP assemblies instead of the legacy System.Net.Http NuGet package
- On .NET 8+, the client-owned HttpClient recycles pooled connections every 2 minutes so long-lived clients follow DNS changes

VALIDATION AND COMPATIBILITY:
- Offline request, parsing, authentication, cancellation, and HttpClient ownership regression tests
- Live tests require explicit opt-in, a dedicated account, and a configured recipient; only test-created messages are modified
- Verified latest stable direct dependencies, including System.Text.Json 10.0.12, Microsoft.NET.Test.Sdk 18.10.1 and xunit.runner.visualstudio 4.0.0
- Added net9.0 and net10.0 targets; offline tests run on .NET 8, 9 and 10
- Retained .NET Framework 4.7, 4.7.1, 4.7.2 and 4.8 targets; Microsoft lists these versions as Active, subject to the host Windows lifecycle
- Response fixtures are synthetic; live FaxCore response compatibility still requires integration verification
- Numeric search-filter mappings and server acceptance of named filters remain unverified; no live credentials were configured during validation