FreeAgent.Client 0.1.0-alpha.4

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

FreeAgent.Client

A .NET client library for the FreeAgent API with OAuth 2.0 support, rate limiting, retries, typed transport errors, and pagination.

Prerelease software. This package is in alpha. Public APIs may change between releases. As of September 2026 this library is in active development and I am aiming to have full FreeAgent API coverage over coming weeks and months. See versioning policy.

Features

  • OAuth 2.0 protocol helpers with automatic token refresh.
  • Rate limiting and bounded retries for transient failures.
  • Typed exception model (FreeAgentApiException, FreeAgentRateLimitException, …).
  • Pagination (single-page and auto-pagination).
  • Company, Contacts, Categories, Users, Projects, Invoices, Estimates, Recurring invoices, Credit notes, Credit note reconciliations, Stock items, Price list items, Tasks, Timeslips, Notes, and Email addresses API support.
  • CurrencyCode enum for documented ISO 4217 codes (reference type; not a REST resource).
  • Targets .NET 8.0 and .NET 10.0.
  • Fully async/await with XML documentation.

Installation

dotnet add package FreeAgent.Client

Quick start

using FreeAgent.Client;
using FreeAgent.Client.Models.Invoices;
using FreeAgent.Client.Models.Projects;
using FreeAgent.Client.Models.Tasks;

// Sandbox or Production - use the same value for OAuth and API calls.
var environment = FreeAgentEnvironment.Sandbox;
var oauthClient = new FreeAgentOAuthClient(clientId, clientSecret, redirectUri, environment);
var authUrl = oauthClient.GetAuthorizationUrl(state: "optional-state");

// Redirect the user to authUrl, then exchange the callback code:
var token = await oauthClient.ExchangeCodeForTokenAsync(code);

using var client = new FreeAgentClient(oauthClient, token, environment);
var company = await client.Company.GetCompanyAsync();
Console.WriteLine($"{company.Name} ({company.Currency})");

The SDK provides protocol-level OAuth utilities only, your application owns callback endpoints and browser flows.

Linked resources

FreeAgent links resources with URI strings. The SDK types those links so you do not parse URLs or hard-code API hosts:

// Create a project for a known contact ID (no manual URI construction)
await client.Projects.CreateProjectAsync(new Project
{
    Name = "Website redesign",
    BillingContact = client.Urls.Contact(42),
    Status = ProjectStatus.Active
});

// Read full billing contact fields when you need them
var project = await client.Projects.GetProjectAsync(
    123,
    new ProjectGetOptions { IncludeBillingContact = true });
var organisation = project.Contact!.OrganisationName;

// Display name only - one HTTP call
var summary = await client.Projects.GetProjectAsync(123);
var label = summary.ContactName;

// Create a task under a project (parent scoped via query param)
await client.Tasks.CreateTaskAsync(123, new Task
{
    Name = "Planning",
    IsBillable = true,
    Status = TaskStatus.Active
});

// Log time against a task
using FreeAgent.Client.Models.Timeslips;

await client.Timeslips.CreateTimeslipAsync(new Timeslip
{
    LinkedTask = client.Urls.Task(456),
    LinkedProject = client.Urls.Project(123),
    LinkedUser = client.Urls.User(1),
    DatedOn = DateOnly.FromDateTime(DateTime.UtcNow),
    Hours = 1.5m
});

// Create a draft invoice for a contact
await client.Invoices.CreateInvoiceAsync(new Invoice
{
    BillingContact = client.Urls.Contact(42),
    DatedOn = DateOnly.FromDateTime(DateTime.UtcNow),
    PaymentTermsInDays = 14,
    InvoiceItems =
    [
        new InvoiceItem
        {
            Description = "Consulting",
            ItemType = InvoiceItemType.Hours,
            Quantity = 2,
            Price = 100,
            Category = client.Urls.Category("001")
        }
    ]
});

// List recurring invoice profiles (read-only API)
using FreeAgent.Client.Models.RecurringInvoices;

var recurringPage = await client.RecurringInvoices.ListAsync(
    view: RecurringInvoiceViews.Active,
    contactId: 42);

// List credit notes with nested line items
using FreeAgent.Client.Models.CreditNotes;

var creditNotesPage = await client.CreditNotes.ListAsync(
    view: CreditNoteViews.Open,
    contactId: 42,
    nestedCreditNoteItems: true);

// Reconcile a credit note against an invoice
using FreeAgent.Client.Models.CreditNoteReconciliations;

var reconciliation = await client.CreditNoteReconciliations.CreateCreditNoteReconciliationAsync(
    CreateCreditNoteReconciliationRequest.Create(
        grossValue: 100m,
        invoice: client.Urls.Invoice(1),
        creditNote: client.Urls.CreditNote(2)));

// Add a note to a contact
using FreeAgent.Client.Models.Notes;

await client.Notes.CreateContactNoteAsync(
    42,
    CreateContactNoteRequest.Create("Follow up next week"));

See linked resources for the full pattern.

Documentation

Published documentation: markheydon.me.uk/freeagent-dotnet

Licence

MIT - see LICENSE.

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.

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.1.0-alpha.4 88 9/25/2026
0.1.0-alpha.3 111 9/21/2026
0.1.0-alpha.2 115 9/4/2026
0.1.0-alpha.1 91 9/3/2026