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.
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.
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
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
CurrencyRateto 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/.
Other systems: Business Central · Xero · QuickBooks Online · SAP · Odoo · all integrations. Endpoint reference: Central Bank Rates.