DEV Community

viraj geeth
viraj geeth

Posted on Originally published at allratestoday.com

Pushing Official Central Bank Exchange Rates into QuickBooks Online (One POST per Currency per Day)

Once multicurrency is on, QuickBooks Online downloads market rates automatically. It also lets you enter your own rate per currency per day, and that override is a first-class API object: ExchangeRate in the Accounting API, keyed by source currency and AsOfDate. Transactions dated that day pick the override up unless a rate was set on the transaction itself.

That means the whole "book at the central bank's rate" integration is one POST per currency per day. The full guide is on AllRatesToday: QuickBooks Online integration.

The rate QuickBooks expects

Rate is home-currency units per 1 unit of SourceCurrencyCode. For a USD company and EUR that is USD per EUR. Rather than working out whether the bank publishes that direction, ask the API for the pair directly. It inverts or crosses when needed and tells you:

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

{ "bank": "ecb", "rate_date": "2026-10-09", "source": "EUR", "target": "USD",
  "rate": 1.1206, "derived": false, "method": "published" }
Enter fullscreen mode Exit fullscreen mode

The daily sync

import requests

REALM = "1234567890"
QBO = f"https://quickbooks.api.intuit.com/v3/company/{REALM}"
QBO_H = {"Authorization": f"Bearer {qbo_access_token}", "Accept": "application/json"}
ART_H = {"Authorization": "Bearer art_live_your_key"}
BANK, HOME = "ecb", "USD"

# 1. currencies enabled in the company
q = requests.get(f"{QBO}/query", headers=QBO_H,
                 params={"query": "SELECT * FROM CompanyCurrency", "minorversion": 75}).json()
codes = [c["Code"] for c in q["QueryResponse"].get("CompanyCurrency", [])]

# 2. one official rate per currency, home units per 1 foreign unit
for code in codes:
    r = requests.get(f"https://allratestoday.com/api/v1/central-bank/{BANK}/latest",
                     params={"source": code, "target": HOME}, headers=ART_H, timeout=10)
    if r.status_code == 404:          # bank does not cover this currency
        continue
    body = r.json()
    payload = {"SourceCurrencyCode": code, "AsOfDate": body["rate_date"], "Rate": body["rate"]}
    requests.post(f"{QBO}/exchangerate", headers=QBO_H, params={"minorversion": 75}, json=payload).raise_for_status()
    print(code, body["rate_date"], body["rate"], "derived" if body["derived"] else "published")
Enter fullscreen mode Exit fullscreen mode

Run it after the bank's publication time each business day. Re-posting the same currency and date updates the rate in place, so a rerun is safe, and a bank that amends its table (it happens) is handled by simply running again.

Three things to know

  • Pairs are always foreign to home in QuickBooks. There is no cross-pair table to maintain.
  • US companies often need the US Treasury quarterly table rather than a daily central-bank rate. Same loop, different bank code, quarterly schedule.
  • Per-transaction override is still available. If only some documents need the official rate, set ExchangeRate on the invoice or bill body instead of the company table. Same meaning: home units per 1 unit of document currency.

Try it without a key

https://allratestoday.com/api/open/central-bank/ecb returns the latest ECB table keyless, so you can see what the bank covers before you sign up. The keyed endpoint adds the pair resolution and dated history.

Links

Rates are redistributed from each institution's public publication. They are reference rates for accounting, tax and compliance, not dealing quotes.

Top comments (0)