About

REST API POC: POST /api/calculate/mortgage

Single-endpoint proof-of-concept validating the dual-product (REST + MCP) architecture pattern for digitalcalculator.info. POC scope only — full REST surface (per-tool endpoints, auth, pricing tiers) is ADR-pending S142+.

POC scope — not for production multi-endpoint use

This endpoint demonstrates the contract surface and engineering pattern. Only the mortgage calculator is exposed via REST today. Other calculators remain accessible via the MCP server (all 9 tools). Per-key auth, paid tier rate limits, multi-endpoint versioning, and SDKs are gated on the S142+ full REST surface ADR.

Endpoint

  • Method: POST
  • Path: /api/calculate/mortgage
  • Host (POC): assigned at deploy time — check the RestApiPocEndpoint output of the infra/mcp CFN stack after deployment
  • Auth: none (POC). Per-IP rate limit of 100 req / 5 min inherited from the shared WAFv2 rule (SECR-005/006)
  • Throttle: 1.67 rps + burst 50 (global, inherited)
  • API version header: X-API-Version: 0.1.0-poc on every response

Request

The request body is the bare tool input (no envelope wrapper — the route already encodes the tool name). Same input schema as the MCP dc.calculator.mortgage.monthlyPayment tool.

Input schema

Input schema for POST /api/calculate/mortgage
FieldTypeRequiredRangeDescription
principalnumber (USD)yes0 – 100,000,000Loan principal
annualRatePercentnumberyes0 – 30Annual rate as whole-number percent (e.g., 6.5)
termYearsintegeryes1 – 50Loan term in whole years

Sample cURL

bash
curl -X POST https://api.digitalcalculator.info/api/calculate/mortgage \
  -H "Content-Type: application/json" \
  -d '{
    "principal": 300000,
    "annualRatePercent": 6.5,
    "termYears": 30
  }'

Sample request body

json
{
  "principal": 300000,
  "annualRatePercent": 6.5,
  "termYears": 30
}

Response

Same ToolResult<T> envelope as the MCP surface (per ADR-0039 § 3). Field-for-field identical — tool clients can swap transports without re-parsing.

Sample 200 response

json
{
  "result": {
    "monthlyPayment": 1896.20,
    "totalInterest": 382633.47,
    "totalPaid": 682633.47
  },
  "disclaimer": "Estimates only. Not financial, tax, or legal advice. Consult a licensed professional before making decisions based on these calculations.",
  "methodology": {
    "url": "https://www.digitalcalculator.info/mortgage-calculator/",
    "version": "2026-05-09"
  },
  "calculatedAt": "2026-05-27T18:42:11.832Z",
  "engineVersion": "1.0.0"
}

Error responses

Errors follow the standard ToolError envelope — single-nested { "error": { code, message, retriable, field? } }. Status mapping:

  • 400INPUT_VALIDATION or BUSINESS_RULE
  • 405 — non-POST method (POC guard; gateway should only route POST)
  • 413 — request body > 4 KB (SECR-006 byte-cap)
  • 429RATE_LIMIT (WAFv2 per-IP or API Gateway global throttle)
  • 500INTERNAL (logged; report if you see one)

Sample 400 response

json
{
  "error": {
    "code": "INPUT_VALIDATION",
    "message": "Number must be greater than or equal to 1",
    "field": "termYears",
    "retriable": false
  }
}

Architecture — dual-product (REST + MCP)

The same monthlyPayment engine powers three surfaces:

  1. Browser calculator at /mortgage-calculator/ (source-of-truth math; engine lifted to TypeScript per ADR-0039 § 5)
  2. MCP server at dc.calculator.mortgage.monthlyPayment (stdio transport for AI agents; npm: @markcolabs/mcp)
  3. REST POC (this endpoint) for traditional HTTP clients

All three call the same Zod-validated, version-pinned monthlyPayment() function. The engineVersion field in every response confirms math parity. Parity tests at packages/mcp/test/parity/mortgage.test.ts gate the engine against the browser source to the cent.

Why REST AND MCP?

MCP is the right transport for AI agents (Claude Desktop, agentic frameworks, MCP Inspector). REST is the right transport for traditional integrations (server-side jobs, partner systems, browser-side fetch). Same engine, two transports, one source of truth. The REST surface is the “what an enterprise integrator expects to see” companion to the AI-native MCP server.

Path forward

This POC validates the contract pattern. If the architecture proves out (clean integration, no math drift, no operational overhead surprises), the next sprint cycle (S142+) will file an ADR for the full REST surface covering:

  • Per-tool endpoints for the remaining 8 calculators (compound interest, 401(k), Social Security, paycheck, IRA, Roth conversion, RMD, HSA)
  • API key auth + per-key rate limits (MCP-SEC-006 DynamoDB counter pattern)
  • Tier-aware pricing (free + paid throttle classes)
  • Stable versioning policy + deprecation runway
  • OpenAPI / Swagger surface + SDK generation
  • POST /api/v1/... path-prefix migration (POC uses /api/... without a version segment by design — do NOT integrate against the POC URL in production)

Until that ADR ships, treat this endpoint as contract reference only. The POC may be removed or moved without notice.

References