Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions blog/260219-update-bills-bill-pay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: "Bill Pay: update bills with no hassle"
date: "2026-02-19"
tags: ["Product", "Update", "Bill Pay"]
authors: pzaichkina
---

You can now update existing bills directly through our Bill Pay solution.

<!--truncate-->

## What's new?

We've expanded our [Bill Pay](/payables/overview) solution with the new [Update bills](/sync-for-payables-v2-api#/operations/update-bill) endpoint.

No more deleting and recreating bills just to fix a typo or a changed line item. With this update, your customers can edit bills in their accounting software, and we will automatically sync these changes to your platform, keeping the records accurate and up-to-date.

The endpoint currently supports our FreeAgent, QuickBooks Online, and Xero integrations.

## Who is this relevant for?

This update is relevant for all clients using Codat's Bill Pay solution who want to give their customers a seamless bill management experience.

## How to get started?

You can start using the endpoint right now. Check out the [Update bills](/sync-for-payables-v2-api#/operations/update-bill) endpoint in our API reference, or explore Bill Pay's [Update bills](/payables/sync/update-bill) documentation for a full walkthrough.
6 changes: 3 additions & 3 deletions docs/payables/configure-customer.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Remember to [authenticate](/using-the-api/authentication) when making calls to o

## Create a company

Within Bill Pay, a company represents your SMB customer that pays and manages their bills using your application. To create it, use our [Create company (async)](/sync-for-payables-api#/operations/create-company) or [Create company (sync)](/sync-for-payables-v2-api#/operations/create-company) endpoints.
Within Bill Pay, a company represents your SMB customer that pays and manages their bills using your application. To create it, use our [Create company](/sync-for-payables-v2-api#/operations/create-company) endpoints.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [vale] reported by reviewdog 🐶
[Google.WordList] Use 'app' instead of 'application'.


The endpoints return the company schema containing the ID that you will use to establish a connection to an accounting software.

Expand Down Expand Up @@ -122,7 +122,7 @@ if companyResponse.StatusCode == 200 {

## Create a connection

Next, use the [Create connection (async)](/sync-for-payables-api#/operations/create-connection) or [Create connection (sync)](/sync-for-payables-v2-api#/operations/create-connection) endpoints to connect the company to an accounting data source via one of our integrations.
Next, use the [Create connection](/sync-for-payables-v2-api#/operations/create-connection) endpoints to connect the company to an accounting data source via one of our integrations.

This will allow you to synchronize data with that source, fetching or creating suppliers, bills, and payment methods. In the request body, specify a `platformKey` of the accounting software you're looking to connect.

Expand Down Expand Up @@ -225,7 +225,7 @@ fmt.Println(connectionResponse.Connection.LinkUrl)

## Deauthorize a connection

If your customer wants to revoke their approval and sever the connection to their accounting software, use the [Unlink connection (async)](/sync-for-payables-api#/operations/Unlink-connection) or [Unlink connection (sync)](/sync-for-payables-v2-api#/operations/Unlink-connection) endpoints.
If your customer wants to revoke their approval and sever the connection to their accounting software, use the [Unlink connection](/sync-for-payables-v2-api#/operations/Unlink-connection) endpoints.

You can [learn more](/auth-flow/optimize/connection-management) about connection management best practices and see how you can provide this functionality in your app's UI.

Expand Down
192 changes: 192 additions & 0 deletions docs/payables/sync/update-bill.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
---
title: Update bills
description: "Update existing bills using Codat's Bill Pay solution"
sidebar_label: Update a bill
---

import Tabs from "@theme/Tabs";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[Google.Semicolons] Use semicolons judiciously.

import TabItem from "@theme/TabItem";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[Google.Semicolons] Use semicolons judiciously.


:::tip Invoices or bills?

We distinguish between invoices where the company _owes_ money and those where the company _is owed_ money. If the company receives an invoice and owes money as a result, we call this a **bill**.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[Google.Passive] In general, use active voice instead of passive voice ('is owed').

:::

## Update a bill

:::info Software coverage

This action is currently only supported for FreeAgent, QuickBooks Online, and Xero.

:::

In some cases, your SMB customer may want to update their existing bill: for example, to change a tax rate, change a nominal code for a line item, or associate it to a different supplier.

Use our [Update bill](/sync-for-payables-v2-api#/operations/update-bill) endpoint to perform this operation. The following rules apply:

- You can only update the bills in `Open` status, and updates to bills in any other states will be rejected.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[Google.Will] Avoid using 'will'.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[Google.Passive] In general, use active voice instead of passive voice ('be rejected').

- During the update, all existing bill line items will removed and replaced with new line items.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[Google.Will] Avoid using 'will'.

- You can change the following values:
- `reference`
- `supplierRef.id`
- `issueDate`
- `dueDate`
- `currency`
- `currencyRate`
- `lineItems[]`

For integration-specific rules and errors, review the [Software requirements](/payables/sync/update-bill#software-requirements) section.

---

### Example payloads

<Tabs groupId="software">

<TabItem value="gen" label="Request structure">

```json
PUT /companies/{companyId}/connections/{dataConnectionId}/payables/bills/{billId}

{
"reference": "INV-001",
"supplierRef": { "id": "supplier-id" },
"issueDate": "2026-01-28",
"dueDate": "2026-02-28",
"currency": "GBP",
"currencyRate": 1.0,
"status": "Open",
"lineItems": [
{
"description": "Service fee",
"unitAmount": 100.00,
"quantity": 1,
"accountRef": { "id": "account-id" },
"taxRateRef": { "id": "tax-rate-id" },
"taxAmount": 20.00,
"trackingRefs": [{ "id": "tracking-id" }]
}
]
}
```

</TabItem>

<TabItem value="fa" label="FreeAgent example">

```json
{
"description": "Consulting",
"unitAmount": 500,
"quantity": 2,
"accountRef": { "id": "<nominal-code>" },
"taxAmount": 200,
"trackingRefs": [{ "id": "<project-id>", "isBillable": true }]
}
```

</TabItem>

<TabItem value="qbo" label="QBO example">

```json
{
"description": "Consulting",
"unitAmount": 500,
"quantity": 2,
"accountRef": { "id": "<account-id>" },
"taxRateRef": { "id": "<tax-rate-id>" }
}
```
</TabItem>

<TabItem value="xero" label="Xero example">

```json
{
"description": "Consulting",
"unitAmount": 500,
"quantity": 2,
"accountRef": { "id": "<account-guid>" },
"taxRateRef": { "id": "<tax-rate-code>" },
"trackingRefs": [{ "id": "<tracking-option-guid>" }]
}
```

</TabItem>

</Tabs>

### Software requirements

We have summarized the key differences between the integrations that support updates to bills below:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[Google.Contractions] Use 'we've' instead of 'We have'.


| Feature | FreeAgent | QBO | Xero |
|--------------------------|----------------------|---------------------|---------------------|
| **Reference max length** | 255 characters | 21 characters | 255 characters |
| **`TaxRateRef`** | Must be `null` | Required | Required |
| **Tax handling** | Use `taxAmount` only | Use `taxRateRef.id` | Use `taxRateRef.id` |
| **`AccountRef` format** | Nominal code | Numeric string | GUID |
| **Max line items** | 40 | No limit | No limit |

### Validation errors

You may encounter a validation error when sending a request to update a bill. In the sections below, we`ve included general and software-specific errors to help resolve these.

#### General validation errors

| Validation | Error message |
|-----------------------------|---------------------------------------------------------|
| Missing `supplierRef` | `Supplier Ref` must not be empty. |
| Missing `supplierRef.id` | `Supplier Ref Id` must not be empty. |
| Missing `issueDate` | `Issue Date` must not be empty. |
| Missing `dueDate` | `Due Date` must not be empty. |
| Missing currency | `Currency` must not be empty. |
| Invalid currency | `Currency Length` must be equal to `3`. |
| Currency rate `<=0` | `Currency Rate` must be greater than `0`. |
| Missing status | `Status` must not be empty. |
| Invalid status | `Status` must be equal to `Open`. |
| Missing or empty line items | `Line Items` must not be empty. |
| Negative line items total | Sum of `LineItems` must be greater than or equal to `0`. |
| Reference too long | `Reference Length` must be less than or equal to `255`. |
| Bill not found | 404 Not Found |

#### Software-specific errors

<Tabs groupId="software">

<TabItem value="fa" label="FreeAgent">

| Issue | Error message |
|----------------------|-----------------------------------------------|
| Invalid account code | `Account Ref` was not found in FreeAgent. |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[Google.Contractions] Use 'wasn't' instead of 'was not'.

| Invalid supplier ID | `Supplier Ref Id` was not found in FreeAgent. |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[Google.Contractions] Use 'wasn't' instead of 'was not'.


</TabItem>

<TabItem value="qbo" label="QuickBooks Online">

| Issue | Error message |
|----------------------------------------|----------------------------------------------------------------------------|
| Bill currency doesn`t match supplier | Ensure that the currency of the bill matches the currency of the supplier. |
| Supplier doesn`t support bill currency | The chosen `supplierId` doesn`t handle the bills currency. |

</TabItem>

<TabItem value="xero" label="Xero">

| Issue | Error message |
|----------------------|-------------------------------------------|
| Invalid account GUID | `Account Ref` was not found in Xero. |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[Google.Contractions] Use 'wasn't' instead of 'was not'.

| Invalid supplier ID | `SupplierRef Id` was not found in Xero. |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] reported by reviewdog 🐶
[Google.Contractions] Use 'wasn't' instead of 'was not'.

| Currency not enabled | No currency exists for code `currency`. |

</TabItem>

</Tabs>

---

## Read next

- Enable your customers to [pay single bills](/payables/sync/pay-bill) to complete the Bill Pay process.
1 change: 1 addition & 0 deletions sidebars/payables.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ module.exports = [
},
"payables/sync/bills",
"payables/sync/pay-bill",
"payables/sync/update-bill",
{
type: "doc",
id: "payables/sync/sync-data-types",
Expand Down
2 changes: 1 addition & 1 deletion src/components/DataTypes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const products = {
path: "/sync-for-payables-api",
},
billpaysync: {
name: "Bill Pay (sync)",
name: "Bill Pay",
spec: BillPaySync,
path: "/sync-for-payables-v2-api",
},
Expand Down
2 changes: 1 addition & 1 deletion src/pages/sync-for-payables-v2-api/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const URL = "/oas/Codat-Sync-Payables.json"

const PayablesApi = () => {
return (
<Api url={URL} title="Bill Pay (sync) API reference"/>
<Api url={URL} title="Bill Pay API reference"/>
);
}

Expand Down
Loading