Billy.Api
5.2.0
dotnet add package Billy.Api --version 5.2.0
NuGet\Install-Package Billy.Api -Version 5.2.0
<PackageReference Include="Billy.Api" Version="5.2.0" />
<PackageVersion Include="Billy.Api" Version="5.2.0" />
<PackageReference Include="Billy.Api" />
paket add Billy.Api --version 5.2.0
#r "nuget: Billy.Api, 5.2.0"
#:package Billy.Api@5.2.0
#addin nuget:?package=Billy.Api&version=5.2.0
#tool nuget:?package=Billy.Api&version=5.2.0
Billy API — .NET client
A .NET 8 library for the Billy Billing REST API (https://api.billysbilling.com/v2/).
Install
install-package BillyService
Supported resources
| Resource | Get | List | Create | Update | Delete |
|---|---|---|---|---|---|
| BankPayments* | ✓ | ✓ | ✓ | ✓ | |
| Bills | ✓ | ✓ | ✓ | ✓ | ✓ |
| Invoices | ✓ | ✓ | ✓ | ✓ | ✓ |
| Contacts | ✓ | ✓ | ✓ | ✓ | ✓ |
| Products | ✓ | ✓ | ✓ | ✓ | ✓ |
| Daybooks | ✓ | ✓ | ✓ | ✓ | ✓ |
| DaybookTransactions | ✓ | ✓ | ✓ | ✓ | ✓ |
| Accounts | ✓ | ✓ | |||
| AccountGroups | ✓ | ✓ | |||
| Organizations | ✓ | ✓ | |||
| TaxRates | ✓ | ✓ | |||
| SalesTaxRulesets | ✓ | ✓ |
* The Billy API docs list delete and bulk delete for bankPayments, but these endpoints do not appear to work in practice.
Quick start
// Construct from an API key — creates its own HttpClient
var bills = new Bills("your-api-key");
// Or share a single RestClient across repositories (better for DI scenarios)
var client = ClientExtensions.CreateBillyClient("your-api-key");
var bills = new Bills(client);
var invoices = new Invoices(client);
var contacts = new Contacts(client);
Get and list
var bill = await bills.GetAsync("bill-id");
var allBills = await bills.ListAsync();
// Filter, sort, page
var recent = await invoices.ListAsync(
new { contactId = "abc123" },
i => i.ApprovedTime,
SortOrder.DESC,
pageSize: 25
);
Create and update
var id = await bills.CreateAsync(new Bill
{
OrganizationId = "org-id",
ContactId = "contact-id",
EntryDate = DateTime.Today,
DueDate = DateTime.Today.AddDays(30),
TaxMode = "incl",
Lines = [
new BillLine { AccountId = "acc-id", Amount = 10000 }
]
});
// Full update (sends the whole object)
await bills.UpdateAsync(bill);
// Partial update — only sends the changed fields
var delta = new DeltaObject<Bill>()
.Set(b => b.State, BillStates.Approved)
.Set(b => b.DueDate, DateTime.Today.AddDays(14));
await bills.UpdateAsync(id, delta);
Delete
await bills.DeleteAsync("bill-id");
Sideloading related objects
Some repositories expose opt-in sideloads that fetch related data in a single API call:
// Bills — loads BillLine objects and attaches them to Bill.Lines
bills.SideloadLines();
var bill = await bills.GetAsync("bill-id"); // bill.Lines is populated
// Contacts — attach Country and Locale objects
contacts.SideloadCountry();
contacts.SideloadLocale();
var contact = await contacts.GetAsync("contact-id"); // contact.Country is populated
// Accounts always sideloads Group and Organization automatically
var account = await accounts.GetAsync("account-id"); // account.Group is populated
Debug logging
var client = ClientExtensions.CreateBillyClient(
httpClient,
"your-api-key",
new BillyDebugLog(Console.WriteLine)
);
Testing
- Register at www.billy.dk and create an API key in account settings.
- Set the environment variable
BILLY_TEST_APIKEYto your key. - Restart Visual Studio so it picks up the new variable.
- Run the tests in
Billy.Api.Tests.
Extending — add your own endpoints
Every repository in this library is simply a class that inherits one of three base classes. You can do the same thing in your own project to reach Billy endpoints that haven't been implemented here yet, or to add custom helper methods on top of existing ones.
Read-only endpoint (Get + List)
// Your model
public class BankPaymentRoot : Root
{
public BankPayment? BankPayment { get; set; }
public List<BankPayment>? BankPayments { get; set; }
}
public class BankPayment : IEntity
{
public string? Id { get; set; }
public string OrganizationId { get; set; }
// ... other fields
}
// Your repository
public class BankPayments : Billy.Api.Repositories.Base<BankPayment, BankPaymentRoot>
{
public BankPayments(string key) : base(key) { }
public BankPayments(RestClient client) : base(client) { }
}
Full CRUD endpoint (Get + List + Create + Update + Delete)
public class BankPayments : Billy.Api.Repositories.BaseWithDelete<BankPayment, BankPaymentRoot>
{
public BankPayments(string key) : base(key) { }
public BankPayments(RestClient client) : base(client) { }
}
Add custom methods to an existing repository
Inherit from the existing class and add whatever you need:
public class MyInvoices : Billy.Api.Invoices
{
public MyInvoices(string key) : base(key) { }
public async Task<IList<Invoice>?> GetDraftAsync()
=> await ListAsync(new { state = "draft" });
}
The URL is auto-derived from the class name (BankPayments → /bankPayments/). See CLAUDE.md for the full naming conventions and sideload wiring guide.
Architecture
See CLAUDE.md for a detailed guide on the internal patterns and step-by-step instructions for adding new resources.
| Product | Versions 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 was computed. 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. |
-
net8.0
- RestSharp (>= 114.0.0)
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 |
|---|---|---|
| 5.2.0 | 300 | 6/12/2026 |
| 5.1.0 | 132 | 6/12/2026 |
| 5.0.0 | 159 | 6/9/2026 |
| 4.1.2 | 124 | 6/9/2026 |
| 4.0.2 | 113 | 6/9/2026 |
| 4.0.1 | 124 | 6/9/2026 |
| 4.0.0 | 137 | 6/8/2026 |
| 3.2.0 | 141 | 6/5/2026 |
| 3.1.0 | 189 | 4/10/2026 |
| 3.0.1 | 120 | 4/10/2026 |
| 3.0.0 | 124 | 4/10/2026 |
| 2.1.7 | 121 | 4/8/2026 |
| 2.1.6 | 123 | 4/8/2026 |
| 2.1.5 | 496 | 7/8/2025 |
| 2.1.4 | 286 | 12/15/2024 |
| 2.1.3 | 231 | 6/12/2024 |
| 2.1.2 | 200 | 6/12/2024 |
| 2.1.1 | 204 | 6/11/2024 |
| 2.0.2 | 225 | 6/6/2024 |
| 2.0.0 | 217 | 6/6/2024 |
Convention-driven .NET 8 repository layer over the Billy REST API. Partial updates via DeltaObject<T>, opt-in sideloading, filtering, sorting, and paging. Repositories are fully extensible from consumer projects.