Developer documentation
Embed the calculator
The simplest option — drop our calculator into your page as an iframe. We serve a chromeless version (no INTEGRIS header or footer) at /calculatorSkinny, so it embeds cleanly into any layout.
<iframe
src="https://www.integris-mgt.com/calculatorSkinny"
width="100%"
height="700"
title="INTEGRIS PPP Calculator"
loading="lazy"
style="border: 0;"
></iframe>About 700 px tall fits most layouts comfortably. The calculator is responsive — give it whatever width you have available.
IPP variant
Append ?plan=ipp to render the IPP-styled embed. The legend reads “IPP” instead of “PPP®”, the age slider is restricted to 40+, and the stat panel reads “Your IPP advantage.”
<iframe
src="https://www.integris-mgt.com/calculatorSkinny?plan=ipp"
width="100%"
height="700"
title="INTEGRIS IPP Calculator"
loading="lazy"
style="border: 0;"
></iframe>Hide our call-to-action
By default the calculator shows an INTEGRIS “Get my personalized illustration” button under the result. If you’d rather add your own call-to-action, append ?cta=off to hide it — the sliders, chart, and result stats stay exactly the same.
<iframe
src="https://www.integris-mgt.com/calculatorSkinny?cta=off"
width="100%"
height="700"
title="INTEGRIS PPP Calculator"
loading="lazy"
style="border: 0;"
></iframe>The parameters compose — e.g. ?plan=ipp&cta=off renders the IPP embed with no INTEGRIS CTA.
Build your own UI with our API
If you want full control over the look and feel, call our projection endpoint directly and render the numbers however you like — your own chart library, a table, a bespoke layout.
Endpoint
POST https://www.integris-mgt.com/api/calculators/pppvsrsp
Content-Type: application/jsonRequest body
All four fields are required and must be numeric. Out-of-range values are silently clamped to the bounds rather than rejected, so the API never refuses a real-looking request — mirror these bounds in your own UI if you want a clean user experience.
| Field | Range (inclusive) | Notes |
|---|---|---|
age | 19 – 65 | Member age in years |
yearsOfService | 0 – 50 | Past T4 employment years to buy back |
currentSalary | 70000 – 500000 | Annual salary in dollars (not $1000s) |
averagePastSalary | 0 – 500000 | Average T4 income over the past service years |
Response
The response is always 53 yearly rows starting at the input age. Most callers want to truncate at the natural drawdown end — the first row after the peak where sPPP hits 0 — so the chart closes cleanly at retirement instead of trailing flat zeros. Take whatever window suits your layout.
{
"sStatus": "success",
"sLabels": ["45 years", "46 years", "47 years", "48 years", "...", "97 years"],
"sPPP": [0, 5234, 11421, 18587, // 53 entries
/* … */],
"sRRSP": [0, 4218, 9106, 14751,
/* … */]
}sLabels— 53 year-of-age strings, starting at the input age ("{n} years").sPPP— projected total inside the pension plan at each of those ages, in dollars.sRRSP— projected total inside an equivalent RRSP at each of those ages, for comparison.
Error responses
- 400 — request body is missing a required field or one of the values is non-numeric. Out-of-range numeric values do not return 400; they get clamped silently.
- 405 — the request method is not
POST. - 500 — engine error. Should not happen in normal use; ping us if you see one.
Example — curl
curl -X POST https://www.integris-mgt.com/api/calculators/pppvsrsp \
-H "Content-Type: application/json" \
-d '{"age":45,"yearsOfService":0,"currentSalary":120000,"averagePastSalary":0}'Example — JavaScript
const res = await fetch('https://www.integris-mgt.com/api/calculators/pppvsrsp', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
age: 45, // 19–65, integer
yearsOfService: 0, // 0–50, integer
currentSalary: 120000, // 70000–500000, dollars (not $1000s)
averagePastSalary: 0, // 0–500000, dollars
}),
});
const { sLabels, sPPP, sRRSP } = await res.json();
// 53 yearly rows starting at the input age. Slice the window you want
// (e.g. the next 25 years of accumulation) and feed it into your chart.Rate limits and caching
Cache aggressively.Responses are fully deterministic — the same input tuple (age, yearsOfService, currentSalary, averagePastSalary) always returns the same 53 rows. If you’re using this from an LLM tool-use loop, cache by a hash of those four values; you almost never need to call twice for the same inputs.
Soft cap: ~10 requests / second per integration.No hard quota right now, but please keep concurrent bursts low so live users don’t hit a cold start while your bulk job is running. We’ll publish a real 429 response if it ever becomes a problem.
Cold start is ~13 seconds, warm calls are ~400 ms. The function caches its formula engine in memory between requests, so the first call after a quiet stretch or after a deploy can stall briefly. Treat one slow first call as normal, not a failure.
Backoff on 5xx.Exponential, max 3 retries. We pre-warm during weekday business hours but transient errors are still possible.
No PII.The four inputs are scalar numbers — never send names, emails, account numbers, or anything that could identify a real person.