Contents Lesson 8 of 16

4 min read · professional

What exactly is the 10-year?

"The 10-year is at 4.65" is a sentence every market report writes. As a data question it is badly underspecified, and this endpoint family gives you at least four candidate answers on any given day.

The last member of the family

GET /ust/long-term-rates completes the set. Same parameters again — from, to, filter[year], page[limit], page[offset], fmt — and rows shaped date, rate_type, rate, extrapolation_factor.

rate_type takes three values: BC_20year, Over_10_Years and Real_Rate. In 2026 the endpoint returns meta.total of 426 rows to 27 July, which is 142 × 3. For 27 July 2026:

  • BC_20year — 5.15
  • Over_10_Years — 5.11
  • Real_Rate — 2.95

Over_10_Years is a long-term composite: an average across outstanding Treasury securities with more than ten years remaining. Real_Rate is the corresponding long-term real average. extrapolation_factor exists for periods when the Treasury had to extrapolate the long end because no 30-year bond was being issued; across the whole of 2026 it comes back null on every row. A nullable field that is almost always null is still a field you must handle.

The cross-check that proves the family is consistent

BC_20year on 27 July 2026 is 5.15. The 20Y tenor from /ust/yield-rates on the same date is also 5.15. Real_Rate is 2.95, and the 30Y point from /ust/real-yield-rates is 2.95.

Only one of those is an identity. BC_20year is the 20-year CMT, so assert that one: if a rebuild ever breaks it, something upstream changed and you will find out from a failing check rather than from a wrong chart.

The second pair is a coincidence of that particular day, and it is worth knowing why before you write it into a test. Real_Rate is Treasury's Long-Term Real Rate Average — the unweighted average of bid real yields on every outstanding TIPS with more than ten years to run — so it spans the ten-to-thirty sector rather than sitting at the long end. Over 2026 it matched the 30Y real CMT on three days out of 171, and by 4 September it read 2.92 against 2.96. Compare the two by all means. Do not assert them equal, or your pipeline fails 98% of the time for no reason.

Four different 10-years

Now the underspecified sentence. On 27 July 2026, all of the following are defensible readings of "the 10-year":

  • 4.65 — the 10Y constant-maturity par yield from /ust/yield-rates. A fitted point on a curve. No security has this yield.
  • 2.44 — the 10Y real yield from /ust/real-yield-rates. Same maturity, inflation stripped out.
  • 5.11 — the Over_10_Years composite, an average over everything past ten years. Longer in effective maturity, and therefore higher on this curve.
  • The yield of the on-the-run 10-year note — the most recently auctioned one, which is what a trading desk usually means. It is a real security with a real CUSIP, it trades slightly differently from older notes of similar maturity, and it is not in any of these three endpoints.

A fifth reading exists that none of these endpoints publish: the 10-year zero-coupon (spot) rate. A par yield and a zero rate differ whenever the curve is not flat, which is always. The credit endpoints in Unit 4 do publish both, under yield_type values of par and spot, and the difference there is around nine basis points.

Why the distinction is not pedantry

Duration, discounting and any present-value calculation are sensitive to which curve you used. Discounting a stream of cash flows with par yields rather than zero rates introduces a small, systematic error that grows with the steepness of the curve and the length of the stream. The Fixed Income domain's duration material develops that properly; here the only claim is that the choice exists and your data must record which one you made.

For a visual anchor, a long-duration Treasury fund gives you the price side of the same story — the 20-year point at 5.15% and the 30-year at 5.12% are the discount rates that value it:

Interactive line chart: TLT.US (1Y)

Try it now

  1. Here are /ust/long-term-rates and /ust/yield-rates on their newest date. Check BC_20year against the 20Y tenor; leave Real_Rate unasserted, for the reason above. Measured on 28 September 2026, BC_20year equalled the 20Y CMT on all 185 dates of 2026; write that assertion into your test suite.
Live API response: mda2 ust long term latest
Live API response: mda2 ust latest curve
2. Write down which of the four 10-years above your own code uses, and where that decision is recorded. If it is not written anywhere, it will be relitigated by whoever reads your chart. 3. Counted on 28 September 2026, the long-term endpoint's 2026 year held 555 rows (185 dates × 3) and not one had a non-null `extrapolation_factor`. So your null handling is exercised by nothing in this year's data. Write the test row that exercises it deliberately: which value would you put in the field, and what should your code do with it?