Schedule of Reductions calculation API
A public, source labeled implementation of the federal Direct Loan Schedule of Reductions calculation. Use it to inspect inputs, replay published scenarios, compare your own implementation, and challenge the math with a citation.
curl https://sor.myproduct.life/api/public/v1/healthThe API is anonymous, requires no key, and returns JSON for every successful response and handled error.
Quickstart
curl -X POST https://sor.myproduct.life/api/public/v1/calculate \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-Request-Id: demo-sor-001" \
-d "$(curl -s https://sor.myproduct.life/api/public/v1/scenarios | jq '.scenarios[0].input')"const scenarios = await fetch("https://sor.myproduct.life/api/public/v1/scenarios")
.then((response) => response.json());
const calculation = await fetch("https://sor.myproduct.life/api/public/v1/calculate", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
"X-Request-Id": "demo-sor-001",
},
body: JSON.stringify(scenarios.scenarios[0].input),
}).then((response) => response.json());
console.log(calculation.data);import requests
base = "https://sor.myproduct.life/api/public/v1"
scenarios = requests.get(f"{base}/scenarios", timeout=20).json()
response = requests.post(
f"{base}/calculate",
json=scenarios["scenarios"][0]["input"],
headers={"X-Request-Id": "demo-sor-001"},
timeout=20,
)
print(response.status_code)
print(response.json()["data"])Developer Tools
Use this as the source contract for tooling, SDK review, and automated checks.
Open Swagger Editor, choose Import URL, and paste the OpenAPI JSON URL.
Import the OpenAPI URL, or run the exported collection from the repo with Newman.
Use this when a response appears wrong and you have a public citation.
https://sor.myproduct.life/api/public/v1/openapi.jsonEndpoint Reference
| Method | Path | Purpose |
|---|---|---|
| GET | /api/public/v1/health | Check liveness, engine version, policy year, and deployed source commit. |
| GET | /api/public/v1/scenarios | Fetch the public parity fixture catalog with inputs, expected outputs, and source IDs. |
| POST | /api/public/v1/calculate | Run the SOR engine against a caller supplied input payload. |
| GET | /api/public/v1/openapi.json | Read the OpenAPI 3.1 contract for tooling and integration review. |
Response Contract
Successful calculations return a `data` block from the shared engine and a `meta` block with `engineVersion`, `policyYear`, `policySnapshotDate`, `sourceCommit`, `policyStatus`, `sourceSet`, `citations`, `computedAt`, and `requestId`.
The live API sets `Cache-Control: no-store` and supports a caller supplied `X-Request-Id` for reproducible issue reports.
Rate Limits And Safety
The public API is free and anonymous with a best effort limit of 30 requests per minute per client fingerprint. The limiter uses a daily salted hash so raw IPs are not stored by the application.
This is an educational and validation tool, not an official ED calculator, legal advice, or an institutional policy substitute.
The SOR API does not calculate NSLDS remaining aggregate limits, lifetime maximum eligibility, Parent PLUS remaining eligibility, or consolidation allocation. Apply those ceilings before relying on a graduate, professional, or Grad PLUS result.
Validation Codes
Source Status
Final regulation or stable public guidance supports the rule.
The behavior is supported by current public guidance, but may change after final federal guidance.
Challenge The Calculation
If a published scenario or API response looks wrong, open a Scenario Challenge with the exact input JSON, observed output, expected output, and a public regulatory citation. Accepted challenges become fixtures first, then code changes.