Billy.Api 5.2.0

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

Billy API — .NET client

A .NET 8 library for the Billy Billing REST API (https://api.billysbilling.com/v2/).

Build status

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");

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

  1. Register at www.billy.dk and create an API key in account settings.
  2. Set the environment variable BILLY_TEST_APIKEY to your key.
  3. Restart Visual Studio so it picks up the new variable.
  4. 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 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. 
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
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.