Guides · bonds

Price a fixed-rate bond with a REST API (clean/dirty price, YTM, duration)

To price a fixed-rate bond over REST, POST its coupon, dates, day count and a yield (or zero curve) to https://quantbox.dev/v1/bonds/price. One call returns the clean price, dirty price, accrued interest, YTM, modified duration, convexity and basis-point value — all per 100 of face value, with the conventions restated in the response.

01The call

A 5% annual bond issued 2024-07-01, maturing 2029-07-01, settling 2026-10-15, priced at a flat 4% yield:

request
curl -s https://quantbox.dev/v1/bonds/price \
  -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
  -d '{"coupon_rate": 0.05,
       "issue_date": "2024-07-01",
       "maturity_date": "2029-07-01",
       "settlement_date": "2026-10-15",
       "frequency": "annual",
       "day_count": "act/act",
       "yield_rate": 0.04}'

Runs on the free tier — 500 calls/month, no credit card. Get a key.

response
{
  "clean_price": 102.4892,
  "dirty_price": 103.9413,
  "accrued": 1.4521,
  "ytm": 0.04,
  "modified_duration": 2.4748,
  "convexity": 8.7012,
  "bpv": -0.0257,
  "conventions": {
    "prices": "per 100 of face value (market quote convention)",
    "settlement": "as provided (settlementDays=0, no implicit T+2)",
    "ytm": "compounded annual, act/act",
    "zero_curve": "zero rates continuously compounded, act/365",
    "calendar": "TARGET, unadjusted schedule"
  }
}

02Same call in Python

python
import requests

KEY = "YOUR_API_KEY"  # free key from https://quantbox.dev

r = requests.post("https://quantbox.dev/v1/bonds/price",
    headers={"X-API-Key": KEY},
    json={"coupon_rate": 0.05,
          "issue_date": "2024-07-01",
          "maturity_date": "2029-07-01",
          "settlement_date": "2026-10-15",
          "frequency": "annual",
          "day_count": "act/act",
          "yield_rate": 0.04})
bond = r.json()
print(bond["clean_price"], bond["dirty_price"], bond["bpv"])
# 102.4892 103.9413 -0.0257

03What "pricing a bond" actually computes

Pricing a fixed-rate bond means discounting its remaining cash flows — here the 5.00 coupons of July 2027, 2028 and 2029 plus the 100 principal at maturity — at the yield you supply, compounded at the coupon frequency. The API generates the coupon schedule backwards from maturity, applies the day count you name, and splits the present value into the three numbers markets actually use: the clean price (what is quoted), the accrued interest (coupon earned since the last payment), and the dirty price (what the buyer pays: clean + accrued).

The schedule and day-count bookkeeping is where spreadsheet bond math quietly goes wrong — which is why the request states every convention explicitly and the response repeats them back.

04Every field in the response

FieldValueMeaning
clean_price102.4892Present value of remaining cash flows minus accrued interest — the number markets quote, per 100 face.
dirty_price103.9413What the buyer actually pays at settlement: clean + accrued. See clean vs dirty, explained with code.
accrued1.4521Coupon earned since the last payment (2026-07-01): 106 of 365 days into the period under act/act, so 5.00 × 106/365 = 1.4521.
ytm0.04Echoes the flat yield here (compounded annual, act/act). When you price off a zero_curve instead, the equivalent YTM is backed out for you.
modified_duration2.4748First-order rate sensitivity: ΔP ≈ −D·P·Δy.
convexity8.7012Second-order correction — add ½·C·P·Δy² for larger yield moves.
bpv-0.0257Exact price change for +1 bp of yield, per 100 face — repriced, not approximated. Also called DV01; see the DV01/BPV guide.

Sanity check the trio: modified duration × dirty price / 10,000 = 2.4748 × 103.9413 / 10,000 ≈ 0.0257 — the BPV, with the sign telling you the direction.

05Conventions

ConventionValue
pricesper 100 of face value (market quote convention)
settlementas provided (settlementDays=0, no implicit T+2)
ytmcompounded annual, act/act
zero_curvezero rates continuously compounded, act/365
calendarTARGET, unadjusted schedule

Two of these bite in practice. Settlement is taken literally — no implicit T+2, you pass the date the trade actually settles, which makes results reproducible instead of "correct on the day you ran it". And the YTM convention follows your request: it is compounded at the frequency you set and measured with your day_count, so an annual 4% and a semiannual 4% are different yields.

06Flat yield or your own curve

Replace yield_rate with a zero_curve (pillars in years + continuously-compounded zero rates) and the bond is discounted off the curve instead; you provide exactly one of the two. Need the curve itself from market quotes? That is POST /v1/curves/bootstrap. For the risk side of this same response — duration, convexity, BPV in depth — see bond duration, convexity and BPV over HTTP.

Price your own bond. Key in seconds, 500 free calls a month, full request schema in the docs.

Get a free API key

No credit card · schemas and error codes in /docs

Related: Clean vs dirty bond price and accrued interest · DV01 / BPV of a bond via API · Bond duration, convexity and BPV over HTTP