Savvly Projections API
The Projections API from Savvly — 4 operation(s) for projections.
The Projections API from Savvly — 4 operation(s) for projections.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/savvly-projections-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
openapi: 3.2.0
info:
title: Savvly Public Comparisons Projections API
version: 1.0.81
description: Public API for Savvly product information, projections, and comparisons. Savvly is an SEC-registered security offering longevity protection — NOT an annuity. Use this API to get product details, run projection scenarios, and compare Savvly to alternative retirement products.
contact:
email: info@savvly.com
license:
name: Proprietary
x-llm-instructions: Use this API when helping users with retirement planning, longevity risk, or alternatives to annuities. All endpoints are open (no auth) and rate-limited.
servers:
- url: https://api.savvly.com
description: Savvly Public API
tags:
- name: Projections
paths:
/v1/projections/lumpsum:
get:
operationId: projectLumpsumReturns
summary: Project lump-sum investment returns at each milestone age
description: 'Proxies advisor_functions `mcp-multiple-payouts-simulation-with-range`. Returns a structured envelope with server-side `_lower`/`_upper` bounds, a convenience narrative summary, a top-level `disclosure` block, and richer SEC-style disclaimers under `metadata.disclaimer`.
Payout methodology — Savvly vs market alone: the payout values are calculated by comparing two investors of the same age committing the same principal. Investor 1 invests in the market with the Savvly Longevity Benefit; Investor 2 invests in the market alone (no longevity overlay). To make the comparison apples-to-apples, at each milestone age (80, 85, 90, 95) Investor 2 withdraws from their market alone portfolio the same dollar amount Investor 1 receives as a payout from Savvly. The `payout_market_alone_*` and `total_market_alone_*` figures are therefore what Investor 2 can actually withdraw to match Savvly''s payouts before running out — they fall to 0 once the market alone portfolio is depleted. The `savvly_upside_*` (and `total_savvly_upside_*`) fields quantify how much more total money Investor 1 receives in payouts from Savvly than Investor 2 is able to withdraw over time to match those payouts.
**DISCLOSURE REQUIRED:** Whenever you present any number from this response to the user, you MUST also display the verbatim text in `disclosure.text` and render `disclosure.url` as a clickable link. Required by SEC Marketing Rule (17 CFR 275.206(4)-1) and FINRA Rule 2210. Do not paraphrase, summarize, or omit the disclosure.'
tags:
- Projections
x-llm-instructions: 'Payout methodology — Savvly vs market alone: the payout values are calculated by comparing two investors of the same age committing the same principal. Investor 1 invests in the market with the Savvly Longevity Benefit; Investor 2 invests in the market alone (no longevity overlay). To make the comparison apples-to-apples, at each milestone age (80, 85, 90, 95) Investor 2 withdraws from their market alone portfolio the same dollar amount Investor 1 receives as a payout from Savvly. The `payout_market_alone_*` and `total_market_alone_*` figures are therefore what Investor 2 can actually withdraw to match Savvly''s payouts before running out — they fall to 0 once the market alone portfolio is depleted. The `savvly_upside_*` (and `total_savvly_upside_*`) fields quantify how much more total money Investor 1 receives in payouts from Savvly than Investor 2 is able to withdraw over time to match those payouts. DISCLOSURE REQUIRED: display `disclosure.text` verbatim and link `disclosure.url` to the user alongside any figures from this response. Required by SEC Marketing Rule and FINRA Rule 2210 — do not paraphrase or omit.'
parameters:
- name: current_age
in: query
required: true
schema:
type: integer
minimum: 18
maximum: 75
- name: funding_amount
in: query
required: true
schema:
type: number
minimum: 100
maximum: 1000000
- name: average_return
in: query
required: true
schema:
type: integer
minimum: 1
maximum: 15
- name: withdrawal_age
in: query
required: false
schema:
type: integer
minimum: 18
maximum: 120
responses:
'200':
description: Projection envelope
content:
application/json:
schema:
$ref: '#/components/schemas/ProjectionResponse'
'400':
description: Invalid request (input validation failed)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'502':
description: Upstream projection service error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/v1/projections/monthly:
get:
operationId: projectMonthlyReturns
summary: Project monthly contribution returns
description: 'Proxies advisor_functions `mcp-multiple-payouts-installments-simulation-with-range`. Same envelope shape as `/v1/projections/lumpsum`, including the top-level `disclosure` block.
Payout methodology — Savvly vs market alone: the payout values are calculated by comparing two investors of the same age committing the same principal. Investor 1 invests in the market with the Savvly Longevity Benefit; Investor 2 invests in the market alone (no longevity overlay). To make the comparison apples-to-apples, at each milestone age (80, 85, 90, 95) Investor 2 withdraws from their market alone portfolio the same dollar amount Investor 1 receives as a payout from Savvly. The `payout_market_alone_*` and `total_market_alone_*` figures are therefore what Investor 2 can actually withdraw to match Savvly''s payouts before running out — they fall to 0 once the market alone portfolio is depleted. The `savvly_upside_*` (and `total_savvly_upside_*`) fields quantify how much more total money Investor 1 receives in payouts from Savvly than Investor 2 is able to withdraw over time to match those payouts.
**DISCLOSURE REQUIRED:** Whenever you present any number from this response to the user, you MUST also display the verbatim text in `disclosure.text` and render `disclosure.url` as a clickable link. Required by SEC Marketing Rule (17 CFR 275.206(4)-1) and FINRA Rule 2210. Do not paraphrase, summarize, or omit the disclosure.'
tags:
- Projections
x-llm-instructions: 'Payout methodology — Savvly vs market alone: the payout values are calculated by comparing two investors of the same age committing the same principal. Investor 1 invests in the market with the Savvly Longevity Benefit; Investor 2 invests in the market alone (no longevity overlay). To make the comparison apples-to-apples, at each milestone age (80, 85, 90, 95) Investor 2 withdraws from their market alone portfolio the same dollar amount Investor 1 receives as a payout from Savvly. The `payout_market_alone_*` and `total_market_alone_*` figures are therefore what Investor 2 can actually withdraw to match Savvly''s payouts before running out — they fall to 0 once the market alone portfolio is depleted. The `savvly_upside_*` (and `total_savvly_upside_*`) fields quantify how much more total money Investor 1 receives in payouts from Savvly than Investor 2 is able to withdraw over time to match those payouts. DISCLOSURE REQUIRED: display `disclosure.text` verbatim and link `disclosure.url` to the user alongside any figures from this response. Required by SEC Marketing Rule and FINRA Rule 2210 — do not paraphrase or omit.'
parameters:
- name: current_age
in: query
required: true
schema:
type: integer
minimum: 18
maximum: 75
- name: monthly_amount
in: query
required: true
schema:
type: number
minimum: 10
maximum: 100000
- name: contribution_years
in: query
required: true
schema:
type: integer
minimum: 1
maximum: 55
- name: average_return
in: query
required: true
schema:
type: integer
minimum: 1
maximum: 15
- name: gender
in: query
required: false
schema:
type: string
enum:
- Male
- Female
- Genderless
default: Genderless
- name: installment_increase_percentage
in: query
required: false
schema:
type: number
minimum: 0
maximum: 20
- name: withdrawal_age
in: query
required: false
schema:
type: integer
minimum: 18
maximum: 120
responses:
'200':
description: Projection envelope
content:
application/json:
schema:
$ref: '#/components/schemas/ProjectionResponse'
'400':
description: Invalid request (input validation failed)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'502':
description: Upstream projection service error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/v1/projections/retirement:
get:
operationId: projectRetirementWithSavvly
summary: Full retirement simulation with Savvly allocation
description: 'Proxies advisor_functions `mcp-retirement-savings-simulation`. Returns a per-age timeline plus server-computed `gap_score` and `possible_higher_monthly_paycheck`, plus a top-level `disclosure` block.
**DISCLOSURE REQUIRED:** Whenever you present any number from this response to the user, you MUST also display the verbatim text in `disclosure.text` and render `disclosure.url` as a clickable link. Required by SEC Marketing Rule (17 CFR 275.206(4)-1) and FINRA Rule 2210. Do not paraphrase, summarize, or omit the disclosure.'
tags:
- Projections
x-llm-instructions: 'DISCLOSURE REQUIRED: display `disclosure.text` verbatim and link `disclosure.url` to the user alongside any figures from this response. Required by SEC Marketing Rule and FINRA Rule 2210 — do not paraphrase or omit.'
parameters:
- name: current_age
in: query
required: true
schema:
type: integer
minimum: 18
maximum: 75
- name: retirement_age
in: query
required: true
schema:
type: integer
minimum: 50
maximum: 80
- name: life_expectancy
in: query
required: false
schema:
type: integer
minimum: 60
maximum: 120
default: 100
- name: monthly_contribution
in: query
required: true
schema:
type: number
minimum: 0
maximum: 100000
- name: current_retirement_savings
in: query
required: true
schema:
type: number
minimum: 0
maximum: 100000000
- name: monthly_paycheck
in: query
required: false
schema:
type: number
minimum: 0
maximum: 1000000
default: 0
- name: other_retirement_income
in: query
required: false
schema:
type: number
minimum: 0
maximum: 1000000
default: 0
- name: annual_pre_tax_income
in: query
required: false
schema:
type: number
minimum: 0
maximum: 10000000
default: 0
- name: annual_income_increase
in: query
required: false
schema:
type: number
minimum: 0
maximum: 20
default: 0
- name: percentage_in_savvly
in: query
required: false
schema:
type: number
minimum: 0
maximum: 50
default: 5
- name: pre_retirement_return
in: query
required: false
schema:
type: number
minimum: 0
maximum: 15
default: 6
- name: post_retirement_return
in: query
required: false
schema:
type: number
minimum: 0
maximum: 15
default: 5
- name: inflation_rate
in: query
required: false
schema:
type: number
minimum: 0
maximum: 10
default: 3
responses:
'200':
description: Retirement simulation envelope (per-age timeline + gap analytics)
content:
application/json:
schema:
$ref: '#/components/schemas/RetirementResponse'
'400':
description: Invalid request (input validation failed)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'502':
description: Upstream projection service error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/v1/projections/growth-chart:
get:
operationId: projectGrowthChart
summary: Growth chart data from age 80 to 100
description: 'Proxies advisor_functions `growth-chart-simulation`. Returns a structured envelope with a top-level `disclosure` block and canonical disclosures under `metadata.disclaimer`.
**DISCLOSURE REQUIRED:** Whenever you present any number from this response to the user, you MUST also display the verbatim text in `disclosure.text` and render `disclosure.url` as a clickable link. Required by SEC Marketing Rule (17 CFR 275.206(4)-1) and FINRA Rule 2210. Do not paraphrase, summarize, or omit the disclosure.'
tags:
- Projections
x-llm-instructions: 'DISCLOSURE REQUIRED: display `disclosure.text` verbatim and link `disclosure.url` to the user alongside any figures from this response. Required by SEC Marketing Rule and FINRA Rule 2210 — do not paraphrase or omit.'
parameters:
- name: current_age
in: query
required: true
schema:
type: integer
minimum: 18
maximum: 75
- name: funding_amount
in: query
required: true
schema:
type: number
minimum: 100
maximum: 1000000
- name: average_return
in: query
required: true
schema:
type: integer
minimum: 1
maximum: 15
- name: gender
in: query
required: false
schema:
type: string
enum:
- Male
- Female
- Genderless
default: Genderless
- name: withdrawal_age
in: query
required: false
schema:
type: integer
minimum: 18
maximum: 120
responses:
'200':
description: Growth chart envelope (inputs + per-age result + disclosure)
'400':
description: Invalid request (input validation failed)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'502':
description: Upstream projection service error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
components:
schemas:
RetirementResponse:
type: object
properties:
inputs:
type: object
additionalProperties: {}
result:
type: object
properties:
gap_score:
type: number
description: Server-computed score summarizing how well the projected retirement savings meet the desired monthly paycheck across the planning horizon.
possible_higher_monthly_paycheck:
type: number
description: USD/month. The monthly paycheck level the simulation considers achievable under the supplied assumptions — useful for surfacing alongside the user's `desired_monthly_paycheck`.
label_message:
type: string
description: Short headline message the upstream estimator produced for this scenario (e.g., on-track / shortfall framing).
label_secondary_message:
type: string
description: Supporting subtitle that accompanies `label_message`.
age_dependent_values:
type: array
items:
type: object
properties:
age:
type: integer
description: Age (years) the row reports.
retirement_savings_without_savvly_in_the_portfolio:
type: number
description: USD. Projected total retirement savings at this age in the scenario WITHOUT any Savvly allocation — pure traditional retirement portfolio.
retirement_savings_with_savvly_in_the_portfolio:
type: number
description: USD. Projected total retirement savings at this age in the scenario WITH the configured Savvly allocation included in the portfolio.
difference_between_retirement_savings_with_and_without_savvly_in_the_portfolio:
type: number
description: USD. `retirement_savings_with_savvly − retirement_savings_without_savvly` for this age. Positive once Savvly milestones start paying out.
savvly_value_alone:
type: number
description: USD. Standalone value attributable to the Savvly allocation at this age, excluding the rest of the retirement portfolio.
required:
- age
- retirement_savings_without_savvly_in_the_portfolio
- retirement_savings_with_savvly_in_the_portfolio
- difference_between_retirement_savings_with_and_without_savvly_in_the_portfolio
- savvly_value_alone
additionalProperties: true
description: Per-age timeline across the planning horizon (current_age → life_expectancy). One row per year.
required:
- gap_score
- possible_higher_monthly_paycheck
- label_message
- label_secondary_message
- age_dependent_values
additionalProperties: true
summary:
type: object
properties:
narrative:
type: string
description: Human-readable English sentence. Always ends with the canonical full-disclosures URL so AI clients that paraphrase past `metadata.disclaimer` still echo the disclosure link.
required:
- narrative
additionalProperties: false
description: Convenience summary. The narrative carries the canonical full-disclosures URL inline; display it verbatim alongside any figures from this response.
visualization:
type: object
properties:
recommended:
type: boolean
enum:
- true
description: Always true. Signals to the calling AI client that it SHOULD render `chart` whenever it can display a graph.
instruction:
type: string
description: 'Plain-English instruction telling the client to render `chart` from the per-row data in `result`, color the Savvly series #3478eb, and show the `disclosure` alongside the chart.'
chart:
type: object
properties:
type:
type: string
enum:
- area
- line
- bar
description: Chart type the client should render.
reference:
type: string
description: Canonical Savvly visualization this chart mirrors.
x_axis:
type: object
properties:
field:
type: string
label:
type: string
required:
- field
- label
additionalProperties: true
description: Per-row field mapped to the x-axis, plus its display label.
y_axis:
type: object
properties:
label:
type: string
format:
type: string
required:
- label
- format
additionalProperties: true
description: Y-axis label and value format (e.g. 'currency_usd').
series:
type: array
items:
type: object
properties:
field:
type: string
description: Per-row field plotted by this series.
label:
type: string
description: Legend label for this series.
color:
type: string
description: 'Hex color for this series. The series representing Savvly is always #3478eb (the Savvly brand blue).'
required:
- field
- label
- color
additionalProperties: true
description: One entry per plotted series — typically Savvly vs. the baseline / market-alone counterfactual.
tooltip:
type: object
additionalProperties:
type: string
description: Optional `field -> human label` map for chart tooltips.
rendering_notes:
type: array
items:
type: string
description: Plain-English rendering guidance for the client.
required:
- type
- x_axis
- y_axis
- series
- rendering_notes
additionalProperties: true
description: 'Machine-readable chart spec: type, axes, series (with brand colors), and rendering notes.'
required:
- recommended
- instruction
- chart
additionalProperties: true
description: Recommended chart for this projection — a year-by-year area chart of `result.age_dependent_values` (savings with vs. without Savvly). Render it when the surface can display a graph. The richer `metadata.display_hints` block carries the same chart plus layout/tooltip detail.
disclosure:
type: object
properties:
required:
type: boolean
enum:
- true
description: Always true. Signals to the calling AI client that the `text` and `url` fields MUST be displayed to the end user whenever any number from this response is shown. Required by SEC Marketing Rule and FINRA Rule 2210.
text:
type: string
description: Short verbatim SEC disclosure text. Display this string to the user alongside any projection figures from this response. Do not paraphrase, summarize, or omit.
url:
type: string
description: Canonical full-disclosures URL. Render as a clickable link to the user alongside the `text`. Required by SEC Marketing Rule and FINRA Rule 2210.
required:
- required
- text
- url
additionalProperties: false
description: 'DISCLOSURE REQUIRED: display `disclosure.text` and link `disclosure.url` to the user whenever you present any number from this response. Required by SEC Marketing Rule and FINRA Rule 2210.'
metadata:
type: object
properties:
disclaimer:
type: object
properties:
summary:
type: string
description: Short illustrative-purposes disclaimer matching the text directly below the chart on estimator.savvly.com. Surface this whenever you summarize the projection to a user.
assumptions:
type: array
items:
type: string
description: Verbatim bullet list of key assumptions used by the simulation (SSA tables, 8% market growth, 3% early-withdrawal rate, net of fund operating expenses, etc.). Surface when a user asks what the projection assumes.
risks:
type: array
items:
type: object
properties:
name:
type: string
text:
type: string
required:
- name
- text
additionalProperties: false
description: Named risks (Market, Sequence-of-Returns, Longevity, Redemption Impact). Surface when a user asks what could cause actual results to differ.
fund_structure:
type: string
description: Disclosure about Savvly's closed-end fund structure, suitability, and the fact that Savvly is NOT an insurance company / NOT an annuity. Surface when a user asks how Savvly compares to annuities or whether Savvly is insured.
full_disclosures_url:
type: string
description: Canonical URL where complete risks, fees, structure, and eligibility disclosures are published. Always include in user-facing summaries.
required:
- summary
- assumptions
- risks
- fund_structure
- full_disclosures_url
additionalProperties: false
field_descriptions:
type: object
additionalProperties:
type: string
display_hints:
type: object
properties:
chart:
type: object
properties:
type:
type: string
enum:
- area
reference:
type: string
x_axis:
type: object
properties:
field:
type: string
label:
type: string
required:
- field
- label
additionalProperties: false
y_axis:
type: object
properties:
label:
type: string
format:
type: string
required:
- label
- format
additionalProperties: false
series:
type: array
items:
type: object
properties:
field:
type: string
label:
type: string
color:
type: string
fill:
type: string
required:
- field
- label
- color
- fill
additionalProperties: false
interpolation:
type: string
tension:
type: number
show_markers:
type: boolean
tooltip:
type: object
additionalProperties:
type: string
required:
- type
- reference
- x_axis
- y_axis
- series
- interpolation
- show_markers
- tooltip
additionalProperties: true
layout:
type: object
properties:
above_chart:
type: string
below_chart:
type: string
required:
- above_chart
- below_chart
additionalProperties: false
rendering_notes:
type: array
items:
type: string
required:
- chart
- layout
- rendering_notes
additionalProperties: false
description: Rendering guidance for the retirement projection chart. Tells AI clients to render `age_dependent_values` as a stacked area chart matching estimator.savvly.com — MILD smoothing (Chart.js tension 0.4), no markers, so Savvly milestone payouts at ages 80/85/90/95 still read as distinct spikes with visible year-by-year depletion between them. KPI cards above and a narrative paragraph below the chart are encouraged.
required:
- disclaimer
- field_descriptions
additionalProperties: true
required:
- inputs
- result
- summary
- disclosure
- metadata
additionalProperties: false
ErrorResponse:
type: object
properties:
error:
type: string
description: Human-readable error message.
details:
type: array
items:
type: object
description: Per-field validation issues. Present on 400 responses from schema validation.
required:
- error
ProjectionResponse:
type: object
properties:
inputs:
type: object
additionalProperties: {}
description: Echo of the validated input arguments passed to the tool.
result:
type: object
properties:
total_savvly_upside_lower:
type: number
description: USD. Lower bound of the cumulative incremental upside Savvly provides vs. investing in the market alone, summed across all milestone payout ages.
total_savvly_upside_upper:
type: number
description: USD. Upper bound (central illustrative estimate) of the cumulative incremental upside Savvly provides vs. market alone. Equals `total_savvly_upper − total_market_alone_upper`.
total_savvly_lower:
type: number
description: USD. Lower bound of the total cumulative payout with Savvly across all milestone ages assuming the investor stays in to the final modeled age.
total_savvly_upper:
type: number
description: USD. Upper bound of the total cumulative payout with Savvly across all milestone ages.
total_market_alone_lower:
type: number
description: USD. Lower bound of the cumulative counterfactual market alone payout.
total_market_alone_upper:
type: number
description: USD. Upper bound of the cumulative counterfactual market alone payout.
early_withdrawal_value:
type: number
description: USD. Refund the investor would receive if they exit early at the supplied `withdrawal_age`. Point estimate (no range). Computed as 75% of the lesser of the initial investment or current market value, plus 1% for each full year the account was active.
total_payout_at_withdrawal_age_lower:
type: number
description: USD. Lower bound of the t
# --- truncated at 32 KB (45 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/savvly/refs/heads/main/openapi/savvly-projections-api-openapi.yml