Your organisation's products, as they're sold right now: the terms customers see (cooling-off period, what's included and excluded) and the limits on the cover you can quote for (amounts, ages and terms).
Products come from the current release of each product, so changes you're still working on in the dashboard don't show here until they're published.
List your products
GET
https://subcontext.com/api/v1/products
Try it
Token scopes:
read or write
Every product your organisation makes, in name order, whatever its
state. Check lifecycle_state for the ones on sale (production).
Responses
200 Your products.
| Field | Type | Description |
|---|---|---|
| data required | array of Product |
The products, in name order. |
| data[].id required | string (uuid) |
The product's id. |
| data[].display_id required | string |
The id as Subcontext shows it, |
| data[].slug required | string |
The product's slug, used in addresses such as |
| data[].name required | string |
The product's name, as customers see it. |
| data[].product_type required | string |
What kind of product it is. One of:"term", "decreasing_term", "whole_of_life", "critical_illness", "income_protection", "bundled", "child_cover", "healthcare"
|
| data[].currency_code required | string |
The currency it's priced in (ISO 4217), such as |
| data[].lifecycle_state required | string |
Where the product is in its life. Only "draft", "sandbox", "production", "archived"
|
| data[].cooldown_days required | integer |
The cooling-off period, in days, during which a customer can cancel for a full refund. |
| data[].inclusions required | array of string |
What the product includes, as short sentences for customers. |
| data[].exclusions required | array of string |
What the product doesn't cover, as short sentences for customers. |
| data[].cover_bounds required | CoverBounds |
The limits for a quote across all the product's covers: the lowest
and highest amount, age at the start and term. Each is |
| data[].cover_bounds.sum_assured_min_pence required | integer or null |
The smallest amount of cover, in whole pence (the smallest unit of the product's currency). |
| data[].cover_bounds.sum_assured_max_pence required | integer or null |
The largest amount of cover, in whole pence. |
| data[].cover_bounds.age_min required | integer or null |
The youngest age, in years, at which cover can start. |
| data[].cover_bounds.age_max required | integer or null |
The oldest age at which cover can start. |
| data[].cover_bounds.term_min required | integer or null |
The shortest term, in years. |
| data[].cover_bounds.term_max required | integer or null |
The longest term, in years. |
| data[].covers required | array of Cover |
The covers that make up the product, such as life cover with critical illness cover added. |
| data[].covers[].id required | string (uuid) |
The cover's id. |
| data[].covers[].display_id required | string |
The id as Subcontext shows it, |
| data[].covers[].cover_type required | string |
What the cover pays out for. One of:"life", "critical_illness", "income_protection", "accidental_death", "child_benefit", "healthcare"
|
| data[].covers[].cover_index required | integer |
The cover's position in the product, starting at 0. |
| data[].covers[].sum_assured_min_pence required | integer |
The smallest amount of cover, in whole pence (the smallest unit of the product's currency). For a monthly benefit, the yearly amount. |
| data[].covers[].sum_assured_max_pence required | integer |
The largest amount of cover, in whole pence. |
| data[].covers[].age_at_entry_min required | integer |
The youngest age, in years, at which this cover can start. |
| data[].covers[].age_at_entry_max required | integer |
The oldest age at which this cover can start. |
| data[].covers[].term_years_min required | integer or null |
The shortest term in years, or |
| data[].covers[].term_years_max required | integer or null |
The longest term in years, or |
| data[].covers[].max_age_at_expiry required | integer or null |
The oldest the person can be when the cover ends, if there's a limit. |
| data[].covers[].premium_basis required | string |
Whether the price is fixed for the whole term ( "guaranteed", "reviewable"
|
| data[].covers[].review_period_years required | integer or null |
For reviewable premiums, how often in years the price is reviewed. |
| data[].covers[].minimum_premium_pence required | integer |
The lowest monthly premium, in pence (or the smallest unit of the product's currency). |
| data[].covers[].ci_payout_basis required | string |
For critical illness cover, whether it pays out on top of life cover ( "additional", "accelerated"
|
| data[].covers[].survival_period_days required | integer |
How many days the person must survive after a diagnosis for a critical illness claim. |
| data[].covers[].indexation_method required | string |
How the amount of cover changes over the term. One of:"none", "rpi", "fixed_percent", "decreasing"
|
| data[].covers[].benefit_basis required | string |
Whether the cover pays a lump sum or a monthly benefit. One of:"lump_sum", "monthly_benefit"
|
| data[].covers[].title required | string or null |
The cover's name where its type alone doesn't say which it is, such as one level of a group plan ( |
| data[].covers[].pricing_basis required | string |
How the cover is priced: by underwriting and rate tables ( "rated", "fixed_tiers", "per_member"
|
| data[].covers[].member_premium_pence required | integer or null |
For a |
| data[].covers[].members_factor required | string or null |
For a |
| data[].covers[].opt_in_factor required | string or null |
For a |
{
"data": [
{
"id": "0199a3c2-5d1e-7b4a-9c3f-2e8d4b6a1f07",
"display_id": "prod_0199a3c2-5d1e-7b4a-9c3f-2e8d4b6a1f07",
"slug": "level-term-life",
"name": "Level Term Life",
"product_type": "term",
"currency_code": "GBP",
"lifecycle_state": "production",
"cooldown_days": 30,
"inclusions": [
"Terminal illness benefit, paid early if you're diagnosed with 12 months or less to live"
],
"exclusions": [
"Death caused by a deliberately self-inflicted injury in the first year"
],
"cover_bounds": {
"sum_assured_min_pence": 1000000,
"sum_assured_max_pence": 50000000,
"age_min": 18,
"age_max": 65,
"term_min": 5,
"term_max": 40
},
"covers": [
{
"id": "0199a3c2-5d1e-7b4a-9c3f-2e8d4b6a1f08",
"display_id": "cov_0199a3c2-5d1e-7b4a-9c3f-2e8d4b6a1f08",
"cover_type": "life",
"cover_index": 0,
"sum_assured_min_pence": 1000000,
"sum_assured_max_pence": 50000000,
"age_at_entry_min": 18,
"age_at_entry_max": 65,
"term_years_min": 5,
"term_years_max": 40,
"max_age_at_expiry": 80,
"premium_basis": "guaranteed",
"review_period_years": null,
"minimum_premium_pence": 500,
"ci_payout_basis": "additional",
"survival_period_days": 14,
"indexation_method": "none",
"benefit_basis": "lump_sum",
"title": null,
"pricing_basis": "rated",
"member_premium_pence": null,
"members_factor": null,
"opt_in_factor": null
}
]
}
]
}
401 No token was sent, or it isn't valid because it has expired, was revoked (for example because the application's secret was rotated), or was cut short. Get a new token and try once more.
| Field | Type | Description |
|---|---|---|
| error required | object | |
| error.code required | string |
A short code for the kind of error, such as |
| error.message required | string |
What went wrong and what to do about it, in plain English. |
| error.fields | object |
When the error is about particular inputs, which ones and why,
by name: a nested one with a dot ( |
{
"error": {
"code": "invalid_token",
"message": "The access token has expired. Ask for a new one."
}
}
403 The token can't be used here. It's missing a scope, it was used from the wrong place (a server-only application's token in a browser, or a browser application's token from a server, another website or a request only server-only applications may make), or it wasn't asked for with `resource=https://subcontext.com/api/v1`.
| Field | Type | Description |
|---|---|---|
| error required | object | |
| error.code required | string |
A short code for the kind of error, such as |
| error.message required | string |
What went wrong and what to do about it, in plain English. |
| error.fields | object |
When the error is about particular inputs, which ones and why,
by name: a nested one with a dot ( |
{
"error": {
"code": "forbidden",
"message": "origin 'https://www.example.com' is not allowlisted for this OAuth application"
}
}
Get a product
GET
https://subcontext.com/api/v1/products/{slug}
Try it
Token scopes:
read or write
One of your organisation's products, found by its slug.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| slug required | path | string | The product's slug, shown on its page in the dashboard under Products. |
Responses
200 The product.
| Field | Type | Description |
|---|---|---|
| data required | Product |
A product, with the terms it's sold on now. |
| data.id required | string (uuid) |
The product's id. |
| data.display_id required | string |
The id as Subcontext shows it, |
| data.slug required | string |
The product's slug, used in addresses such as |
| data.name required | string |
The product's name, as customers see it. |
| data.product_type required | string |
What kind of product it is. One of:"term", "decreasing_term", "whole_of_life", "critical_illness", "income_protection", "bundled", "child_cover", "healthcare"
|
| data.currency_code required | string |
The currency it's priced in (ISO 4217), such as |
| data.lifecycle_state required | string |
Where the product is in its life. Only "draft", "sandbox", "production", "archived"
|
| data.cooldown_days required | integer |
The cooling-off period, in days, during which a customer can cancel for a full refund. |
| data.inclusions required | array of string |
What the product includes, as short sentences for customers. |
| data.exclusions required | array of string |
What the product doesn't cover, as short sentences for customers. |
| data.cover_bounds required | CoverBounds |
The limits for a quote across all the product's covers: the lowest
and highest amount, age at the start and term. Each is |
| data.cover_bounds.sum_assured_min_pence required | integer or null |
The smallest amount of cover, in whole pence (the smallest unit of the product's currency). |
| data.cover_bounds.sum_assured_max_pence required | integer or null |
The largest amount of cover, in whole pence. |
| data.cover_bounds.age_min required | integer or null |
The youngest age, in years, at which cover can start. |
| data.cover_bounds.age_max required | integer or null |
The oldest age at which cover can start. |
| data.cover_bounds.term_min required | integer or null |
The shortest term, in years. |
| data.cover_bounds.term_max required | integer or null |
The longest term, in years. |
| data.covers required | array of Cover |
The covers that make up the product, such as life cover with critical illness cover added. |
| data.covers[].id required | string (uuid) |
The cover's id. |
| data.covers[].display_id required | string |
The id as Subcontext shows it, |
| data.covers[].cover_type required | string |
What the cover pays out for. One of:"life", "critical_illness", "income_protection", "accidental_death", "child_benefit", "healthcare"
|
| data.covers[].cover_index required | integer |
The cover's position in the product, starting at 0. |
| data.covers[].sum_assured_min_pence required | integer |
The smallest amount of cover, in whole pence (the smallest unit of the product's currency). For a monthly benefit, the yearly amount. |
| data.covers[].sum_assured_max_pence required | integer |
The largest amount of cover, in whole pence. |
| data.covers[].age_at_entry_min required | integer |
The youngest age, in years, at which this cover can start. |
| data.covers[].age_at_entry_max required | integer |
The oldest age at which this cover can start. |
| data.covers[].term_years_min required | integer or null |
The shortest term in years, or |
| data.covers[].term_years_max required | integer or null |
The longest term in years, or |
| data.covers[].max_age_at_expiry required | integer or null |
The oldest the person can be when the cover ends, if there's a limit. |
| data.covers[].premium_basis required | string |
Whether the price is fixed for the whole term ( "guaranteed", "reviewable"
|
| data.covers[].review_period_years required | integer or null |
For reviewable premiums, how often in years the price is reviewed. |
| data.covers[].minimum_premium_pence required | integer |
The lowest monthly premium, in pence (or the smallest unit of the product's currency). |
| data.covers[].ci_payout_basis required | string |
For critical illness cover, whether it pays out on top of life cover ( "additional", "accelerated"
|
| data.covers[].survival_period_days required | integer |
How many days the person must survive after a diagnosis for a critical illness claim. |
| data.covers[].indexation_method required | string |
How the amount of cover changes over the term. One of:"none", "rpi", "fixed_percent", "decreasing"
|
| data.covers[].benefit_basis required | string |
Whether the cover pays a lump sum or a monthly benefit. One of:"lump_sum", "monthly_benefit"
|
| data.covers[].title required | string or null |
The cover's name where its type alone doesn't say which it is, such as one level of a group plan ( |
| data.covers[].pricing_basis required | string |
How the cover is priced: by underwriting and rate tables ( "rated", "fixed_tiers", "per_member"
|
| data.covers[].member_premium_pence required | integer or null |
For a |
| data.covers[].members_factor required | string or null |
For a |
| data.covers[].opt_in_factor required | string or null |
For a |
{
"data": {
"id": "0199a3c2-5d1e-7b4a-9c3f-2e8d4b6a1f07",
"display_id": "prod_0199a3c2-5d1e-7b4a-9c3f-2e8d4b6a1f07",
"slug": "level-term-life",
"name": "Level Term Life",
"product_type": "term",
"currency_code": "GBP",
"lifecycle_state": "production",
"cooldown_days": 30,
"inclusions": [
"Terminal illness benefit, paid early if you're diagnosed with 12 months or less to live"
],
"exclusions": [
"Death caused by a deliberately self-inflicted injury in the first year"
],
"cover_bounds": {
"sum_assured_min_pence": 1000000,
"sum_assured_max_pence": 50000000,
"age_min": 18,
"age_max": 65,
"term_min": 5,
"term_max": 40
},
"covers": [
{
"id": "0199a3c2-5d1e-7b4a-9c3f-2e8d4b6a1f08",
"display_id": "cov_0199a3c2-5d1e-7b4a-9c3f-2e8d4b6a1f08",
"cover_type": "life",
"cover_index": 0,
"sum_assured_min_pence": 1000000,
"sum_assured_max_pence": 50000000,
"age_at_entry_min": 18,
"age_at_entry_max": 65,
"term_years_min": 5,
"term_years_max": 40,
"max_age_at_expiry": 80,
"premium_basis": "guaranteed",
"review_period_years": null,
"minimum_premium_pence": 500,
"ci_payout_basis": "additional",
"survival_period_days": 14,
"indexation_method": "none",
"benefit_basis": "lump_sum",
"title": null,
"pricing_basis": "rated",
"member_premium_pence": null,
"members_factor": null,
"opt_in_factor": null
}
]
}
}
401 No token was sent, or it isn't valid because it has expired, was revoked (for example because the application's secret was rotated), or was cut short. Get a new token and try once more.
| Field | Type | Description |
|---|---|---|
| error required | object | |
| error.code required | string |
A short code for the kind of error, such as |
| error.message required | string |
What went wrong and what to do about it, in plain English. |
| error.fields | object |
When the error is about particular inputs, which ones and why,
by name: a nested one with a dot ( |
{
"error": {
"code": "invalid_token",
"message": "The access token has expired. Ask for a new one."
}
}
403 The token can't be used here. It's missing a scope, it was used from the wrong place (a server-only application's token in a browser, or a browser application's token from a server, another website or a request only server-only applications may make), or it wasn't asked for with `resource=https://subcontext.com/api/v1`.
| Field | Type | Description |
|---|---|---|
| error required | object | |
| error.code required | string |
A short code for the kind of error, such as |
| error.message required | string |
What went wrong and what to do about it, in plain English. |
| error.fields | object |
When the error is about particular inputs, which ones and why,
by name: a nested one with a dot ( |
{
"error": {
"code": "forbidden",
"message": "origin 'https://www.example.com' is not allowlisted for this OAuth application"
}
}
404 There's no such record in your organisation.
| Field | Type | Description |
|---|---|---|
| error required | object | |
| error.code required | string |
A short code for the kind of error, such as |
| error.message required | string |
What went wrong and what to do about it, in plain English. |
| error.fields | object |
When the error is about particular inputs, which ones and why,
by name: a nested one with a dot ( |
{
"error": {
"code": "not_found",
"message": "Resource not found"
}
}