Invoices
List, create, update, and delete invoices; status transitions; email and PDF actions; company default additional text.
| SDK service | client.Invoices (InvoiceService) |
| FreeAgent docs | dev.freeagent.com/docs/invoices |
| Sample app | /invoices (list), /invoices/detail (CRUD and transitions) |
Pagination patterns: see Pagination. Contact, project, category, and bank account links: see Linked resources. Sales cluster patterns: see Sales entity map.
Methods
ListAsync
Task<PaginatedResponse<Invoice>> ListAsync(
int page = 1,
int perPage = 25,
string? view = null,
string? sort = null,
DateTimeOffset? updatedSince = null,
ContactReference? contact = null,
long? contactId = null,
ProjectReference? project = null,
long? projectId = null,
bool? nestedInvoiceItems = null,
CancellationToken cancellationToken = default)
| Parameter | Type | Required | Default | Wire |
|---|---|---|---|---|
page |
int |
No | 1 |
page |
perPage |
int |
No | 25 |
per_page (max 100) |
view |
string? |
No | null |
view |
sort |
string? |
No | null |
sort |
updatedSince |
DateTimeOffset? |
No | null |
updated_since |
contact |
ContactReference? |
No | null |
contact (URI) |
contactId |
long? |
No | null |
contact (URI from client.Urls.Contact(id)) |
project |
ProjectReference? |
No | null |
project (URI) |
projectId |
long? |
No | null |
project (URI from client.Urls.Project(id)) |
nestedInvoiceItems |
bool? |
No | null |
nested_invoice_items |
cancellationToken |
CancellationToken |
No | default |
- |
HTTP: GET /v2/invoices
Client validation: page ≥ 1; perPage between 1 and 100; supply contact or contactId, not both; supply project or projectId, not both.
Sample:
using FreeAgent.Client.Models.Invoices;
var page = await client.Invoices.ListAsync(
view: InvoiceViews.Open,
contactId: 42,
nestedInvoiceItems: true);
ListAutoPagingAsync
IAsyncEnumerable<Invoice> ListAutoPagingAsync(...)
Same query parameters as ListAsync except page.
GetInvoiceAsync
Task<Invoice> GetInvoiceAsync(long invoiceId, CancellationToken cancellationToken = default)
Task<Invoice> GetInvoiceAsync(
long invoiceId,
InvoiceGetOptions? options,
CancellationToken cancellationToken = default)
HTTP: GET /v2/invoices/:id
When options.IncludeContact or options.IncludeProject is true, the SDK fetches linked resources when the response contains only URIs.
GetInvoicePdfAsync
Task<byte[]> GetInvoicePdfAsync(long invoiceId, CancellationToken cancellationToken = default)
HTTP: GET /v2/invoices/:id/pdf
Decodes the base64 pdf.content wrapper returned by FreeAgent.
CreateInvoiceAsync
Task<Invoice> CreateInvoiceAsync(Invoice invoice, CancellationToken cancellationToken = default)
HTTP: POST /v2/invoices
Required on create: ContactId, DatedOn, PaymentTermsInDays, and at least one line item with Description.
DuplicateInvoiceAsync
Task<Invoice> DuplicateInvoiceAsync(long invoiceId, CancellationToken cancellationToken = default)
HTTP: POST /v2/invoices/:id/duplicate
UpdateInvoiceAsync
Task<Invoice> UpdateInvoiceAsync(
long invoiceId,
Invoice invoice,
InvoiceUpdateOptions? options = null,
CancellationToken cancellationToken = default)
HTTP: PUT /v2/invoices/:id
Update existing line items with ItemId. Delete line items with ItemId and Destroy = 1. Pass new InvoiceUpdateOptions { OmitLineItems = true } to update scalar fields without sending line items. ShowProjectName is sent on update only when Status is Draft — FreeAgent locks show_project_name once an invoice leaves draft. Setting ShowProjectName on update without Status throws ArgumentException (populate Status from GET first).
DeleteInvoiceAsync
Task DeleteInvoiceAsync(long invoiceId, CancellationToken cancellationToken = default)
HTTP: DELETE /v2/invoices/:id
SendInvoiceEmailAsync
Task SendInvoiceEmailAsync(
long invoiceId,
SendInvoiceEmailRequest request,
CancellationToken cancellationToken = default)
HTTP: POST /v2/invoices/:id/send_email
Set request.Email.UseTemplate = true to send using an existing template.
MarkInvoiceAsSentAsync / MarkInvoiceAsScheduledAsync / MarkInvoiceAsDraftAsync / MarkInvoiceAsCancelledAsync
Task<Invoice> MarkInvoiceAsSentAsync(long invoiceId, CancellationToken cancellationToken = default)
Task<Invoice> MarkInvoiceAsScheduledAsync(long invoiceId, CancellationToken cancellationToken = default)
Task<Invoice> MarkInvoiceAsDraftAsync(long invoiceId, CancellationToken cancellationToken = default)
Task<Invoice> MarkInvoiceAsCancelledAsync(long invoiceId, CancellationToken cancellationToken = default)
HTTP: PUT /v2/invoices/:id/transitions/{action}
Behaviour: The SDK sends PUT .../transitions/{action} with an empty JSON body ({}), then fetches the updated invoice with GET .../invoices/:id because FreeAgent transition endpoints return no response body. If the transition succeeds but the follow-up GET fails, the invoice state has already changed on the server; retry the GET to obtain the updated resource.
TakeDirectDebitPaymentAsync
Task TakeDirectDebitPaymentAsync(long invoiceId, CancellationToken cancellationToken = default)
HTTP: POST /v2/invoices/:id/direct_debit
ListTimelineAsync
Task<IReadOnlyList<InvoiceTimelineItem>> ListTimelineAsync(CancellationToken cancellationToken = default)
HTTP: GET /v2/invoices/timeline
Company-wide invoice timeline (not scoped to a single invoice).
ConvertToCreditNoteAsync
Task<CreditNote> ConvertToCreditNoteAsync(long invoiceId, CancellationToken cancellationToken = default)
HTTP: PUT /v2/invoices/:id/transitions/convert_to_credit_note
Returns the converted credit note. Use client.CreditNotes for full credit note operations — see Credit notes.
GetDefaultAdditionalTextAsync / UpdateDefaultAdditionalTextAsync / DeleteDefaultAdditionalTextAsync
HTTP: GET, PUT, and DELETE /v2/invoices/default_additional_text
Company-level default text shown on all invoices.
List filters
view (InvoiceViews)
| Constant | Wire value |
|---|---|
InvoiceViews.All |
all |
InvoiceViews.RecentOpenOrOverdue |
recent_open_or_overdue |
InvoiceViews.Open |
open |
InvoiceViews.Overdue |
overdue |
InvoiceViews.OpenOrOverdue |
open_or_overdue |
InvoiceViews.Draft |
draft |
InvoiceViews.Paid |
paid |
InvoiceViews.ScheduledToEmail |
scheduled_to_email |
InvoiceViews.ThankYouEmails |
thank_you_emails |
InvoiceViews.ReminderEmails |
reminder_emails |
sort (InvoiceSortOptions)
created_at, updated_at — prefix with - for descending.
InvoiceGetOptions
| Property | Type | Purpose |
|---|---|---|
IncludeContact |
bool |
Fetch contact when only a URI is returned |
IncludeProject |
bool |
Fetch project when only a URI is returned |
InvoiceUpdateOptions
| Property | Type | Purpose |
|---|---|---|
OmitLineItems |
bool |
Exclude line items from the update payload |
OmitContact |
bool |
Exclude the contact link from the update payload |
OmitProject |
bool |
Exclude the project link from the update payload |
OmitBankAccount |
bool |
Exclude the bank account link from the update payload |
Invoice model
Key properties:
| Property | Type | Wire name | Notes |
|---|---|---|---|
Reference |
string? |
reference |
|
Status |
InvoiceStatus? |
status |
|
DatedOn |
DateOnly? |
dated_on |
Required on create |
DueOn |
DateOnly? |
due_on |
|
PaymentTermsInDays |
int? |
payment_terms_in_days |
Required on create |
ContactId |
long? |
contact |
Required on create |
ProjectId |
long? |
project |
Optional project link |
BankAccountId |
long? |
bank_account |
Optional remittance bank account |
InvoiceItems |
List<InvoiceItem>? |
invoice_items |
Nested line items |
ShowProjectName |
bool? |
show_project_name |
Writable on create and on draft updates; omitted once the invoice leaves draft; requires Status on update when set |
ItemId |
long? |
id (line items) |
Required to update or delete existing line items |
CategoryNominalCode |
string? |
category (line items) |
Category link on line items |
Url |
string |
url |
Errors
Failures throw FreeAgentApiException.