A comprehensive .NET client library for the FreeAgent accounting API, providing strongly-typed access to all FreeAgent resources with modern C# features.
Parts of this library have been generated by AI and may contain errors. Please raise an issue / submit a PR.
Endjin.FreeAgent is a fully-featured .NET client library designed to simplify integration with the FreeAgent accounting platform. Built with .NET 10 and C# 14 preview features, it provides a type-safe, performant, and developer-friendly way to interact with FreeAgent's REST API.
The solution consists of two core packages:
- Endjin.FreeAgent.Client - The main client library providing API operations and HTTP communication
- Endjin.FreeAgent.Domain - Domain models and types representing all FreeAgent resources
- ✅ Invoicing - Create, manage, and track sales invoices and recurring invoices
- ✅ Contacts - Manage customers, suppliers, and other contacts
- ✅ Projects - Track projects and their associated tasks
- ✅ Expenses - Handle expense claims, receipts, and mileage tracking
- ✅ Banking - Bank accounts, transactions, explanations, and statement uploads
- ✅ Time Tracking - Timeslips and task management
- ✅ Bills - Purchase bills and supplier invoices
- ✅ Credit Notes - Refunds, corrections, and reconciliations
- ✅ Estimates - Quotes and proposals
- ✅ Reports - Trial Balance, Balance Sheet, P&L, Cash Flow, Final Accounts
- ✅ Tax Returns - VAT, Corporation Tax, Self Assessment, CIS
- ✅ Payroll - RTI payroll data and payroll profiles (UK)
- ✅ Assets - Capital assets, depreciation profiles, and stock items
- ✅ Webhooks - API event notifications
- ✅ Company Settings - Company configuration and users
- 🚀 Modern .NET 10 - Built on the latest .NET runtime
- 📝 Strongly-Typed - Full type safety with C# 14 records
- ⚡ High Performance - System.Text.Json with source generation
- 🔄 Async/Await - Fully asynchronous operations
- 💾 Built-in Caching - Memory caching with 5-minute sliding expiration (24 hours for reference data)
- 🔐 OAuth2 Support - Complete authentication flow implementation with automatic token refresh
- 📊 Comprehensive Logging - Integration with Microsoft.Extensions.Logging
- ♻️ Retry Logic - Resilient HTTP operations with Corvus.Retry exponential backoff
- 🧪 Well-Tested - Extensive test coverage with MSTest
- .NET 10.0 or later
- A FreeAgent account with API access
- OAuth2 credentials (Client ID and Secret)
Install the client library via NuGet:
dotnet add package Endjin.FreeAgent.ClientThe domain package is automatically included as a dependency.
using Endjin.FreeAgent.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
// Configure services
ServiceCollection services = new();
services.AddMemoryCache();
services.AddHttpClient();
services.AddLogging(builder => builder.AddConsole());
ServiceProvider serviceProvider = services.BuildServiceProvider();
// Configure client options
FreeAgentOptions options = new()
{
ClientId = "your-client-id",
ClientSecret = "your-client-secret",
RefreshToken = "your-refresh-token",
UseSandbox = false // Set to true for sandbox environment
};
// Create client
IMemoryCache cache = serviceProvider.GetRequiredService<IMemoryCache>();
IHttpClientFactory httpClientFactory = serviceProvider.GetRequiredService<IHttpClientFactory>();
ILoggerFactory loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
FreeAgentClient client = new(options, cache, httpClientFactory, loggerFactory);
// Use the client
IEnumerable<Invoice> invoices = await client.Invoices.GetAllAsync();
IEnumerable<Contact> contacts = await client.Contacts.GetAllActiveAsync();If you need to obtain a refresh token or support interactive user login:
// Create client with interactive authentication
FreeAgentClient client = FreeAgentClient.CreateInteractive(
clientId: "your-client-id",
clientSecret: "your-client-secret",
useSandbox: false,
cache: cache,
httpClientFactory: httpClientFactory,
loggerFactory: loggerFactory);
// This will trigger the OAuth2 flow (opening browser, etc.) on first API call
IEnumerable<Invoice> invoices = await client.Invoices.GetAllAsync();The library provides extension methods for easy registration with IServiceCollection:
// In Program.cs or Startup.cs
builder.Services.AddFreeAgentClientServices(builder.Configuration);Ensure your configuration (e.g., appsettings.json) contains the FreeAgent section:
{
"FreeAgent": {
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret",
"RefreshToken": "your-refresh-token",
"UseSandbox": false
}
}The solution includes a CLI demo application (DemoApp) that showcases the library's capabilities. It uses Spectre.Console for a rich terminal experience.
You can run the demo app from the command line. It supports both standard (configured) mode and interactive login mode.
If you have your credentials configured in appsettings.json or User Secrets:
dotnet run --project Solutions/DemoApp/DemoApp.csprojTo log in interactively via OAuth2 (useful for obtaining your first Refresh Token):
dotnet run --project Solutions/DemoApp/DemoApp.csproj -- --interactive-loginOr using the short flag:
dotnet run --project Solutions/DemoApp/DemoApp.csproj -- -iTo use the FreeAgent Sandbox environment:
dotnet run --project Solutions/DemoApp/DemoApp.csproj -- --sandboxYou can combine flags:
dotnet run --project Solutions/DemoApp/DemoApp.csproj -- -i -sYou can configure the Demo App using User Secrets to avoid committing credentials:
dotnet user-secrets init --project Solutions/DemoApp/DemoApp.csproj
dotnet user-secrets set "FreeAgent:ClientId" "your-client-id" --project Solutions/DemoApp/DemoApp.csproj
dotnet user-secrets set "FreeAgent:ClientSecret" "your-client-secret" --project Solutions/DemoApp/DemoApp.csproj
dotnet user-secrets set "FreeAgent:RefreshToken" "your-refresh-token" --project Solutions/DemoApp/DemoApp.csprojThe demo app uses the UserSecretsId FreeAgent.DemoApp.
Endjin.FreeAgent/
├── Solutions/
│ ├── Endjin.FreeAgent.Client/ # Main client library
│ │ ├── Client/ # API client implementations
│ │ ├── Configuration/ # Client configuration
│ │ └── OAuth2/ # Authentication logic
│ ├── Endjin.FreeAgent.Domain/ # Domain models
│ │ ├── Domain/ # All FreeAgent resource models
│ │ ├── Converters/ # JSON converters for enums and custom types
│ │ └── Validation/ # Data validation classes
│ ├── Endjin.FreeAgent.Client.Tests/ # Client unit tests
│ ├── Endjin.FreeAgent.Domain.Tests/ # Domain unit tests
│ └── DemoApp/ # Demo application
├── Docs/ # FreeAgent API specifications
└── README.md # This file
The client currently supports the following FreeAgent API endpoints:
| Resource | Operations | Status |
|---|---|---|
| Core Financial | ||
| Invoices | Create, Read, Update, Delete, List, Email, Mark as Sent | ✅ Complete |
| Recurring Invoices | Read, List | ✅ Complete |
| Invoice Settings | Read, Update | ✅ Complete |
| Estimates | Create, Read, Update, Delete, List, Send, Mark as Sent | ✅ Complete |
| Bills | Create, Read, Update, Delete, List | ✅ Complete |
| Credit Notes | Create, Read, Delete, List | ✅ Complete |
| Credit Note Reconciliations | Create, Read, Delete, List | ✅ Complete |
| Expenses | Create, Read, Update, Delete, List | ✅ Complete |
| Mileages | Create, Read, Update, Delete, List | ✅ Complete |
| Banking | ||
| Bank Accounts | Read, List | ✅ Complete |
| Bank Transactions | Create, Read, Update, Delete, List | ✅ Complete |
| Bank Transaction Explanations | Create, Read, Delete, List | ✅ Complete |
| Bank Statement Uploads | Create (OFX, QIF, CSV) | ✅ Complete |
| Contacts & Projects | ||
| Contacts | Create, Read, Update, Delete, List | ✅ Complete |
| Projects | Create, Read, Update, Delete, List | ✅ Complete |
| Tasks | Create, Read, Update, Delete, List | ✅ Complete |
| Timeslips | Create, Read, Update, Delete, List | ✅ Complete |
| Accounting | ||
| Categories | List | ✅ Complete |
| Journal Sets | Create, Read, Delete, List | ✅ Complete |
| Transactions | Read, List | ✅ Complete |
| Opening Balances | Read, Update | ✅ Complete |
| Assets & Inventory | ||
| Capital Assets | Create, Read, Update, Delete, List | ✅ Complete |
| Capital Asset Types | Read, List | ✅ Complete |
| Depreciation Profiles | Read, List | ✅ Complete |
| Stock Items | Create, Read, Update, Delete, List | ✅ Complete |
| Price List Items | Create, Read, Update, Delete, List | ✅ Complete |
| Reports | ||
| Trial Balance | Read (with summary entries) | ✅ Complete |
| Balance Sheet | Read | ✅ Complete |
| Profit & Loss | Read | ✅ Complete |
| Cash Flow | Read | ✅ Complete |
| Final Accounts | Read | ✅ Complete |
| Aged Debtors & Creditors | Read | ✅ Complete |
| Tax | ||
| VAT Returns | Read, List, Update (payments) | ✅ Complete |
| Sales Tax Periods | Read, List | ✅ Complete |
| Sales Tax Rates | List | ✅ Complete |
| EC MOSS Sales Tax Rates | List | ✅ Complete |
| Corporation Tax Returns | Read, List | ✅ Complete |
| Self Assessment Returns | Read, List | ✅ Complete |
| CIS Bands | List (UK only) | ✅ Complete |
| Payroll | ||
| Payroll | Read (UK RTI data) | ✅ Complete |
| Payroll Profiles | Read, Update | ✅ Complete |
| UK-Specific | ||
| Hire Purchases | Create, Read, Update, Delete, List | ✅ Complete |
| Properties | Create, Read, Update, Delete, List | ✅ Complete |
| Company & Users | ||
| Company | Read, Update | ✅ Complete |
| Users | Read, List, Update | ✅ Complete |
| Email Addresses | Read, List | ✅ Complete |
| Other | ||
| Attachments | Create, Delete | ✅ Complete |
| Notes | Create, Read, Update, Delete, List | ✅ Complete |
| Webhooks | Create, Read, Delete, List | ✅ Complete |
Some features are only available in specific regions or require certain FreeAgent subscription types:
- UK-Only Features: CIS Bands (Construction Industry Scheme), Hire Purchases, Properties (for unincorporated landlords), Payroll (RTI data)
- EU-Specific Features: EC MOSS Sales Tax Rates (Mini One Stop Shop)
We welcome contributions! Please see our contributing guidelines for details on:
- Code style and conventions
- Testing requirements
- Pull request process
- Issue reporting
- Visual Studio 2026 or later
- .NET 10 SDK
- Git
The solution uses the Microsoft Testing Platform. You can run tests using dotnet run:
# Run client tests
dotnet run --project Solutions/Endjin.FreeAgent.Client.Tests/Endjin.FreeAgent.Client.Tests.csproj
# Run domain tests
dotnet run --project Solutions/Endjin.FreeAgent.Domain.Tests/Endjin.FreeAgent.Domain.Tests.csprojThe client library is optimized for performance:
- Source-Generated JSON - Uses System.Text.Json source generation for minimal allocations
- HTTP Client Factory - Proper HttpClient lifecycle management
- Memory Caching - Built-in caching for frequently accessed resources
- Async Throughout - Non-blocking I/O operations
- Minimal Dependencies - Carefully selected, essential dependencies only
The client provides comprehensive error handling:
try
{
Invoice invoice = await client.Invoices.GetAsync(invoiceId);
}
catch (HttpRequestException ex)
{
// Handle network and API errors
Console.WriteLine($"API Error: {ex.Message}");
if (ex.StatusCode.HasValue)
{
Console.WriteLine($"Status Code: {ex.StatusCode}");
}
}For issues, feature requests, or questions:
- 🐛 Report an Issue
- 💬 Discussions
- 📧 Contact Endjin Limited
See FreeAgent's API Terms
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Copyright © Endjin Limited. All rights reserved.