What is the central bank's rate — and why is that a bad question?
Ask this endpoint for the Federal Reserve's policy rate and it returns two numbers. Ask for the European Central Bank's and it returns three. Ask for the Bank of England's and it returns one. None of them is being unhelpful; the question assumed a singular that does not exist.
The endpoint
GET /rates/policy-rates takes filter[code], filter[country], filter[central_bank], filter[from], filter[to], page[offset], page[limit] (default 20, maximum 100) and fmt. Note the bracketed filter syntax — this family uses filter[from], not the bare from of the Treasury endpoints.
The bare names are not rejected, which is the trap. On 29 September 2026 country=US answered 200 with every row of every bank, meta.total 47,776, where filter[country]=US answered 12,994 Fed rows; a bare from=2024-09-02 on /rates/reference-rates answered with the newest fixings instead of that week. Check meta.total against what you expected before you trust a filter took.
The coverage is three central banks: the Fed, the ECB and the Bank of England. filter[country]=AU, JP or CA answers 422 Invalid parameters, so a rate differential against the Australian dollar or the yen needs its other leg from somewhere else.
Rows carry date, code, country, central_bank, rate, source and source_series_id. That last field is the identifier at the original publisher, and it is the single most useful field for auditing: it lets you go and check the number at its source.
Three central banks, three shapes
Filtering on central_bank=FED for 27 July 2026 returns two rows:
FED_TARGET_LOWER— 3.50FED_TARGET_UPPER— 3.75
The Fed sets a target range, not a point. There is no FED_TARGET code because there is no such published rate. The midpoint of 3.625 that commentary quotes is derived: (3.50 + 3.75) ÷ 2. If your schema has one column for "the Fed rate", it cannot represent what the Fed actually announces.
Filtering on central_bank=ECB for the same date returns three:
ECB_DFR— 2.25, the deposit facility rateECB_MRO— 2.40, the main refinancing operations rateECB_MLF— 2.65, the marginal lending facility rate
The same three rows, on whatever the latest published date happens to be:
Those three define a corridor 40 basis points wide and are not interchangeable. Which one is "the ECB rate" depends on what you are asking, and since the euro area moved to structural excess liquidity in the mid-2010s the deposit rate has generally been the one that binds, because a banking system holding excess reserves has nothing to borrow at the top of the corridor. That is a description of a mechanism, not a rule you should hard-code without checking the era you are looking at.
Filtering on central_bank=BOE returns exactly one code, BOE_BANK_RATE, at 3.75 on 24 July 2026.
A step function stored as a daily series
filter[central_bank]=ECB reported meta.total of 27,182 rows on 2026-07-28 and 27,329 on 2026-09-15 — it grows by three a day. That is not 27,182 decisions. It is a daily grid of three codes — and it is not even a complete grid. ECB_DFR and ECB_MLF each carry one row for every calendar day since 1999-01-01; ECB_MRO is 3,031 days short of them, and the three counts sum to the total. Ask for 1 to 3 June 2003 and the response holds ECB_DFR and ECB_MLF and no ECB_MRO row at all, because the underlying MRR_FR series does not cover the years the ECB ran variable-rate tenders. Policy rates change on meeting dates and stay flat in between; the endpoint stores the flat days — except where one of the three codes stops storing them for the better part of a decade.
The practical consequences:
- To find decisions, diff consecutive rows on the same
code. Every row where the value differs from the previous row is a policy change, and itsdateis the effective date. - Paging matters. With a maximum
page[limit]of 100, a full ECB history is 272 requests. Filter to a date range instead. - The effective date is not the announcement date. A decision announced on one day frequently takes effect on the next business day, and this series records the effect.
Why this is the join key for everything else
A policy rate is an administered number: a committee votes and publishes it. Every other rate in this unit is a measured number: transactions happen and somebody computes a statistic. Conflating the two produces confident nonsense — you cannot say a policy rate "moved on the data", because it does not move at all between meetings.
The what-central-banks-do lesson in Markets Foundations covers what the committee is trying to achieve. This lesson only insists that when you write rate into a column, you record whether a committee set it or a market printed it. The next lesson is the other half.
Try it now
- Here is
/rates/policy-rates?filter[central_bank]=FEDfor 16 and 17 September 2026. Reconstruct the target range as a single midpoint for each day, and say what happened between them. Note that you had to write the arithmetic yourself: no row holds a midpoint.
- Here is the same question asked twice, once as
country=USand once asfilter[country]=US. Compare the twometa.totalvalues and the banks in the first rows, and write the one-line check your client runs to catch a parameter that was accepted and ignored.