Picwell Commercial API
This document provides general guidance to developers using our APIs on matters of technical support and infrastructure, and complements the Picwell API specification provided.
Infrastructure
Environments
Picwell operates two distinct and isolated environments on behalf of its clients.
User Acceptance Testing
Our User Acceptance Testing (UAT) environment is a shared testing environment between Picwell and a client. New features and functionality are regularly released into UAT for preview by our clients. Pending their validation, they are released into Production.
Our UAT environment is accessible at https://uat-api.picwell.net/
Production
Our Production environment is our live environment, geared for serving live traffic from our clients. New features and functionality are only deployed here after clearing UAT preview.
Our Production environment is accessible at https://api.picwell.net/
Change management
- Changes to Picwell's APIs are first previewed in our UAT environment.
- Changes to UAT may occur as frequently as necessary to support our internal development and serve our clients.
- Pending client validation, new features are eligible to be enabled in production.
User management
Demo/Sandbox Clients in UAT
- Each demo client has their own set of credentials for API access.
- Demo clients share a common set of test models and resources where data may be commingled.
- ex. A household created in UAT for demo-client-a may also be accessible by demo-client-b
Clients in UAT/PROD
- Full (non-demo) clients always have their own set of credentials for API access.
- Credentials across environments (ex. UAT/PROD) will always be unique.
- ex. A given client's credentials for UAT will be different from their credentials in PROD
- Clients in UAT and PROD are independent of one another.
- ex. A household in UAT will not appear in PROD
- ex. Plans available in UAT may not be the same plans available in PROD
Request for Access
If you are interested in access to our UAT environment, please contact your Picwell rep for more information.
Security
Picwell is committed to securely managing data collected through our clients. Our broad security posture includes:
- Reduction of user data surface area by:
- Minimizing the amount of PHI collected from customers
- Leveraging machine generated, unique identifiers when possible
- Encryption of all data in-flight and at-rest.
- Firewalled access to Picwell data infrastructure.
Keep your keys safe
Your secret API key can be used to make any API call on behalf of your account, Use the following best practices to keep your keys safe:
- Grant access only to those who need it.
- Ensure the key is kept out of version control systems.
- Ensure the key is not kept in plain text.
- Don't embed your secret API key in mobile applications or other places from where the key could be extracted.
Sanitized User Input
If requested, Picwell will sanitize all user input returned by the API, making it safe to insert into an HTML page without modification. This is not a security feature (API client software is responsible for safely handling data), but is offered as a convenience for our customers.
Authentication
Authentication is required for all but the /auth/
endpoint and is
handled using session tokens. To reach an authenticated endpoint,
provide a Picwell-Auth-Token
header in your request.
To create a session, log in using the following route:
POST /auth/
Create a new session
Body parameter
{
"username": "picwell",
"password": "abcabc123123"
}
Parameters
Parameter | In | Type | Required | Description |
---|---|---|---|---|
body | body | Authentication Request | true | Authentication body |
Example responses
201 Response
{
"auth_token": "aab82ec6-320f-4fb7-88a8-00bd0d002be0"
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
201 | Created | Session created | Authentication Response |
400 | Bad Request | Bad request | None |
401 | Unauthorized | Bad auth | None |
API Versioning
With no version specified:
$ curl https://uat-api.picwell.net/healthcheck/ -I
HTTP/1.1 200 OK
X-Picwell-Media-Type: picwell.v1
Specifying a version:
$ curl https://uat-api.picwell.net/healthcheck/ -I \
-H "Accept: application/vnd.picwell.v2+json"
HTTP/1.1 200 OK
X-Picwell-Media-Type: picwell.v2; format=json
The Picwell API uses custom media types to let consumers specify the version of the API they wish to consume.
All Picwell media types look like this:
application/vnd.picwell[.version][+json]
The most basic media types the API supports are:
application/json
application/vnd.picwell+json
Neither of these specify a version, so the result will always be the same: the current lowest version for that endpoint.
Any request that does not specify a media type, specifies an invalid media type, or specifies the wildcard type */*
will also receive the current lowest version.
A version can be specified as follows:
application/vnd.picwell.v2+json
The current version is also included in every resonse's headers, as the X-Picwell-Media-Type
header.
Current Versions
Version v1
(default)
The current default version. If no version is specified, this is the version in use.
Version v2
Introduced January 2016:
- Breaking change:
/recommendations
endpoint returns aRecommendationSet
instead of a list ofRecommendation
s.
Version v3
- Replaced
enrolled_in
field expected inHousehold
withenrollment
which now expects anEnrollment
object - Replaced
spending_account
field expected inHousehold
withspending_accounts
which now takes a list ofSpendingAccounts
Version v4
Introduced August 2017:
- Added an optional field to the plan when getting recommendations:
coverage_tier
. Ifcoverage_tier
is not specified on a plan with a recommnedation request then it is calculated based on household members.
Version v5
Introduced March 2018:
- Ability to retrieve
HSARecommendation
object. - Ability to retrieve
HSAForecast
object for HSA long-term forecasts. - Accept new fields in SpendingAccount for HSA-related requests;
employer_contribution_limit
andemployer_percentage_contribution
Migration from v4
:
- Ensure all requests to Picwell API are now sent with the
Accept: application/vnd.picwell.v5+json
header. - Ensure
SpendingAccount
objects oftype=hsa
inHousehold
s are sent withemployer_contribution_limit
and/oremployer_percentage_contribution
to utilize HSA recommendation and forecasting capabilities.
Compression
Picwell employs GZIP compression on HTTP responses to reduce the byte-size of data transferred between our servers and yours. This compression is activated when the response payload is optimal size to benefit from compression.
If supplied with the standard Accept-Encoding
HTTP header, we respond with
GZIP compressed payloads as well as the Content-Encoding
HTTP header. Most
web development frameworks can incorporate HTTP compression easily (e.g.
.NET)
Households
Methods allow for operations on Objects, and typically generate Object References as side effects. Picwell exposes API endpoints that conform to RESTful semantics.
Create a new household (v1)
Example Request:
POST /client_name/household/ HTTP/1.1
Host: uat-api.picwell.net
Content-Type: application/json
Accept: application/vnd.picwell.v1+json
Picwell-Auth-Token: <your-auth-token>
Example Request body:
{
"external_id": "XYZ_789",
"enrollment": null,
"zip_code_3": "117",
"version": 2016,
"survey": [
{
"answer": "very_important",
"question_id": "1"
},
{
"answer": "gt_5",
"question_id": "2"
},
{
"answer": "no",
"question_id": "3"
},
{
"answer": "100_150",
"question_id": "4"
},
{
"answer": "plan_b",
"question_id": "5"
},
{
"answer": "plan_b",
"question_id": "6"
}
],
"members": [
{
"external_id": "ABC_123",
"gender": "male",
"age": 34,
"parent": true,
"dependant": false,
"policyholder": true,
"uses_tobacco": false,
"prescriptions": [
{
"ndc": "00093738598",
"frequency": 30,
"quantity": 30
},
{
"ndc": "63304009919",
"frequency": 30,
"quantity": 9
}
]
},
{
"external_id": "CDE_234",
"gender": "female",
"age": 37,
"parent": true,
"dependant": false,
"policyholder": false,
"uses_tobacco": false,
"prescriptions": [
{
"ndc": "68462010810",
"frequency": 30,
"quantity": 360
},
{
"ndc": "00049233045",
"frequency": 30,
"quantity": 6
}
]
},
{
"external_id": "DEF_456",
"gender": "male",
"age": 9,
"parent": false,
"dependant": true,
"policyholder": false,
"uses_tobacco": false,
"prescriptions": []
}
],
"income": 75000,
"spending_account": {
"employee_contribution": 234,
"employer_contribution": 500,
"type": "hsa"
}
}
Example response body:
{
"id": "<target-household-id>",
"version": 2016
}
Establish a household (for downstream reference in recommendation request).
HTTP Method | POST |
Endpoint | /client_name/household/ |
Headers | Picwell-Auth-Token: {AuthenticationReference.auth_token}, Accept: application/vnd.picwell.v1+json |
Request Body | Household |
Response Body | HouseholdReference |
Discussion
- When creating a
Household
with anexternal_id
, if anotherHousehold
with thatexternal_id
already exists, the API will returnHTTP 400 Bad Request
.
Create a new household (v3)
Example Request:
POST /client_name/household/ HTTP/1.1
Host: uat-api.picwell.net
Content-Type: application/json
Accept: application/vnd.picwell.v3+json
Picwell-Auth-Token: <your-auth-token>
Example Request body:
{
"external_id": "XYZ_789",
"enrollment": {},
"zip_code_3": "117",
"version": 2016,
"survey": [
{
"answer": "very_important",
"question_id": "1"
},
{
"answer": "gt_5",
"question_id": "2"
},
{
"answer": "no",
"question_id": "3"
},
{
"answer": "100_150",
"question_id": "4"
},
{
"answer": "plan_b",
"question_id": "5"
},
{
"answer": "plan_b",
"question_id": "6"
}
],
"members": [
{
"external_id": "ABC_123",
"gender": "male",
"age": 34,
"parent": true,
"dependant": false,
"policyholder": true,
"uses_tobacco": false,
"prescriptions": [
{
"ndc": "00093738598",
"frequency": 30,
"quantity": 30
},
{
"ndc": "63304009919",
"frequency": 30,
"quantity": 9
}
]
},
{
"external_id": "CDE_234",
"gender": "female",
"age": 37,
"parent": true,
"dependant": false,
"policyholder": false,
"uses_tobacco": false,
"prescriptions": [
{
"ndc": "68462010810",
"frequency": 30,
"quantity": 360
},
{
"ndc": "00049233045",
"frequency": 30,
"quantity": 6
}
]
},
{
"external_id": "DEF_456",
"gender": "male",
"age": 9,
"parent": false,
"dependant": true,
"policyholder": false,
"uses_tobacco": false,
"prescriptions": []
}
],
"income": 75000,
"spending_accounts": [
{
"employee_contribution": 234,
"employer_contribution": 500,
"type": "hsa"
}
]
}
Example response body:
{
"id": "<target-household-id>",
"version": 2016
}
Establish a household (for downstream reference in recommendation request).
HTTP Method | POST |
Endpoint | /client_name/household/ |
Headers | Picwell-Auth-Token: {AuthenticationReference.auth_token}, Accept: application/vnd.picwell.v3+json |
Request Body | Household |
Response Body | HouseholdReference |
Discussion
- When creating a
Household
with anexternal_id
, if anotherHousehold
with thatexternal_id
already exists, the API will returnHTTP 400 Bad Request
.
New Household Version
DEPRECATED An upcoming release (December 2024) will continue to support this endpoint, but multiple versions of a household will not be supported. This endpoint will persist until the next major version, but will be an alias to Update household, always updating the same household record, with no support for mulitple versions of the household.
This endpoint may be removed in a future version. Please convert any calls to this endpoint to use Update Household instead.
Example request:
POST /client_name/household/<target-household-id>/ HTTP/1.1
Host: uat-api.picwell.net
Content-Type: application/json
Picwell-Auth-Token: <your-auth-token>
Example request body:
{
"external_id": "XYZ_789",
"enrollment": null,
"zip_code_3": "117",
"version": 2017,
"survey": [
{
"answer": "very_important",
"question_id": "1"
},
{
"answer": "gt_5",
"question_id": "2"
},
{
"answer": "no",
"question_id": "3"
},
{
"answer": "100_150",
"question_id": "4"
},
{
"answer": "plan_b",
"question_id": "5"
},
{
"answer": "plan_b",
"question_id": "6"
}
],
"members": [
{
"external_id": "ABC_123",
"gender": "male",
"age": 35,
"parent": true,
"dependant": false,
"policyholder": true,
"uses_tobacco": false,
"prescriptions": [
{
"ndc": "00093738598",
"frequency": 30,
"quantity": 30
},
{
"ndc": "63304009919",
"frequency": 30,
"quantity": 9
}
]
},
{
"external_id": "CDE_234",
"gender": "female",
"age": 38,
"parent": true,
"dependant": false,
"policyholder": false,
"uses_tobacco": false,
"prescriptions": [
{
"ndc": "68462010810",
"frequency": 30,
"quantity": 360
},
{
"ndc": "00049233045",
"frequency": 30,
"quantity": 6
}
]
},
{
"external_id": "DEF_456",
"gender": "male",
"age": 10,
"parent": false,
"dependant": true,
"policyholder": false,
"uses_tobacco": false,
"prescriptions": []
}
],
"income": 75000,
"spending_account": {
"employee_contribution": 234,
"employer_contribution": 500,
"type": "hsa"
}
}
Example response body:
{
"id": "<target-household-id>",
"version": 2017
}
Create a new version of a previously created household.
HTTP Method | POST |
Endpoint | /client_name/household/{Household.id}/ |
Headers | Picwell-Auth-Token: {Authentication.auth_token} |
Request Body | Household |
Response Body | HouseholdReference |
Discussion
When creating a Household
with an external id, if another Household
with
that external id already exists, the API will return HTTP 400 Bad Request
.
Get Household
Example request:
GET /client_name/household/<target-household-id>/ HTTP/1.1
Host: uat-api.picwell.net
Content-Type: application/json
Picwell-Auth-Token: <your-auth-token>
Example response body:
{
"external_id": "XYZ_789",
"enrollment": null,
"zip_code_3": "456",
"version": 2017,
"survey": [
{
"answer": "very_important",
"question_id": "1"
},
{
"answer": "gt_5",
"question_id": "2"
},
{
"answer": "no",
"question_id": "3"
},
{
"answer": "100_150",
"question_id": "4"
},
{
"answer": "plan_b",
"question_id": "5"
},
{
"answer": "plan_b",
"question_id": "6"
}
],
"members": [
{
"prescriptions": [
{
"ndc": "00093738598",
"frequency": 30,
"quantity": 30
},
{
"ndc": "63304009919",
"frequency": 30,
"quantity": 9
}
],
"parent": true,
"gender": "male",
"age": 34,
"uses_tobacco": false,
"dependant": false,
"policyholder": true,
"external_id": "ABC_123"
},
{
"prescriptions": [
{
"ndc": "68462010810",
"frequency": 30,
"quantity": 360
},
{
"ndc": "00049233045",
"frequency": 30,
"quantity": 6
}
],
"parent": true,
"gender": "female",
"age": 37,
"uses_tobacco": false,
"dependant": false,
"policyholder": false,
"external_id": "CDE_234"
},
{
"prescriptions": [],
"parent": false,
"gender": "male",
"age": 9,
"uses_tobacco": false,
"dependant": true,
"policyholder": false,
"external_id": "DEF_456"
}
],
"income": 75000,
"spending_account": {
"employee_contribution": 234,
"employer_contribution": 500,
"type": "hsa"
}
}
Get the Household
record.
HTTP Method | GET |
Endpoint | /client_name/household/{Household.id}/ |
Headers | Picwell-Auth-Token: {Authentication.auth_token} |
Response Body | Household |
Get Household (versioned) -- DEPRECATED
DEPRECATED
An upcoming release (December 2024) will continue to support this endpoint and the version
field,
but multiple versions of a household will not be supported or saved. The response will
contain a single record reflecting the most recently saved household data.
This endpoint may be removed in a future version. Please convert any calls to this endpoint to use Get Household instead.
Example request:
GET /client_name/household/<target-household-id>/?version=2016 HTTP/1.1
Host: uat-api.picwell.net
Content-Type: application/json
Picwell-Auth-Token: <your-auth-token>
Example response body:
{
"external_id": "XYZ_789",
"enrollment": null,
"zip_code_3": "117",
"version": 2016,
"survey": [
{
"answer": "very_important",
"question_id": "1"
},
{
"answer": "gt_5",
"question_id": "2"
},
{
"answer": "no",
"question_id": "3"
},
{
"answer": "100_150",
"question_id": "4"
},
{
"answer": "plan_b",
"question_id": "5"
},
{
"answer": "plan_b",
"question_id": "6"
}
],
"members": [
{
"prescriptions": [
{
"ndc": "00093738598",
"frequency": 30,
"quantity": 30
},
{
"ndc": "63304009919",
"frequency": 30,
"quantity": 9
}
],
"parent": true,
"gender": "male",
"age": 34,
"uses_tobacco": false,
"dependant": false,
"policyholder": true,
"external_id": "ABC_123"
},
{
"prescriptions": [
{
"ndc": "68462010810",
"frequency": 30,
"quantity": 360
},
{
"ndc": "00049233045",
"frequency": 30,
"quantity": 6
}
],
"parent": true,
"gender": "female",
"age": 37,
"uses_tobacco": false,
"dependant": false,
"policyholder": false,
"external_id": "CDE_234"
},
{
"prescriptions": [],
"parent": false,
"gender": "male",
"age": 9,
"uses_tobacco": false,
"dependant": true,
"policyholder": false,
"external_id": "DEF_456"
}
],
"income": 75000,
"spending_account": {
"employee_contribution": 234,
"employer_contribution": 500,
"type": "hsa"
}
}
Get a specific version of a specified Household
.
HTTP Method | GET |
Endpoint | /client_name/household/{Household.id}/?version={v} |
Headers | Picwell-Auth-Token: {Authentication.auth_token} |
Response Body | Household with {Household.version} = v |
Get Household (all versions) -- DEPRECATED
DEPRECATED
An upcoming release (December 2024) will continue to support this endpoint and the version
field,
but multiple versions of a household will not be supported or saved. The response array will
contain a single record reflecting the most recently saved household data.
This endpoint may be removed in a future version. Please convert any calls to this endpoint to use Get Household instead.
Example request:
GET /client_name/household/<target-household-id>/?version=all HTTP/1.1
Host: uat-api.picwell.net
Content-Type: application/json
Picwell-Auth-Token: <your-auth-token>
Example response body:
[
{
"external_id": "XYZ_789",
"enrollment": null,
"zip_code_3": "117",
"version": 2017,
"survey": [
{
"answer": "very_important",
"question_id": "1"
},
{
"answer": "gt_5",
"question_id": "2"
},
{
"answer": "no",
"question_id": "3"
},
{
"answer": "100_150",
"question_id": "4"
},
{
"answer": "plan_b",
"question_id": "5"
},
{
"answer": "plan_b",
"question_id": "6"
}
],
"members": [
{
"prescriptions": [
{
"ndc": "00093738598",
"frequency": 30,
"quantity": 30
},
{
"ndc": "63304009919",
"frequency": 30,
"quantity": 9
}
],
"parent": true,
"gender": "male",
"age": 34,
"uses_tobacco": false,
"dependant": false,
"policyholder": true,
"external_id": "ABC_123"
},
{
"prescriptions": [
{
"ndc": "68462010810",
"frequency": 30,
"quantity": 360
},
{
"ndc": "00049233045",
"frequency": 30,
"quantity": 6
}
],
"parent": true,
"gender": "female",
"age": 37,
"uses_tobacco": false,
"dependant": false,
"policyholder": false,
"external_id": "CDE_234"
},
{
"prescriptions": [],
"parent": false,
"gender": "male",
"age": 9,
"uses_tobacco": false,
"dependant": true,
"policyholder": false,
"external_id": "DEF_456"
}
],
"income": 75000,
"spending_account": {
"employee_contribution": 234,
"employer_contribution": 500,
"type": "hsa"
}
}
]
Get all versions of a specified Household
.
HTTP Method | GET |
Endpoint | /household/{Household.id}/?version=all |
Headers | Picwell-Auth-Token: {Authentication.auth_token} |
Response Body | list:Household |
Get Household by external id (all versions)
DEPRECATED
An upcoming release (December 2024) will continue to support this endpoint and the version
field,
but multiple versions of a household will not be supported or saved. The response array will
contain a single record reflecting the most recently saved household data.
This endpoint may be removed in a future version. Please convert any calls to this endpoint to use Get Household instead.
Example request:
GET /client_name/household/<target-household-id>/?external_id=XYZ_789 HTTP/1.1
Host: uat-api.picwell.net
Content-Type: application/json
Picwell-Auth-Token: <your-auth-token>
Example response body:
[
{
"external_id": "XYZ_789",
"enrollment": null,
"zip_code_3": "117",
"version": 2016,
"survey": [
{
"answer": "very_important",
"question_id": "1"
},
{
"answer": "gt_5",
"question_id": "2"
},
{
"answer": "no",
"question_id": "3"
},
{
"answer": "100_150",
"question_id": "4"
},
{
"answer": "plan_b",
"question_id": "5"
},
{
"answer": "plan_b",
"question_id": "6"
}
],
"members": [
{
"prescriptions": [
{
"ndc": "00093738598",
"frequency": 30,
"quantity": 30
},
{
"ndc": "63304009919",
"frequency": 30,
"quantity": 9
}
],
"parent": true,
"gender": "male",
"age": 34,
"uses_tobacco": false,
"dependant": false,
"policyholder": true,
"external_id": "ABC_123"
},
{
"prescriptions": [
{
"ndc": "68462010810",
"frequency": 30,
"quantity": 360
},
{
"ndc": "00049233045",
"frequency": 30,
"quantity": 6
}
],
"parent": true,
"gender": "female",
"age": 37,
"uses_tobacco": false,
"dependant": false,
"policyholder": false,
"external_id": "CDE_234"
},
{
"prescriptions": [],
"parent": false,
"gender": "male",
"age": 9,
"uses_tobacco": false,
"dependant": true,
"policyholder": false,
"external_id": "DEF_456"
}
],
"income": 75000,
"spending_account": {
"employee_contribution": 234,
"employer_contribution": 500,
"type": "hsa"
}
}
]
Get all versions of a Household
which have a given
external_id
.
HTTP Method | GET |
Endpoint | /household/?external_id={Household.external_id} |
Headers | Picwell-Auth-Token: {Authentication.auth_token} |
Response Body | list:HouseholdReference |
Discussion
- If no
Household
exists with theexternal_id
, response code will beHTTP 404 Not Found
. - If no
external_id
parameter is provided, response code will beHTTP 400 Bad Request
.
Update Household
Example request:
PUT /client_name/household/<target-household-id>/ HTTP/1.1
Host: uat-api.picwell.net
Content-Type: application/json
Picwell-Auth-Token: <your-auth-token>
Example request body:
{ "zip_code_3": "456" }
Example response body:
{
"id": "<target-household-id>",
"version": 2017
}
Modify an existing Household
.
HTTP Method | PUT |
Endpoint | /household/{Household.id}/ |
Headers | Picwell-Auth-Token: {Authentication.auth_token} |
Request Body | Household (optionally partially updated) |
Response Body | HouseholdReference |
Discussion
- Partial
Household
objects must include complete values for each top-level key included, e.g. ifmembers
is included, the list of members should be complete. Updates the
Household
object with the highestversion
value ifversion
is not specified in the POST body. DEPRECATED An upcoming release (December 2024) will continue to support this endpoint and theversion
field, but multiple versions of a household will not be supported or saved. The single household record will be updated, including theversion
field.When updating a
Household
'sexternal_id
, if anotherHousehold
with thatexternal_id
already exists, the API will return HTTP 400.When updating a
Household
'sexternal_id
tonull
, if theHousehold
version previously had anexternal_id
, the API will return HTTP 400.
Surveys
Get Survey
Example response body:
[
{
"id": "1",
"type": "physician",
"question": "How important is it that your (or your family's) current doctor(s) are in the network of the health plan that you choose?",
"answers": {
"very_important": "Very Important",
"important": "Important",
"not_very_important": "Not Very Important",
"not_important": "Not Important"
}
},
{
"id": "2",
"type": "physician",
"question": "Think about the physician who's most important to you (or your family). How long have you been with this physician?",
"answers": {
"lt_1": "One year or less",
"2_3": "2 to 3 years",
"4_5": "4 to 5 years",
"gt_5": "More than 5 years",
"0": "I do not have a current physician"
}
},
{
"id": "3",
"type": "utilization",
"question": "Are you or a covered family member planning to have a child in the next year?",
"answers": {
"yes": "Yes",
"no": "No"
}
},
{
"id": "4",
"type": "physician",
"question": "What was your total household income before taxes during the past 12 months?",
"answers": {
"lt_25": "Less than $25,000",
"25_35": "$25,000 to $34,999",
"35_50": "$35,000 to $49,999",
"50_75": "$50,000 to $74,999",
"75_100": "$75,000 to $99,999",
"100_150": "$100,000 to $149,999",
"150_200": "$150,000 to $199,999",
"gt_200": "$200,000 or more"
}
},
{
"id": "5",
"type": "risk",
"question": "Imagine that you have a 10% chance of being injured and needing surgery (which mean you have a 90% chance you avoid injury and don't have unexpected surgery). Which plan would you choose?",
"answers": {
"plan_a": "Plan A: where your annual plan costs (premiums) are $1000 higher and you pay $0 out-of-pocket for the surgery.",
"plan_b": "Plan B: where your annual plan costs (premiums) are $1000 lower, but you have to pay $1000 out-of-pocket for the surgery."
}
},
{
"id": "6",
"type": "risk",
"question": "Imagine that you have a 50% chance of being injured and needing surgery (which mean you have a 50% chance you avoid injury and don't have unexpected surgery). Which plan would you choose?",
"answers": {
"plan_a": "Plan A: where your annual plan costs (premiums) are $1000 higher and you pay $0 out-of-pocket for the surgery.",
"plan_b": "Plan B: where your annual plan costs (premiums) are $1000 lower, but you have to pay $1000 out-of-pocket for the surgery."
}
},
{
"id": "7",
"type": "other",
"question": "Do you, or a covered family member, have any of the following medical conditions? Check all that apply."
},
{
"id": "8",
"type": "other",
"question": "If you have a Health Savings Account (HSA), what is your current balance?",
"answers": {
"not_applicable": "I don't have one",
"1_1000": "$1 to $999",
"1000_3000": "$1,000 to $2,999",
"3000_5000": "$3,000 to $4,999",
"gt_5000": "$5,000 or more",
"unknown": "I don't know my balance",
"prefer_no_answer": "I prefer not to answer"
}
},
{
"id": "9",
"type": "risk",
"question": "If you needed to receive unexpected medical care, what is the largest bill that you could afford to pay?",
"answers": {
"lt_500": " Less than $500",
"500_1000": " $500 to $999",
"1000_2000": " $1,000 to $1,999",
"2000_3000": " $2,000 to $2,999",
"3000_4000": " $3,000 to $3,999",
"4000_6000": " $4,000 to $5,999",
"gt_6000": "$6,000 or more",
"prefer_no_answer": "I prefer not to answer"
}
},
{
"id": "10",
"type": "other",
"question": "If one of the doctors you care most about is out of network, would you be willing to find a new in-network doctor if it could save you money?",
"answers": {
"yes": "Yes",
"no": "No"
}
},
{
"id": "aon_1",
"type": "aon",
"question": "Do you agree to share your answers to these questions, your providers, and your prescriptions with the health plan that you choose?",
"answers": {
"yes": "Yes",
"no": "No"
}
}
]
Retrieve user questionnaire for optimizing recommendation responses.
HTTP Method | GET |
Endpoint | /survey/ |
Headers | Picwell-Auth-Token: {Authentication.auth_token} |
Response Body | list:SurveyQuestion |
Recommendations
Get Plan Recommendations (v1)
Retrieve a list of plan recommendations for the given user.
This method takes a Household.id
and list of Plan
objects as arguments.
Example request:
POST /client_name/recommendation/<target-household-id>/?debug=1 HTTP/1.1
Host: uat-api.picwell.net
Content-Type: application/json
Picwell-Auth-Token: <your-auth-token>
Accept: application/vnd.picwell.v1+json
Example request body:
[
{
"premiums": {
"employee_contribution": 100,
"employer_contribution": 150
},
"external_id": "100005_90014_2017",
"health_provider_locations": {
"in_network": [
{
"type": "facility",
"name": "Women's Health Center of Springfield",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
]
},
{
"type": "pcp",
"name": "Julius M. Hibbert",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": []
},
{
"type": "specialist",
"name": "Nick Riviera",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": ["Cardiology", "Chiropractic"]
}
],
"out_of_network": []
},
"spending_account_contribution": 50
},
{
"premiums": {
"employee_contribution": 200,
"employer_contribution": 550
},
"external_id": "100003_90014_2017",
"health_provider_locations": {
"in_network": [
{
"type": "facility",
"name": "Women's Health Center of Springfield",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
]
},
{
"type": "pcp",
"name": "Julius M. Hibbert",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": []
}
],
"out_of_network": [
{
"type": "specialist",
"name": "Nick Riviera",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": ["Cardiology", "Chiropractic"]
}
]
},
"spending_account_contribution": 50
},
{
"premiums": {
"employee_contribution": 300,
"employer_contribution": 450
},
"external_id": "100002_90014_2017",
"health_provider_locations": {
"in_network": [
{
"type": "pcp",
"name": "Julius M. Hibbert",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": []
}
],
"out_of_network": [
{
"type": "facility",
"name": "Women's Health Center of Springfield",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
]
},
{
"type": "specialist",
"name": "Nick Riviera",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": ["Cardiology", "Chiropractic"]
}
]
},
"spending_account_contribution": 50
}
]
Example response body:
[
{
"tier": "red",
"health_provider_locations": [
{
"type": "facility",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
],
"name": "Women's Health Center of Springfield"
},
{
"type": "pcp",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": [],
"name": "Julius M. Hibbert"
},
{
"type": "specialist",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": ["Cardiology", "Chiropractic"],
"name": "Nick Riviera"
}
],
"score": 52,
"plan": {
"external_id": "100005_90014_2017",
"id": "170013162641636495"
},
"costs": {
"drugs": 2104.2,
"real_cost": 6178,
"spending_account_balance_increase": 0,
"effective_premium": 100,
"spending_account_benefit": 600,
"services": {
"in_network": 3473.8
}
}
},
{
"tier": "green",
"health_provider_locations": [
{
"type": "facility",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
],
"name": "Women's Health Center of Springfield"
},
{
"type": "pcp",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": [],
"name": "Julius M. Hibbert"
}
],
"score": 94,
"plan": {
"external_id": "100003_90014_2017",
"id": "170019782991750125"
},
"costs": {
"drugs": 674.44,
"real_cost": 3682.75,
"spending_account_balance_increase": 0,
"effective_premium": 200,
"spending_account_benefit": 600,
"services": {
"in_network": 1208.31
}
}
},
{
"tier": "green",
"health_provider_locations": [
{
"type": "pcp",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": [],
"name": "Julius M. Hibbert"
}
],
"score": 99,
"plan": {
"external_id": "100039_90014_2017",
"id": "170011214029883130"
},
"costs": {
"drugs": 1681.6,
"real_cost": 3000,
"spending_account_balance_increase": 1177.1,
"effective_premium": 300,
"spending_account_benefit": 6022.9,
"services": {
"in_network": 3741.3
}
}
}
]
Make a recommendation for the provided set of plans on the given Household
.
HTTP Method | POST |
Endpoint | /client_name/recommendation/{Household.id}/ |
Headers | Picwell-Auth-Token: {Authentication.auth_token}, Accept: application/vnd.picwell.v1+json |
Request Body | list:Plan |
Response Body | list:Recommendation |
Get Recommendations (v3)
Example Request:
POST /client_name/recommendation/<target-household-id>/?debug=1 HTTP/1.1
Host: uat-api.picwell.net
Content-Type: application/json
Picwell-Auth-Token: <your-auth-token>
Accept: application/vnd.picwell.v3+json
Example request body:
[
{
"premiums": {
"employee_contribution": 100,
"employer_contribution": 150
},
"external_id": "FMHSAPX021MP",
"network_id": "ABC123",
"health_provider_locations": {
"in_network": [
{
"type": "facility",
"name": "Women's Health Center of Springfield",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
]
},
{
"type": "pcp",
"name": "Julius M. Hibbert",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": []
},
{
"type": "specialist",
"name": "Nick Riviera",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": ["Cardiology", "Chiropractic"]
}
],
"out_of_network": []
},
"spending_account_contribution": 50
},
{
"premiums": {
"employee_contribution": 200,
"employer_contribution": 550
},
"external_id": "FMOAPPX034SP",
"network_id": "DEF456",
"health_provider_locations": {
"in_network": [
{
"type": "facility",
"name": "Women's Health Center of Springfield",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
]
},
{
"type": "pcp",
"name": "Julius M. Hibbert",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": []
}
],
"out_of_network": [
{
"type": "specialist",
"name": "Nick Riviera",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": ["Cardiology", "Chiropractic"]
}
]
},
"spending_account_contribution": 50
},
{
"premiums": {
"employee_contribution": 300,
"employer_contribution": 450
},
"external_id": "PMPPOX2PU049",
"network_id": "GHI789",
"health_provider_locations": {
"in_network": [
{
"type": "pcp",
"name": "Julius M. Hibbert",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": []
}
],
"out_of_network": [
{
"type": "facility",
"name": "Women's Health Center of Springfield",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
]
},
{
"type": "specialist",
"name": "Nick Riviera",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": ["Cardiology", "Chiropractic"]
}
]
},
"spending_account_contribution": 50
}
]
Example response body:
{
"recommendations": [
{
"tier": "green",
"health_provider_locations": [
{
"type": "facility",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
],
"name": "Women's Health Center of Springfield"
},
{
"type": "pcp",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": [],
"name": "Julius M. Hibbert"
},
{
"type": "specialist",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": ["Cardiology", "Chiropractic"],
"name": "Nick Riviera"
}
],
"score": 99,
"plan": {
"network_id": "ABC123",
"external_id": "FMHSAPX021MP",
"id": "160021727793302334"
},
"costs": {
"drugs": 1846.37,
"real_cost": 1200,
"spending_account_balance_increase": 404.87,
"effective_premium": 100,
"spending_account_benefit": 6195.13,
"services": {
"in_network": 4348.76
}
}
},
{
"tier": "red",
"health_provider_locations": [
{
"type": "facility",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
],
"name": "Women's Health Center of Springfield"
},
{
"type": "pcp",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": [],
"name": "Julius M. Hibbert"
}
],
"score": 59,
"plan": {
"network_id": "DEF456",
"external_id": "FMOAPPX034SP",
"id": "160021907881896233"
},
"costs": {
"drugs": 442.09,
"real_cost": 3569.22,
"spending_account_balance_increase": 0,
"effective_premium": 200,
"spending_account_benefit": 0,
"services": {
"in_network": 727.13
}
}
},
{
"tier": "red",
"health_provider_locations": [
{
"type": "pcp",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": [],
"name": "Julius M. Hibbert"
}
],
"score": 20,
"plan": {
"network_id": "GHI789",
"external_id": "PMPPOX2PU049",
"id": "160022781555286103"
},
"costs": {
"drugs": 511.19,
"real_cost": 6486.96,
"spending_account_balance_increase": 0,
"effective_premium": 300,
"spending_account_benefit": 0,
"services": {
"in_network": 2375.77
}
}
}
]
}
Make a recommendation for the provided set of plans on the given Household
.
HTTP Method | POST |
Endpoint | /client_name/recommendation/{Household.id}/ |
Headers | Picwell-Auth-Token: {Authentication.auth_token}, Accept: application/vnd.picwell.v3+json |
Request Body | list:Plan |
Response Body | RecommendationSet |
Get Recommendations (v4)
Example Request:
POST /client_name/recommendation/<target-household-id>/?debug=1 HTTP/1.1
Host: uat-api.picwell.net
Content-Type: application/json
Picwell-Auth-Token: <your-auth-token>
Accept: application/vnd.picwell.v4+json
Example request body:
[
{
"premiums": {
"employee_contribution": 100,
"employer_contribution": 150
},
"external_id": "FMHSAPX021MP",
"network_id": "ABC123",
"health_provider_locations": {
"in_network": [
{
"type": "facility",
"name": "Women's Health Center of Springfield",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
]
},
{
"type": "pcp",
"name": "Julius M. Hibbert",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": []
},
{
"type": "specialist",
"name": "Nick Riviera",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": ["Cardiology", "Chiropractic"]
}
],
"out_of_network": []
},
"spending_account_contribution": 50
},
{
"premiums": {
"employee_contribution": 200,
"employer_contribution": 550
},
"external_id": "FMOAPPX034SP",
"network_id": "DEF456",
"health_provider_locations": {
"in_network": [
{
"type": "facility",
"name": "Women's Health Center of Springfield",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
]
},
{
"type": "pcp",
"name": "Julius M. Hibbert",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": []
}
],
"out_of_network": [
{
"type": "specialist",
"name": "Nick Riviera",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": ["Cardiology", "Chiropractic"]
}
]
},
"spending_account_contribution": 50
},
{
"premiums": {
"employee_contribution": 300,
"employer_contribution": 450
},
"external_id": "PMPPOX2PU049",
"network_id": "GHI789",
"health_provider_locations": {
"in_network": [
{
"type": "pcp",
"name": "Julius M. Hibbert",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": []
}
],
"out_of_network": [
{
"type": "facility",
"name": "Women's Health Center of Springfield",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
]
},
{
"type": "specialist",
"name": "Nick Riviera",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": ["Cardiology", "Chiropractic"]
}
]
},
"spending_account_contribution": 50,
"coverage_tier": "individual"
}
]
Example response body:
{
"recommendations": [
{
"tier": "green",
"health_provider_locations": [
{
"type": "facility",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
],
"name": "Women's Health Center of Springfield"
},
{
"type": "pcp",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": [],
"name": "Julius M. Hibbert"
},
{
"type": "specialist",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": ["Cardiology", "Chiropractic"],
"name": "Nick Riviera"
}
],
"score": 99,
"plan": {
"network_id": "ABC123",
"external_id": "FMHSAPX021MP",
"id": "160021727793302334"
},
"costs": {
"drugs": 1846.37,
"real_cost": 1200,
"spending_account_balance_increase": 404.87,
"effective_premium": 100,
"spending_account_benefit": 6195.13,
"services": {
"in_network": 4348.76
}
}
},
{
"tier": "red",
"health_provider_locations": [
{
"type": "facility",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
],
"name": "Women's Health Center of Springfield"
},
{
"type": "pcp",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": [],
"name": "Julius M. Hibbert"
}
],
"score": 59,
"plan": {
"network_id": "DEF456",
"external_id": "FMOAPPX034SP",
"id": "160021907881896233"
},
"costs": {
"drugs": 442.09,
"real_cost": 3569.22,
"spending_account_balance_increase": 0,
"effective_premium": 200,
"spending_account_benefit": 0,
"services": {
"in_network": 727.13
}
}
},
{
"tier": "red",
"health_provider_locations": [
{
"type": "pcp",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": [],
"name": "Julius M. Hibbert"
}
],
"score": 20,
"plan": {
"network_id": "GHI789",
"external_id": "PMPPOX2PU049",
"id": "160022781555286103"
},
"costs": {
"drugs": 511.19,
"real_cost": 6486.96,
"spending_account_balance_increase": 0,
"effective_premium": 300,
"spending_account_benefit": 0,
"services": {
"in_network": 2375.77
}
}
}
]
}
Make a recommendation for the provided set of plans on the given Household
.
HTTP Method | POST |
Endpoint | /client_name/recommendation/{Household.id}/ |
Headers | Picwell-Auth-Token: {Authentication.auth_token}, Accept: application/vnd.picwell.v4+json |
Request Body | list:Plan |
Response Body | RecommendationSet |
HSA
Get HSA Recommendations (v5)
Example request:
POST /client_name/hsa/<target-household-id> HTTP/1.1
Host: uat-api.picwell.net
Content-Type: application/json
Picwell-Auth-Token: <your-auth-token>
Accept: application/vnd.picwell.v5+json
Example request body:
{
"external_id": "100005_90014_2018",
"coverage_tier": "individual",
"spending_account_contribution": 100.0
}
Example response body:
{
"recommended_contribution": 125.2,
"recommended_contribution_deciles": [
0.0, 8.0, 8.0, 28.0, 28.0, 48.0, 48.0, 68.0, 68.0, 88.0, 88.0
],
"oop_deciles": [
0.0, 20.0, 20.0, 40.0, 40.0, 60.0, 60.0, 80.0, 80.0, 100.0, 100.0
],
"employer_contribution_deciles": [
12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0
],
"hsa_benefit_deciles": [
12.0, 14.0, 14.0, 19.0, 19.0, 24.0, 24.0, 29.0, 29.0, 34.0, 34.0
],
"tax_benefit_deciles": [
0.0, 2.0, 2.0, 7.0, 7.0, 12.0, 12.0, 17.0, 17.0, 22.0, 22.0
]
}
Retrieve recommended contribution and benefit deciles for a plan based on
the given Household
.
An HSA recommendation contains a median yearly recommended contribution and several lists of values that correspond to our model's decile values for predicted out-of-pocket cost. The recommended contribution deciles contain the recommended yearly amount an employee should contribute to their HSA at each of the predicted out-of-pocket decile values. The employer contribution deciles contain the yearly amount the employer would contribute if the employee contributed the recommended amount at each decile of predicted out-of-pocket cost. The HSA benefit deciles are the tax amount saved due to the employee's contribution to the HSA combined with either the flat employer contribution amount or the out-of-pocket cost (whichever is lower) at each decile of out-of-pocket cost and recommended contribution. The tax benefit deciles contain just the tax benefits the employee would observe at each decile of out-of-pocket cost and recommended contribution.
HTTP Method | POST |
Endpoint | /client_name/hsa/{Household.id}/ |
Headers | Picwell-Auth-Token: {Authentication.auth_token}, Accept: application/vnd.picwell.v5+json |
Request Body | HSAPlanData |
Response Body | HSARecommendation |
Get HSA Forecast (v5)
Example request:
POST /client_name/hsa_forecast/<target-household-id> HTTP/1.1
Host: uat-api.picwell.net
Content-Type: application/json
Picwell-Auth-Token: <your-auth-token>
Accept: application/vnd.picwell.v5+json
Example request body:
{
"plan": {
"external_id": "0123_12431_2018",
"coverage_tier": "individual",
"spending_account_contribution": 100.0
},
"hsa_balance": 2420.2,
"employee_contribution": 125.0,
"account_usage_strategy": "spender",
"dependant_age_limit": 26,
"investment_rate_of_return": 0.05,
"retirement_age": 65,
"start_year": 2018
}
Example response body:
{
"hsa_balances": {
"twentieth": [1000, 1250, 1500, 1750, 2000],
"median": [2000, 2250, 2500, 2750, 3000],
"eightieth": [3000, 3250, 3500, 3750, 4000]
},
"oop_expenses": {
"twentieth": [200, 300, 400, 500, 600],
"median": [400, 500, 600, 700, 800],
"eightieth": [800, 1000, 1200, 1400, 1600]
},
"hsa_covers_oop_likelihoods": [100.0, 100.0, 95.0, 90.0, 85.0],
"lifetime_tax_savings": 20412.2
}
Retrieve longterm forecasting results for a Household
policyholder of the given Household
.
Picwell uses a monte carlo simulation approach to forecasting a user's HSA balance. The simulations consider medical inflation, growth in contributions and their limits, changes in households over time, and more. Users can provide an expected rate of return, expected retirement age, when to remove dependents from their plan, and their HSA usage strategy. The API then returns the median, 20th, and 80th percentile values for each year up until retirement for simulated HSA balance and OOP expenses. The API also returns the likelihood in each year up until retirement that the HSA balance will cover the user's OOP expenses as well as their lifetime tax savings.
HTTP Method | POST |
Endpoint | /client_name/hsa_forecast/{Household.id}/ |
Headers | Picwell-Auth-Token: {Authentication.auth_token}, Accept: application/vnd.picwell.v5+json |
Request Body | HSAForecastData |
Response Body | HSAForecast |
Drug Search
Example request:
GET /client_name/drugs?q=lipitor
Host: uat-api.picwell.net
Content-Type: application/json
Picwell-Auth-Token: <your-auth-token>
Accept: application/vnd.picwell.v5+json
Example response body:
{
"drugs": [
{
"form": "Oral Tablet",
"name": "LIPITOR",
"strengths": [
{
"full_name": "atorvastatin 10 MG Oral Tablet [Lipitor]",
"generic_name": "atorvastatin 10 MG Oral Tablet",
"generic_rxcui": "617312",
"ndc": "00071015510",
"rxcui": "617314",
"rxnorm_prescribable_name": "Lipitor 10 MG Oral Tablet",
"strength": "10 mg"
},
{
"full_name": "atorvastatin 20 MG Oral Tablet [Lipitor]",
"generic_name": "atorvastatin 20 MG Oral Tablet",
"generic_rxcui": "617310",
"ndc": "00071015610",
"rxcui": "617318",
"rxnorm_prescribable_name": "Lipitor 20 MG Oral Tablet",
"strength": "20 mg"
},
{
"full_name": "atorvastatin 40 MG Oral Tablet [Lipitor]",
"generic_name": "atorvastatin 40 MG Oral Tablet",
"generic_rxcui": "617311",
"ndc": "00071015723",
"rxcui": "617320",
"rxnorm_prescribable_name": "Lipitor 40 MG Oral Tablet",
"strength": "40 mg"
},
{
"full_name": "atorvastatin 80 MG Oral Tablet [Lipitor]",
"generic_name": "atorvastatin 80 MG Oral Tablet",
"generic_rxcui": "259255",
"ndc": "00071015823",
"rxcui": "262095",
"rxnorm_prescribable_name": "Lipitor 80 MG Oral Tablet",
"strength": "80 mg"
}
]
},
{
"brand": "LIPITOR",
"form": "Oral Tablet",
"name": "Atorvastatin",
"strengths": [
{
"full_name": "atorvastatin 10 MG Oral Tablet",
"ndc": "00179021601",
"rxcui": "617312",
"strength": "10 mg",
"rxnorm_prescribable_name": "atorvastatin calcium 10 MG Oral Tablet"
},
{
"full_name": "atorvastatin 20 MG Oral Tablet",
"ndc": "00179021501",
"rxcui": "617310",
"strength": "20 mg",
"rxnorm_prescribable_name": "atorvastatin calcium 20 MG Oral Tablet"
},
{
"full_name": "atorvastatin 40 MG Oral Tablet",
"ndc": "00179021401",
"rxcui": "617311",
"strength": "40 mg",
"rxnorm_prescribable_name": "atorvastatin calcium 40 MG Oral Tablet"
},
{
"full_name": "atorvastatin 80 MG Oral Tablet",
"ndc": "00179014101",
"rxcui": "259255",
"strength": "80 mg",
"rxnorm_prescribable_name": "atorvastatin calcium 80 MG Oral Tablet"
}
]
}
],
"search_term": "lipitor",
"version": "comm"
}
Search for Prescription Drugs
HTTP Method | GET |
Endpoint | /client_name/drugs?q={drug name} |
Headers | Picwell-Auth-Token: {Authentication.auth_token}, Accept: application/vnd.picwell.v5+json |
Response Body | DrugSet |
All Objects (Reference)
Objects are representations of data entities passed to Picwell as inputs. nObjects are serialized in JSON and provided to Picwell via HTTP POST bodies.
Authentication Request
An example
AuthenticationRequest
:
{
"username": "<username>",
"password": "<password>",
"ttl_seconds": 14400
}
A request for an authentication token.
field | type | description |
---|---|---|
username |
string | the username |
password |
string | the password |
ttl_seconds |
integer | min-value:300; max-value:14400; the number of seconds until the token expires (optional) |
Semantics for ttl_seconds
The ttl_seconds
field is optional and defaults to 14400. If specified, it
must be between 300 seconds (5 minutes) and 14400 seconds (4 hours). We
recommend using the default setting for optimal performance.
Authentication Reference
An example
AuthenticationReference
:
{
"auth_token": "<your-auth-token>"
}
A representation of an authentication token.
field | type | description |
---|---|---|
auth_token |
string | the authentication token |
Plan
An example
Plan
:
{
"premiums": {
"employee_contribution": 100,
"employer_contribution": 150
},
"external_id": "100005_90014_2017",
"health_provider_locations": {
"in_network": [
{
"type": "facility",
"name": "Women's Health Center of Springfield",
"location": "123 Fake St, Springfield, OR 97475",
"external_id": "wmh_345",
"specialty": [
"Obstetrics & Gynecology",
"Birthing Center",
"Lab",
"Medical Clinic"
]
},
{
"type": "pcp",
"name": "Julius M. Hibbert",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": []
},
{
"type": "specialist",
"name": "Nick Riviera",
"location": " 734 Evergreen Terrace, Springfield, OR 97475",
"external_id": "jmh_345",
"specialty": ["Cardiology", "Chiropractic"]
}
],
"out_of_network": []
},
"hsa_contributions": {
"monthly_employer_contribution": 50,
"monthly_employee_contribution": 100
},
"coverage_tier": "individual"
}
A representation of a specific insurance plan.
field | type | description |
---|---|---|
external_id |
string | Unique, mutually bound, identifier for the plan |
network_id |
string | Identifier for the network (optional) |
premiums |
||
» employee_contribution |
float | Monthly premium for the plan, contributed by the user. |
» employer_contribution |
float | Monthly premium for the plan, contributed by the employer. |
health_provider_locations |
||
» in_network |
list:HealthProviderLocation |
List of provider locations in-network. |
» out_of_network |
list:HealthProviderLocation |
List of provider locations out-of-network. |
spending_account_contribution |
float | Deprecated in favor of specifying hsa_contributions . Monthly employer contribution to a spending account from the plan. (optional) |
hsa_contributions |
||
» monthly_employee_contribution |
float | Monthly amount contributed by employee to an HSA plan to override Picwell's determination of the recommended contribution. Ignored if set on a non-HSA eligible plan. (optional) |
» monthly_employer_contribution |
float | Monthly employer contribution to an HSA plan. Ignored if set on a non-HSA eligible plan. (optional) |
coverage_tier |
string | one of individual , family , individual_spouse , individual_child (optional in v4 and up) |
Discussion
- It is assumed that descriptive attributes (such as plan names, carrier names) can be populated by the client's UI, and are therefore, not necessary to be passed back and forth in the APIs.
- Some of these secondary attributes would be captured as part of our offline, batch data transfer process (outside the scope of this API spec)
- If employee contributions to the premium are not applicable, set
premiums.employee_contribution
to0
- Semantics for
health_provider_locations.in_network
andhealth_provider_locations.out_of_network
:- In situations where no Health Provider Locations are in or out of network,
set to empty list (i.e.
[]
).
- In situations where no Health Provider Locations are in or out of network,
set to empty list (i.e.
- If optional field
coverage_tier
is not provided in a plan during a recommendation request then it is calculated based on thehousehold
object in the request.
PlanReference
An example
PlanReference
:
{
"id": "150011234567890123",
"external_id": "270093_90014_2015"
}
A reference to a specific insurance plan.
field | type | description |
---|---|---|
id | string | a (max 20-digit) numeric Picwell ID for a plan |
external_id | string | unique client-specific identifier for the plan |
network_id | string | (optional) external identifier for a network , corresponds to Plan.network_id |
Discussion
- When a
Plan
object returned by Picwell, a Picwell ID for that plan is included in the response - Network ID is included if it was provided in the
Plan
object in the recommendation request.
Prescription
An example
Prescription
:
{
"ndc": "00093007401",
"quantity": 2,
"frequency": 30
}
A prescription of a given drug.
field | type | description |
---|---|---|
ndc |
string | 11-digit NDC |
quantity |
integer | numeric quantity of the drug |
frequency |
integer | days between refills |
Spending Account
An example
SpendingAccount
:
{
"type": "hsa",
"employee_contribution": 234.0,
"employer_contribution": 543.0
}
A health spending account.
field | type | description |
---|---|---|
type |
string | enumerable of 'hsa', 'hra', 'fsa' |
employee_contribution |
float | monthly contribution from employee |
employer_contribution |
float | monthly fixed contribution from employer |
employer_percentage_contribution |
float | the employer's percentage match to an HSA given in decimal, defaults to null (optional, v5 and up) |
employer_contribution_limit |
float | annual employer contribution limit to an HSA, defaults to null (optional, v5 and up) |
Discussion
- Semantics when type is
hra
- We assume that employer contributions that we receive will not exceed the employer defined limits
- Semantics for
employer_percentage_contribution
andemployer_contribution_limit
when type ishsa
- These fields are meant to replace
employer_contribution
values in thematched
case, providing bothemployer_contribution
andemployer_percentage_contribution
will return aValidationError
. employer_percentage_contribution
is required if anemployer_contribution_limit
is provided and will return aValidationError
if this requirement is not met.
- These fields are meant to replace
User
An example
User
:
{
"external_id": "298712387712",
"age": 32,
"gender": "female",
"prescriptions": [],
"uses_tobacco": false,
"parent": false,
"dependant": false,
"policyholder": true
}
A representation of a user.
field | type | description |
---|---|---|
external_id |
string | unique, mutually bound, identifier for the user |
age |
integer | the users age |
gender |
string | enumerable of 'male' or 'female' |
prescriptions |
list:Prescription |
list of the users drugs |
uses_tobacco |
boolean | enumerable of true or false |
parent |
boolean | a parent in household, enumerable of true or false |
dependant |
boolean | a dependant in household, enumerable of true or false |
policyholder |
boolean | the primary policyholder in household, enumerable of true or false |
Discussion
- See notes that follow for more information on
parent
anddependant
flags. - There can only be one
policyholder
in a Household - Picwell requires that the
external_id
field is a de-identified (non-PII) data field. For example, a suggested type for this field is a machine generated, 36 character GUID. - Semantics for
prescriptions
field:- If the user does not take any prescription medications, represent as an
empty list (i.e.
[]
)
- If the user does not take any prescription medications, represent as an
empty list (i.e.
Household
An example
Household
:
{
"version": 2015,
"members": [
{
"age": 43,
"dependant": false,
"external_id": "1",
"gender": "male",
"parent": false,
"policyholder": true,
"prescriptions": [],
"uses_tobacco": false
},
{
"age": 23,
"dependant": false,
"external_id": "2",
"gender": "male",
"parent": false,
"policyholder": false,
"prescriptions": [],
"uses_tobacco": false
}
],
"zip_code_3": "123",
"income": 50000,
"spending_accounts": [
{
"employee_contribution": 234.0,
"employer_contribution": 543.0,
"type": "hsa"
}
],
"survey": [],
"external_id": "98798721981723",
"enrolled_in": "123_345_9878"
}
A representation of a household enrolling for coverage. If only part of an actual household is seeking coverage on your platform (e.g. just one member of a household), scope the household to those members.
field | type | description |
---|---|---|
version |
integer | household version |
members |
list:User |
min-size=1, list of enrollees seeking coverage |
zip_code_3 |
string | the household 3-digit zip code |
income |
float | household income (optional) |
spending_account |
SpendingAccount |
(optional, DEPRECATED) |
spending_accounts |
list:SpendingAccount |
min-size=0 |
survey |
list:SurveyAnswer |
min-size=0, responses to survey questions |
external_id |
string | unique client-specific identifier for this Household (optional) |
enrolled_in |
string | (optional, DEPRECATED) the external identifier for the plan that this household is currently enrolled in. |
enrollment |
Enrollment |
(optional) |
Note: For lowly populated ZIP-3s, the zip_code_3
field will be masked to
000
. See
http://www.hhs.gov/hipaa/for-professionals/privacy/special-topics/de-identification#zip
for a list of lowly populated ZIP-3s.
Discussion
- Semantics for optional field
income
:- When presented in the UI, and the user provides, set the field appropriately
- When presented in the UI, but user declines answering, or
when not possible to present UI, set the field to
null
- Semantics for optional field
spending_account
:- When presented in the UI, and the user provides, set the field appropriately
- When presented in the UI, but user declines answering, or when not possible
to present UI, set the field to
null
- This field is deprecated and slated for removal in Q1 2016, prefer
spending_accounts
- Semantics for
spending_accounts
field:- When presented in the UI, and the user provides, set the field appropriately
- When presented in the UI, but user declines answering, or when not possible
to present UI, set the field to
[]
- Note: This field is suppressed legacy implementations
- Semantics for
enrolled_in
field:- This field is used to capture the final plan selected by the user during enrollment
- If selection has not been made, this field should be set to
null
- Once selection is made, this field should be populated with the client's identifier for the plan
- Semantics for
survey
field:- When presented in the UI, and the user provides an answer, set
{Survey Answer.answer}
appropriately - When presented in the UI, and the user declines answering, or when not
possible to present UI, do not include the corresponding
{Survey Answer.answer}
- Should the user not respond to any questions (not expected), set the
survey
field to an empty list (i.e.[]
).
- When presented in the UI, and the user provides an answer, set
- Semantics for
external_id
field:- This field can be populated with a unique identifier for the household, specified by the client
- If not applicable, this field may be omitted or set to
null
- Household structures play a role in determining forecasted expense levels.
Coverage type | User 1 | User 2 | User 3 | User N |
---|---|---|---|---|
Child only | d |
|||
Adult only | n |
|||
Couple only | n |
n |
||
Couple + kid(s) | p |
p |
d |
(d) |
Single parent + kid(s) | p |
d |
(d) |
(d) |
where:
d
indicatesuser.dependant = true
,n
indicatesuser.parent = false and user.dependant = false
,p
indicatesuser.parent = true
(type)
indicate one or more of type
Household Reference
An example
HouseholdReference
:
{
"id": "e9cdcf7e-e7ac-49b1-8a8e-748f6856b198",
"version": 2016
}
A reference to a Household enrolling for coverage.
field | type | description |
---|---|---|
id | string | identifier for Household (a GUID of length 36) |
version | int | client-provided temporal identifier for a Household . Typically the plan year (e.g. 2017) |
Discussion
- When a
Household
object persisted by Picwell, a Household Profile is established - This reference (aka. profile) allows for modifications to be done to Household entity
- References should be stored by the client and re-used for the same user
- Recommendation should be re-requests to get the updated plan scores and cost estimates
Enrollment
An example
Enrollment
:
{
"plan_id": "123_345_9878",
"network_id": "ABC_FGH"
}
A reference to a plan and network that a Household
is enrolled in.
field | type | description |
---|---|---|
plan_id | string | (optional) identifier for a Plan , corresponds to Plan.external_id |
network_id | string | (optional) external identifier for a network , corresponds to Plan.network_id |
Health Provider Location
An example
HealthProviderLocation
:
{
"external_id": "97123_9822",
"specialty": ["General Practice", "Podiatry"],
"type": "facility",
"name": "Dr. Nick Riviera",
"location": "123 Mulberry St, Springfield, IL 55555"
}
A user's healthcare provider (doctor, nurse practitioner, clinic etc.) at a specific location. Health Provider Locations combine the concept of healthcare providers and the locations a provider practices at might be covered by a plan. Therefore, a provider's coverage is at the "Provider-Location" level.
Health Provider Locations also encompass the concept of health facilities that a user might express a preference towards (clinics, general hospitals etc.).
field | type | description |
---|---|---|
external_id |
string | unique identifier for health provider location |
specialty |
list:string | min-size=0, the facility or provider medical or facility specialty |
type |
string | enumerable of 'specialist', 'pcp', 'facility' |
name |
string | the facility or provider name (optional) |
location |
string | the street address of the provider location (optional) |
Discussion
- Semantics for optional field
specialty
:- If data field is available, set the field
- If no specialities are available, set the field to empty list (i.e.
[]
)
- Semantics for optional field
name
:- If data field is available, set the field
- If data field is not available, set the field to
null
- Semantics for optional field
location
:- If data field is available, set the field
- If data field is not available, set the field to
null
Survey Question
An example of a
SurveyQuestion
:
{
"question": "How important is it that your (or your family's) current doctor(s) are in the network of the health plan that you choose?",
"type": "physician",
"id": "1",
"answers": {
"very_important": "Very Important",
"important": "Important",
"not_very_important": "Not Very Important",
"not_important": "Not Important"
}
}
A health services or personality survey question.
field | type | description |
---|---|---|
id | string | string identifier for the SurveyQuestion |
type | string | enumerable of 'risk', 'physician', 'utilization' |
question | string | UI-friendly prompt for the SurveyQuestion |
answers | dict | valid responses to the question |
Discussion
- The
answers
field takes the form of a dictionary, with constants (enumerables) mapping to UI-friendly answer strings. - See "Discussion - Survey Questions and Answers" for specific questions and answers
Survey Answer
An example of a
SurveyAnswer
:
{
"answer": "very_important",
"question_id": "1"
}
A health services or personality survey response.
field | type | description |
---|---|---|
question_id |
string | string identifier for SurveyQuestion |
answer |
string | selection from SurveyQuestion.answers enumerable |
condition_answer |
ConditionAnswer |
valid responses to the medical condition question |
Discussion
- The
answer
field is required for answers to multiple choice questions. - The
condition_answer
field is required for the medical conditions question (question 7).
Condition Answer
An example of a
ConditionAnswer
:
{
"you": {
"id": "<participant_id>",
"allergies": true,
"back_pain": true
},
"spouse": {
"id": "<spouse_id>",
"cancer": true
},
"child": {
"asthma": true
}
}
An object containing answers to the conditions question for "you", "spouse" and/or "child".
field | type | description |
---|---|---|
you |
UserConditions |
Required. |
spouse |
UserConditions |
Optional. |
child |
UserConditions |
Optional. |
User Conditions
An example of a
UserConditions
:
{
"id": "<participant_id>",
"allergies": true,
"arthritis": false,
"asthma": false,
"back_pain": true,
"cancer": false,
"congestive_heart_failure": false,
"coronary_artery_disease": false,
"depression": false,
"diabetes": false,
"high_cholesterol": false,
"hypertension": false,
"kidney_disease": false,
"lung_disease": false,
"obesity": false,
"sinusitis": false,
"not_applicable": false,
"prefer_no_answer": false
}
An object defining the id and conditions of a user.
field | type | description |
---|---|---|
id |
string | id of the individual (optional) |
allergies |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
arthritis |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
asthma |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
back_pain |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
cancer |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
congestive_heart_failure |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
coronary_artery_disease |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
depression |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
diabetes |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
high_cholesterol |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
hypertension |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
kidney_disease |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
lung_disease |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
obesity |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
sinusitis |
bool | indicates whether the individual has the condition. Optional, defaults to False. |
not_applicable |
bool | indicates whether the individual has no applicable conditions. Optional, defaults to False. |
prefer_no_answer |
bool | indicates whether the individual preferred not to answer. Optional, defaults to False. |
Discussion
- The distinction between
not_applicable
andprefer_no_answer
:- If
not_applicable
is true, this explicitly states the user does not have any of the conditions listed. prefer_no_answer
is a field indicating whether the user explicitly chose not to respond to this survey question.- If user has none of the medical conditions, either
not_applicable
orprefer_no_answer
must be set to true. - Picwell will return a 400-level error to indicate any discrepancies between these fields, eg.
not_applicable = True
andallergies = True
- If
Recommendation
An example of a
Recommendation
:
{
"tier": "green",
"health_provider_locations": [],
"score": 99,
"plan": {
"external_id": "270093_90014_2015",
"id": "150011634550502806"
},
"costs": {
"drugs": 351.2,
"real_cost": 1200,
"spending_account_balance_increase": 4660.7,
"effective_premium": 100,
"spending_account_benefit": 1855.3,
"services": {
"in_network": 1504.1
}
}
}
A recommendation for a plan.
field | type | description |
---|---|---|
plan |
PlanReference |
|
score |
integer | Picwell Score from 0 to 100 |
tier |
string | enumerable of 'red', 'green', 'yellow' |
health_provider_locations |
list:HealthProviderLocation |
the providers which are in network for the plan |
costs |
||
» real_cost |
float | Picwell RealCost(tm) estimate of projected annual expenses |
» spending_account_benefit |
float | projected benefit from tax and employer contributions for the year |
» spending_account_balance_increase |
float | projected increase in spending account balance for the year |
» effective_premium |
float | monthly premium expense experienced by the user |
» services |
||
» in_network |
float | sum total cost of health services if utilized in-network |
» drugs |
float | sum total cost of drugs from a pharmacy |
Discussion
- Recommendations should be re-computed if there's a change to a
Household
definition - Premium returned is the same as passed (provided back for convenience)
health_provider_locations
is the same as passed (provided back for convenience)- Picwell RealCost(tm) can be obtained from
costs.real_cost
- This field handles the addition of all the components of RealCost (drug, health, HSA benefit, premiums)
spending_account_benefit
andspending_account_balance_increase
are provided for additional granularity; they probably do not need to be rendered in client UI.- Picwell's Plan objects incorporate the notion of plan years; it is assumed
that
Plan.external_id
maps to a specific plan, for a specific year. - Recommendations for different plan years should be made constituted as separate recommendation requests. As an example, if a user is seeking coverage for periods Nov 2015 - Dec 2015 AND Jan 2016 - Dec 2016, two requests can be made to Picwell.
Null Recommendation
Example of a
Recommendation
for an unknownPlan.external_id
:
{
"plan": {
"external_id": "97123_9822",
"id": null
},
"score": null,
"tier": null,
"costs": null,
"health_provider_locations": []
}
In situations where Picwell is unable to map to a Plan.external_id
field, the API will return a 'null' response.
- Background
- Picwell consumes flat-file data on a client's plan set as part of a batch process (outside the scope of this API document).
- Picwell internally builds a mapping between a client's plan identifier
(which is subsequently re-used in the API as
Plan.external_id
) and Picwell's own internal plan ID. - This allows a client to transact with Picwell using its own identifiers, lowering barriers and time to integration.
- Approach
- Should an API request include
Plan.external_id
values that are unknown to Picwell, we will include a response for that unknown plan with 'null' for all fields not provided in the original request.
- Should an API request include
Recommendation Set
An example of a
RecommendationSet
:
{
"recommendations": [
{
"tier": "green",
"health_provider_locations": [],
"score": 99,
"plan": {
"external_id": "270093_90014_2015",
"id": "150011634550502806"
},
"costs": {
"drugs": 351.2,
"real_cost": 1200,
"spending_account_balance_increase": 4660.7,
"effective_premium": 100,
"spending_account_benefit": 1855.3,
"services": {
"in_network": 1504.1
}
}
},
{
"tier": "red",
"health_provider_locations": [],
"score": 35,
"plan": {
"external_id": "288069_90014_2015",
"id": "150012921039882844"
},
"costs": {
"drugs": 371.54,
"real_cost": 2400,
"spending_account_balance_increase": 4413.27,
"effective_premium": 200,
"spending_account_benefit": 2102.73,
"services": {
"in_network": 1731.2
}
}
},
{
"tier": null,
"health_provider_locations": [],
"score": null,
"plan": {
"external_id": "invalid_external_id",
"id": null
},
"costs": null
}
],
"errors": [
{
"status": 200,
"detail": {
"unmatched_plans": ["invalid_external_id"]
},
"title": "RecommendationError"
}
]
}
A list of recommendations and a list of errors
field | type | description |
---|---|---|
recommendations |
list:Recommendation |
(may be empty) |
errors |
list:Error |
(may be omitted) |
HSA Plan Data
An example of a
HSAPlanData
:
{
"external_id": "0123_12431_2018",
"coverage_tier": "individual",
"spending_account_contribution": 100.0
}
Plan data for HSA-related requests.
field | type | description |
---|---|---|
external_id |
string | unique, mutually bound, identifier for the plan |
coverage_tier |
string | one of individual , family , individual_spouse , individual_child (optional) |
spending_account_contribution |
float | monthly contribution to a spending account from the plan (optional) |
HSA Recommendation
An example of a
HSARecommendation
:
{
"recommended_contribution": 125.2,
"recommended_contribution_deciles": [
0.0, 8.0, 8.0, 28.0, 28.0, 48.0, 48.0, 68.0, 68.0, 88.0, 88.0
],
"oop_deciles": [
0.0, 20.0, 20.0, 40.0, 40.0, 60.0, 60.0, 80.0, 80.0, 100.0, 100.0
],
"employer_contribution_deciles": [
12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0
],
"hsa_benefit_deciles": [
12.0, 14.0, 14.0, 19.0, 19.0, 24.0, 24.0, 29.0, 29.0, 34.0, 34.0
],
"tax_benefit_deciles": [
0.0, 2.0, 2.0, 7.0, 7.0, 12.0, 12.0, 17.0, 17.0, 22.0, 22.0
]
}
A set of recommendations for HSA.
field | type | description |
---|---|---|
recommended_contribution |
float | mean recommended employee contribution to an HSA |
recommended_contribution_deciles |
listfloat |
deciles of recommended employee contributions |
oop_deciles |
listfloat |
deciles of expected out-of-pocket costs |
employer_contribution_deciles |
listfloat |
yearly employer contributions given corresponding employee contribution from recommended_contribution_deciles |
hsa_benefit_deciles |
listfloat |
yearly financial benefits to employee given corresponding employee contributions from recommended_contribution_deciles |
tax_benefit_deciles |
listfloat |
yearly tax benefits to employee given corresponding employee contributions from recommended_contribution_deciles |
Discussion
- The recommended contribution deciles contain the recommended yearly amount an employee should contribute to their HSA in order to cover their costs that percent of the time. For example, the 2nd value represents the amount that would cover their costs for 10% of people like them, the 3rd value for 20% of people like them, and so on.
HSA Forecast
An example of a
HSAForecast
:
{
"hsa_balances": {
"twentieth": [1000, 1250, 1500, 1750, 2000],
"median": [2000, 2250, 2500, 2750, 3000],
"eightieth": [3000, 3250, 3500, 3750, 4000]
},
"oop_expenses": {
"twentieth": [200, 300, 400, 500, 600],
"median": [400, 500, 600, 700, 800],
"eightieth": [800, 1000, 1200, 1400, 1600]
},
"hsa_covers_oop_likelihoods": [100.0, 100.0, 95.0, 90.0, 85.0],
"lifetime_tax_savings": 20412.2
}
A forecast of the user's health spending account projected from current age to the retirement age.
field | type | description |
---|---|---|
hsa_balances |
||
» twentieth |
list:float |
list of balances each representing the 20th percentile for the projected year |
» median |
list:float |
list of balances each representing the 50th percentile for the projected year |
» eightieth |
list:float |
list of balances each representing the 80th percentile for the projected year |
oop_expenses |
||
» twentieth |
list:float |
list of out-of-pocket expenses each representing the 20th percentile for the projected year |
» median |
list:float |
list of out-of-pocket expenses each representing the 50th percentile for the projected year |
» eightieth |
list:float |
list of out-of-pocket expenses each representing the 80th percentile for the projected year |
hsa_covers_oop_likelihoods |
list: float |
likelihood in % that the HSA will cover out-of-pocket costs for the projected years |
lifetime_tax_savings |
float | expected cumulative tax savings from current age to retirement |
Discussion
- Each value in the
twentieth
,median
, andeightieth
lists represents the projection of theHousehold
's hsa balance/out-of-pocket expenses from the policyholder's current age up to their retirement age. For example, for a policyholder that is 26-years old expecting to retire at 65, the first value represents current HSA balance and OOP expenses for the respective percentile, the second value represents forecasted HSA balance and OOP expenses at age 27, and so on, up to the retirement age. - Each value in
hsa_covers_oop_likelihoods
represents the mean likelihood that the HSA balance will cover OOP expenses for each year in the forecast. For example, for a policyholder that is 26-years old expecting to retire at 65, the first value represents the percentage likelihood at age 26, the second value represents the percentage likelihood at age 27, and so on, up to the retirement age.
HSA Forecast Data
An example of a
HSAForecastData
:
{
"plan": {
"external_id": "0123_12431_2018",
"coverage_tier": "individual",
"spending_account_contribution": 100.0
},
"hsa_balance": 2420.2,
"employee_contribution": 125.0,
"account_usage_strategy": "spender",
"investment_rate_of_return": 0.05,
"dependant_age_limit": 26,
"retirement_age": 65,
"start_year": 2018
}
Data and parameters required for long-term HSA forecasts.
field | type | description |
---|---|---|
plan |
HSAPlanData |
|
» external_id |
string | unique, mutually bound, identifier for the plan |
» coverage_tier |
string | one of individual , family , individual_spouse , individual_child (optional) |
» spending_account_contribution |
float | monthly contribution to a spending account from the plan |
hsa_balance |
float | starting balance for HSA |
account_usage_strategy |
string | choice of either spender , saver , and supersaver , see discussion below |
employee_contribution |
float | yearly contribution to the HSA, contributed by the user |
investment_rate_of_return |
float | expected investment rate of return on the investment portion of the HSA provided as a decimal |
dependant_age_limit |
integer | cut-off age for dependants to remain under plan or household, defaults to 26 (optional) |
retirement_age |
integer | expected retirement age, defaults to 65 (optional) |
start_year |
integer | start year of when the user will expect to contribute to the HSA, defaults to current year (optional) |
Discussion
- Choices of
account_usage_strategy
:spender
- a user with thisaccount_usage_strategy
uses as much of their HSA as possible to cover out-of-pocket expenses.saver
- a user with thisaccount_usage_strategy
will not use more than $2000/yr from their HSAsupersaver
- a user with thisaccount_usage_strategy
will not take any distributions for out-of-pocket expenses.
- The typical values for
investment_rate_of_return
are around 4%.
Drug Set
An example of a
DrugSet
:
{
"drugs": [
{
"form": "Oral Tablet",
"name": "LIPITOR",
"strengths": [
{
"full_name": "atorvastatin 10 MG Oral Tablet [Lipitor]",
"generic_name": "atorvastatin 10 MG Oral Tablet",
"generic_rxcui": "617312",
"ndc": "00071015510",
"rxcui": "617314",
"rxnorm_prescribable_name": "Lipitor 10 MG Oral Tablet",
"strength": "10 mg"
},
{
"full_name": "atorvastatin 20 MG Oral Tablet [Lipitor]",
"generic_name": "atorvastatin 20 MG Oral Tablet",
"generic_rxcui": "617310",
"ndc": "00071015610",
"rxcui": "617318",
"rxnorm_prescribable_name": "Lipitor 20 MG Oral Tablet",
"strength": "20 mg"
},
{
"full_name": "atorvastatin 40 MG Oral Tablet [Lipitor]",
"generic_name": "atorvastatin 40 MG Oral Tablet",
"generic_rxcui": "617311",
"ndc": "00071015723",
"rxcui": "617320",
"rxnorm_prescribable_name": "Lipitor 40 MG Oral Tablet",
"strength": "40 mg"
},
{
"full_name": "atorvastatin 80 MG Oral Tablet [Lipitor]",
"generic_name": "atorvastatin 80 MG Oral Tablet",
"generic_rxcui": "259255",
"ndc": "00071015823",
"rxcui": "262095",
"rxnorm_prescribable_name": "Lipitor 80 MG Oral Tablet",
"strength": "80 mg"
}
]
},
{
"brand": "LIPITOR",
"form": "Oral Tablet",
"name": "Atorvastatin",
"strengths": [
{
"full_name": "atorvastatin 10 MG Oral Tablet",
"ndc": "00179021601",
"rxcui": "617312",
"strength": "10 mg",
"rxnorm_prescribable_name": "atorvastatin calcium 10 MG Oral Tablet"
},
{
"full_name": "atorvastatin 20 MG Oral Tablet",
"ndc": "00179021501",
"rxcui": "617310",
"strength": "20 mg",
"rxnorm_prescribable_name": "atorvastatin calcium 20 MG Oral Tablet"
},
{
"full_name": "atorvastatin 40 MG Oral Tablet",
"ndc": "00179021401",
"rxcui": "617311",
"strength": "40 mg",
"rxnorm_prescribable_name": "atorvastatin calcium 40 MG Oral Tablet"
},
{
"full_name": "atorvastatin 80 MG Oral Tablet",
"ndc": "00179014101",
"rxcui": "259255",
"strength": "80 mg",
"rxnorm_prescribable_name": "atorvastatin calcium 80 MG Oral Tablet"
}
],
"search_term": "lipitor",
"version": "comm"
}
A list of drugs that match a given query
field | type | description |
---|---|---|
drugs |
list: PrescriptionDrug |
a list of PrescriptionDrug objects |
search_term |
string | the requested query string |
version |
string | data set version (comm stands for commercial) |
Prescription Drug
An example of a branded
PrescriptionDrug
:
{
"form": "Oral Tablet",
"name": "LIPITOR",
"strengths": [
{
"full_name": "atorvastatin 10 MG Oral Tablet [Lipitor]",
"generic_name": "atorvastatin 10 MG Oral Tablet",
"generic_rxcui": "617312",
"ndc": "00071015510",
"rxcui": "617314",
"rxnorm_prescribable_name": "Lipitor 10 MG Oral Tablet",
"strength": "10 mg"
},
{
"full_name": "atorvastatin 20 MG Oral Tablet [Lipitor]",
"generic_name": "atorvastatin 20 MG Oral Tablet",
"generic_rxcui": "617310",
"ndc": "00071015610",
"rxcui": "617318",
"rxnorm_prescribable_name": "Lipitor 20 MG Oral Tablet",
"strength": "20 mg"
},
{
"full_name": "atorvastatin 40 MG Oral Tablet [Lipitor]",
"generic_name": "atorvastatin 40 MG Oral Tablet",
"generic_rxcui": "617311",
"ndc": "00071015723",
"rxcui": "617320",
"rxnorm_prescribable_name": "Lipitor 40 MG Oral Tablet",
"strength": "40 mg"
},
{
"full_name": "atorvastatin 80 MG Oral Tablet [Lipitor]",
"generic_name": "atorvastatin 80 MG Oral Tablet",
"generic_rxcui": "259255",
"ndc": "00071015823",
"rxcui": "262095",
"rxnorm_prescribable_name": "Lipitor 80 MG Oral Tablet",
"strength": "80 mg"
}
]
}
An example of a generic
PrescriptionDrug
:
{
"form": "Oral Tablet",
"name": "Atorvastatin",
"strengths": [
{
"full_name": "atorvastatin 10 MG Oral Tablet",
"ndc": "00378201505",
"rxcui": "617312",
"rxnorm_prescribable_name": "atorvastatin calcium 10 MG Oral Tablet",
"strength": "10 mg"
},
{
"full_name": "atorvastatin 20 MG Oral Tablet",
"ndc": "00378201705",
"rxcui": "617310",
"rxnorm_prescribable_name": "atorvastatin calcium 20 MG Oral Tablet",
"strength": "20 mg"
},
{
"full_name": "atorvastatin 40 MG Oral Tablet",
"ndc": "00378212105",
"rxcui": "617311",
"rxnorm_prescribable_name": "atorvastatin calcium 40 MG Oral Tablet",
"strength": "40 mg"
},
{
"full_name": "atorvastatin 80 MG Oral Tablet",
"ndc": "00179014145",
"rxcui": "259255",
"rxnorm_prescribable_name": "atorvastatin calcium 80 MG Oral Tablet",
"strength": "80 mg"
}
]
}
A drug object inside a drug set
field | type | description |
---|---|---|
form | string | drug form |
name | string | drug name |
strengths | ||
» full_name |
string | full name of drug including strength and form |
» generic_name (optional) |
string | generic of a branded drug |
» generic_rxcui (optional) |
string | RxNorm Concept Unique Identifier for generic version of drug |
» ndc |
string | National Drug Code |
» rxcui |
string | RxNorm Concept Unique Identifier |
» rxnorm_prescribable_name |
string | RxNorm prescribable name |
» strength |
string | drug strength |
Discussion
- the
generic_name
andgeneric_rxcui
fields only exist forPrescriptionDrug
objects of branded drugs.
Errors
Picwell's APIs may return errors to operators for valid reasons.
Any and all errors returned by the API will return a JSON response with a
top-level field errors
which contains a list of errors. An error
is
guaranteed to have the following fields:
field | type | description |
---|---|---|
title |
string | the title of the error |
detail |
string or object | a human readable description of the error |
status |
int | the HTTP status code returned with the error |
Bad Request
{
"errors": [
{
"title": "Bad Request",
"detail": "Payload provided was not valid JSON",
"status": 400
}
]
}
Sending invalid JSON in the request body to any endpoint will result in a Bad
Request
error.
Data Error
{
"errors": [
{
"title": "DataError",
"detail": {
"external_id": ["This field is required."]
},
"status": 400
}
]
}
Sending JSON to any endpoint which is missing required fields will result in
a DataError
. This example shows that the required field external_id
was not included in the request body for the given endpoint.
Model Conversion Error
{
"errors": [
{
"detail": {
"version": ["Value is not int"]
},
"status": 400,
"title": "ModelConversionError"
}
]
}
Sending JSON to any endpoint which is given the wrong type for a field will
result in a ModelConversionError
. This example shows that the version
field
must be an integer in the request body for the given endpoint.
HTTP Status Codes
Picwell's RESTful APIs make extensive use of HTTP status codes to indicate successes and failures in API requests. Please use these when debugging issues:
HTTP status code | Status code meaning | Example scenario | Exception handling |
---|---|---|---|
200 | Success | Successful request to Picwell API | N/A |
201 | Successful creation | Successfully created a new household object | N/A |
400 | Bad request | Any request to Picwell that is missing a required field. For instance, a missing product type parameter with /recommendation , or a missing inputs field when creating a household profile with /household or a missing field in the input JSON |
HTTP 400 indicates user error with our APIs. Review the API response body for a description of the error. |
401 | Unauthorized | Authentication token has expired | Recreate an authentication token using the /auth method, and retry the API operation |
404 | Object not found | A request for a household profile which does not exist | Recreate the missing profile, if necessary. |
429 | Too Many Requests | The number of requests has exceeded 10 req/s (authentication endpoints only). | |
500 | Server Error | Picwell encounters an internal server error while processing a request | Retry the request to Picwell as the error may have been temporary. Persistent failures may indicate that Picwell is experiencing downtime. |
503 | Temporary Server Error | Picwell encounters an internal server error while processing a request | Retry the request to Picwell as the error may have been temporary. |
These status codes and error messages should be planned for and handled in client code through exception handling
Support
Suggested Tooling
It is strongly suggested that a client's developers adopt a simple HTTP transaction tool to facilitate debugging against Picwell's APIs. These tools help isolate client platform-specific issues from possible Picwell API issues. In our experience, any of these tools provide excellent HTTP transaction logging and instrumentation, ideal of debugging:
- Postman for Windows or Mac or Linux,
- cURL for Windows or Mac or Linux
- Fiddler on Windows for Windows
Reporting Issues
If an API request fails in your development environment or platform, please attempt a clean HTTP request (using the tools listed above) to create a clean HTTP trasanction trace. An HTTP transaction trace includes the data points listed below. When reporting Picwell API errors, it is important to provide us with these critical elements of data in order for us to troubleshoot quickly and effectively:
- Environment being used
- HTTP transaction trace (i.e. for every API call to our service, in a transaction)
- Full URL (including query strings)
- Full HTTP Body (for POSTs and PUTs)
- All HTTP request headers
- Full HTTP response
- All HTTP response headers
- Expected results
Troubleshooting
Each request has a request ID that is returned in the X-Request-ID
header. You can provide
this to your Picwell representative along with your issue to assist in troubleshooting any difficulties.