SOFR Rate API: Secured Overnight Financing Rate as JSON

SOFR Rate API: Secured Overnight Financing Rate as JSON

You need today’s SOFR inside your app without scraping PDFs or waiting on files. By the end of this article you’ll request the Secured Overnight Financing Rate (symbol: SOFR) as JSON, persist it safely, compute spreads and payments from it, and understand the publication patterns and caching considerations that matter in production.

What SOFR is and when you need it in software

SOFR is the Secured Overnight Financing Rate used across USD loans, securities, and derivatives as a risk-free benchmark. If you build lending, treasury, or analytics workflows, you’ll often align funding curves, price floating-rate products, and reconcile accruals against SOFR. You don’t want to hand-maintain a rate sheet; you want an API that returns the latest SOFR as JSON you can store and use in calculations.

The Interest Rates API delivers SOFR under the symbol code SOFR. You call a REST endpoint with your api_key and get a small, predictable JSON envelope containing the rate. Learn more at interestratesapi.com, and keep the docs handy: docs.

Endpoint to get the latest SOFR print

Use GET /api/v1/latest with symbols=SOFR and an api_key. This returns a JSON payload with a top-level metadata block and a rates object that includes rates.SOFR.

curl "https://interestratesapi.com/api/v1/latest?api_key=YOUR_API_KEY&symbols=SOFR"

That call requests the latest SOFR only. Keep this request focused on the symbol you need; multi-symbol latest responses are available on higher tiers, but for a single symbol this is the simplest and fastest path.

Reading the JSON: fields you’ll actually use

Immediately after the code block above you’ll see the live JSON envelope for the latest request. In that payload:

  • rates.SOFR is the numeric rate for the request’s effective date.
  • date indicates the effective date for the rates in the response. Store this alongside the value for reproducibility.
  • Additional metadata fields (such as success or error descriptions when present) help you confirm whether the payload is valid.

How to interpret the value under rates.SOFR:

  • Calculations: Use the raw numeric value returned by rates.SOFR in math. If you display a percentage to users, multiply by 100 and format accordingly.
  • Effective date: Treat the date from the response as the date the rate applies to. Many downstream systems reconcile by date rather than timestamp; persist that exact string to prevent ambiguity.

One JavaScript example to fetch and store SOFR

Below is a minimal script that fetches SOFR using the same endpoint as the curl request. It validates success, reads the rate, and stores symbol, date, and value.

import fetch from "node-fetch";
import fs from "fs/promises";

const API_KEY = process.env.INTEREST_RATES_API_KEY || "YOUR_API_KEY";
const url = new URL("https://interestratesapi.com/api/v1/latest");
url.searchParams.set("symbols", "SOFR");
url.searchParams.set("api_key", API_KEY);

async function fetchSOFR() {
  const res = await fetch(url.toString(), { method: "GET" });
  if (!res.ok) {
    throw new Error(`HTTP ${res.status}: ${await res.text()}`);
  }
  const json = await res.json();

  // Validate the structure you expect. The latest response family returns a `rates` object.
  if (!json || typeof json !== "object" || !json.rates || json.rates.SOFR == null) {
    throw new Error("Missing SOFR in response payload.");
  }

  const date = json.date || null;       // persist the effective date if present
  const sofr = json.rates.SOFR;         // numeric rate used in calculations

  // Example: persist a log line; replace with your DB insert/upsert keyed by (symbol, date)
  const line = JSON.stringify({ symbol: "SOFR", date, value: sofr, received_at: new Date().toISOString() });
  await fs.appendFile("./sofr.log", line + "\n", "utf8");

  return { date, sofr };
}

fetchSOFR()
  .then(({ date, sofr }) => {
    console.log(`SOFR for ${date || "(no-date)"} = ${sofr}`);
  })
  .catch(err => {
    console.error("SOFR fetch failed:", err);
    process.exitCode = 1;
  });

Computing spreads, floating payments, and accruals from SOFR

Most systems don’t use SOFR in isolation; you’ll compute:

  • Quoted spread: spread = your_rate - sofr. If your_rate is a borrower’s annualized rate, subtract the SOFR value to get an implied spread. For display, convert both to percentages first or format the difference consistently.
  • Monthly payment on a SOFR-based loan: Let principal be P, and let the monthly rate be r_month derived from SOFR plus your margin m. Convert annualized values to a per-month decimal rate before using an amortization formula. For example: - Annualized index-plus-margin: r_annual = sofr + m - Monthly rate: r_month = r_annual / 12 - Standard annuity payment: payment = P * r_month / (1 - (1 + r_month)^(-n_months)) Do not hardcode n_months; source it from your loan schedule and use the SOFR value you just fetched.
  • Daily accruals: For day-count accruals, convert the returned SOFR to a per-day rate per your chosen convention (e.g., divide an annualized decimal by the appropriate day-count base), then multiply by principal and elapsed days. Keep your day-count logic isolated and unit-tested.

Because the API returns a numeric value ready for calculation, keep your code paths unit-safe: store as decimal, format as percent only at presentation boundaries.

Understanding publication cadence, business days, and caching

SOFR is administered and published on a business-day schedule. Your integration should:

  • Poll once per publication cycle rather than intra-day. If your workflow runs nightly, fetch and persist the latest SOFR then.
  • Cache by (symbol, date). Use the response’s effective date to key your storage. This makes backfills and audits straightforward.
  • Handle non-publication days. On weekends or holidays you may get the most recent effective date. Avoid assuming a strictly daily sequence with no gaps.
  • Detect stale data. If you require same-day availability, compare your stored date to the expected business calendar in your region.

To plan for multiple symbols or to coordinate with venues and calendars, visit MCP. For endpoint details beyond the latest route covered here, see the API docs.

Using the convert envelope shown below

Below is a published example for the convert endpoint. It illustrates a different envelope than latest and includes multiple parameters. The example request references SOFR in the from parameter and another benchmark in to; it’s useful when you need to transform or compare across benchmarks and terms. If you simply need the latest SOFR number, stick to GET /api/v1/latest with symbols=SOFR as shown earlier.

{
  "success": true,
  "amount": 500000,
  "term_months": 24,
  "from": {
    "symbol": "SOFR",
    "rate": 4.31,
    "date": "2026-04-19",
    "total_interest": 43100.00,
    "total_payment": 543100.00
  }
}

Key differences to remember:

  • latest returns a rates object that includes rates.SOFR keyed by symbol.
  • convert is a separate route with from, to, and additional arguments such as amount and term_months that are not required for latest.

If you are exploring cross-benchmark comparisons or quoting logic that relies on a transformation between indices, the convert route is the right tool. Otherwise, keep your SOFR fetch minimal with latest.

Plans, auth, and multi-symbol considerations

Authentication is via an api_key query parameter. The Starter plan is $19/mo (1 symbol per latest request, 250 calls, 90-day range) with a 7-day trial. Pro is $49 with multi-symbol latest. If you are requesting multiple benchmarks together (e.g., SOFR, SONIA, ECB prints), do not pass a base parameter such as base=USD alongside them. Stick to symbols in the query, and pick a plan that supports multi-symbol responses.

To try it now, start a free trial and get an API key: Register. You can also explore the homepage for additional benchmarks and routes: interestratesapi.com.

Error handling, missing fields, and resilience

Build a small guardrail layer around your call to latest:

  • Check HTTP status. A non-200 status means you should log, back off, and retry according to your job’s SLA.
  • Check the top-level structure. Ensure the response is JSON and contains a rates object with a numeric SOFR value.
  • Handle success=false and error messages when present. If the payload indicates failure, do not cache it as valid data; route it to an alerting path.
  • Idempotency for storage. Upsert rows keyed by symbol and date. If you re-fetch the same effective date, you will avoid duplicate inserts.
  • Backfill strategy. When your application starts or catches up after downtime, fetch and persist the latest, then reconcile any dates you missed by consulting the docs for historical/time series endpoints.

Data hygiene: units, dates, and timezones

A few conventions keep downstream math predictable:

  • Units: Treat the numeric rate under rates.SOFR as a decimal value for calculation. Only convert to percentage for display.
  • Effective date: Use the date field from the response as the authoritative effective date. Persist it as an ISO date string. Do not coerce it into a localized timestamp unless your system requires it; store the raw date for traceability.
  • Timezone: When you need a timestamp for your own logs, add a received_at field with your server’s UTC timestamp. Keep received_at separate from the effective date provided by the API.
  • Caching: Cache by symbol+date. In memory caches can be keyed the same way. This prevents accidental mixing of rates across days.

Putting it all together: minimal production checklist

Runbook

  • Fetch cadence: once shortly after expected publication on business days.
  • Validation: assert presence and type of rates.SOFR; store symbol, date, value, and received_at.
  • Storage: upsert to a durable store keyed by (symbol, date).
  • Alerting: trigger an alert on HTTP errors, malformed JSON, or missing SOFR. Fall back to the last good value for read-only views while surfacing the alert to ops.
  • Usage: in pricing paths, read the cached value for the most recent effective date; in reporting, use the date explicitly requested by the report.

Example functions you’ll call

  • load_latest_sofr(): fetch from /api/v1/latest, return { date, rate }.
  • monthly_payment(P, r_annual, n): compute payment for amortizing loans by converting r_annual to r_month.
  • spread(my_rate, sofr): return my_rate - sofr with common units.
  • accrue(principal, r_annual, days, day_count_base): derive per-day rate and multiply.

FAQ

How often should I call the latest SOFR endpoint?
Call once per publication cycle on business days. Cache by symbol and date. Avoid intra-day polling loops; they add cost without improving fidelity for end-of-day rates.

What if the response doesn’t include a SOFR value?
Treat that as a validation failure. Do not cache the payload as valid data. Log the full body, alert, and retry with exponential backoff. Keep serving the last good value to read-only screens if appropriate for your users.

Is the returned rate a decimal or percentage?
Use the numeric value in calculations as a decimal. If you display a percentage to users, multiply by 100 and format. Keep one canonical internal representation to avoid unit errors.

Can I request multiple benchmarks together?
Yes on plans that support multi-symbol latest. Use symbols with a comma-separated list. Do not pass a base parameter when you also need benchmarks like SONIA or ECB prints in the same request.

Where can I see other endpoints like historical or time series?
Consult the documentation for routes beyond latest. Your integration can start with latest and expand as your backfill and analytics needs grow.

Ready to integrate SOFR in minutes? Start your 7-day trial, get your API key, and ship the latest-rate fetch with one request: Register. Explore benchmarks and routes anytime on interestratesapi.com.

Ready to get started?

Get your API key and start validating bank data in minutes.

Get API Key