---
title: "Official Central Bank Exchange Rates in Xero"
description: "Xero sets organisation exchange rates from XE and does not accept a replacement feed. Here is how to book invoices, bills and bank transactions at the official central-bank rate through the Xero Accounting API."
canonical: https://allratestoday.com/docs/integrations/xero/
source: AllRatesToday (https://allratestoday.com/) — Markdown mirror of the page above; index of all pages at https://allratestoday.com/llms.txt
generated: 2026-10-23T10:58:33.294Z
---

# Official Central Bank Exchange Rates in Xero

Xero sets organisation exchange rates from XE and does not accept a replacement feed. Here is how to book invoices, bills and bank transactions at the official central-bank rate through the Xero Accounting API.

By [Madhushan](https://allratestoday.com/authors/madhushan/), Founder & Lead Developer

  **Which endpoint:** every guide below reads the bank's latest published table from `GET /api/v1/central-bank/{bank}/latest` (free key, one call per fetch) or the keyless evaluation copy at `/api/public/central-bank/{bank}?format=json`. Add `?source=USD&target=EUR` for one resolved pair, `format=xml` or `format=csv` for importers that do not read JSON, and `api_key=` on the URL when the importer cannot send headers. Bank codes are on the [central bank coverage map](https://allratestoday.com/central-bank-rates-api/).

## What Xero allows

Xero fills its organisation-level rates from XE.com once multicurrency is enabled and exposes no endpoint to replace that feed. What it does allow, in the UI and in the Accounting API, is a rate on each transaction: invoices, bills, credit notes, bank transactions and manual journals all carry a `CurrencyRate`. A compliant workflow therefore sets that field at creation time from the official table for the document date, rather than trying to change Xero's defaults.

## The rate Xero expects

`CurrencyRate` is the number of *document currency* units per 1 unit of the *organisation base currency*. For a GBP organisation raising a EUR invoice you need EUR per GBP. Ask the API for exactly that pair and let it handle inversion or cross rates:

```
GET https://allratestoday.com/api/v1/central-bank/boe/latest?source=GBP&target=EUR
Authorization: Bearer art_live_your_key

{
  "bank": "boe",
  "rate_date": "2026-09-16",
  "source": "GBP",
  "target": "EUR",
  "rate": 1.1662,
  "derived": false,
  "method": "published"
}
```

Use the dated endpoint `/api/v1/central-bank/{bank}/{YYYY-MM-DD}` when the invoice date is not today; if the bank did not publish that day you get the prior table and `published_on_requested_date: false`, which is the rate in force and the one to apply.

## Create the invoice with the official rate

Python, using the `xero-python` SDK after the usual OAuth 2.0 connection:

```
import requests
from xero_python.accounting import AccountingApi, Invoice, LineItem

BANK = "boe"                      # the publisher your rule names
BASE = "GBP"                      # Xero organisation base currency

def official_rate(target, on_date):
    url = f"https://allratestoday.com/api/v1/central-bank/{BANK}/{on_date}"
    r = requests.get(url, params={"source": BASE, "target": target},
                     headers={"Authorization": "Bearer art_live_your_key"}, timeout=10)
    r.raise_for_status()
    body = r.json()
    return body["rate"], body["rate_date"], body["derived"]

rate, rate_date, derived = official_rate("EUR", "2026-09-16")

invoice = Invoice(
    type="ACCREC",
    contact={"ContactID": contact_id},
    date="2026-09-16",
    due_date="2026-10-16",
    currency_code="EUR",
    currency_rate=rate,                          # EUR per 1 GBP, from the Bank of England table
    reference=f"BoE {rate_date}{' (derived)' if derived else ''}",
    line_items=[LineItem(description="Consulting", quantity=1, unit_amount=1000, account_code="200")],
)
AccountingApi(api_client).create_invoices(xero_tenant_id, invoices={"Invoices": [invoice]})
```

Writing the bank and `rate_date` into the reference, or a tracking category, keeps the source of the rate on the document for the auditor. The same field exists on `BankTransactions`, `CreditNotes` and `ManualJournals`.

## Bulk month-end revaluation

Xero's unrealised gains report uses its own closing rate. If your statutory close must use the central bank's month-end table, pull that table once with `/api/v1/central-bank/{bank}/{last-business-day}`, and post the revaluation as a manual journal at those rates. The [Excel download](https://allratestoday.com/blog/download-central-bank-exchange-rates-excel-csv/) gives the same table as a dated file if the close is done in a spreadsheet.

## Notes

- One API call per pair per date. A monthly batch of 200 invoices across five currencies is at most 5 calls a day if you cache per date.
- Xero rounds `CurrencyRate` to six decimal places; official tables are published to four or five, so nothing is lost.
- For UK VAT, HMRC's monthly table is a separate source: [/tax-authority-rates-api/hmrc/](https://allratestoday.com/tax-authority-rates-api/hmrc/).
- Working sample: [central-bank-rates-accounting-sync](https://github.com/AllRates-Today/central-bank-rates-accounting-sync), a Node CLI that produces the month-end CSV for Xero (and syncs QuickBooks).

Other systems: [Business Central](https://allratestoday.com/docs/integrations/business-central/) · [Xero](https://allratestoday.com/docs/integrations/xero/) · [QuickBooks Online](https://allratestoday.com/docs/integrations/quickbooks/) · [SAP](https://allratestoday.com/docs/integrations/sap/) · [Odoo](https://allratestoday.com/docs/integrations/odoo/) · [all integrations](https://allratestoday.com/docs/integrations/). Endpoint reference: [Central Bank Exchange Rate API](https://allratestoday.com/docs/#central-bank).
