Welcome to the Angle Health API! This guide will help you get started with creating quotes, uploading necessary documents, and retrieving rates for medical plans. Follow the steps below to begin your integration. The Angle Health APIs enable you to create a quote by providing essential group-level data. Once the quote is initiated, you'll upload supporting documents such as:
After processing, you'll receive rates for each plan included in your request!
In order to generate a quote we need to follow a full quoting workflow. This workflow consists of generating a draft quote, attaching experience documents to this quote, add past medical plans and finally poll for completion.
In order to generate a quote you need to be fully onboarded in Angle's External Platforms. We authenticate platform users through API Keys which are internally managed. If you have not received your API key to perform actions on the Angle API, make sure to contact platform_quoting@anglehealth.com.
Figure 1. The process starts by creating a draft quote. Then you're presented with two options.
Now that we have a quote in place, we will now attach context to it in order to make the quote more accurate. For this purpose we allow uploads of two types of data: Experience Documents: such as renewals rates, high cost claimant reports and current rates; and Past Medical Plans, which allow us to understand the dynamics of group behaviors and choices.
Figure 2. Comprehensive quoting requires the addition of at least past plans or experience documents.
It may be the case that your quotes go into Manual Review, which requires extra time to be completed. Sometimes, this could take a few business days.
The final step of quoting with Angle Platforms is to poll our servers for rates generation completion; once completed, you will receive three items: a healthscore card, which will have important information for your quoters to understand this group and its behaviors; plan rates for plans selected for quoting; and a proposal document with all the information requested.
Figure 3. The three mains results are: rates, Angle's HealthScore Card and Angle Proposal.
Below is a list of our standard plans organized by year, each identified by a unique ID. You can access the Summary of Benefits (SOB) and Summary of Benefits and Coverage (SBC) for each plan by clicking the respective links. Please note that plans from different tiers cannot be included in the same quote request.
If you provide the plan IDs exactly as listed, the network will default to CIGNA.
You cannot mix different networks in the same request — all plans must be quoted using the same network.
The network for these plans will be NOMI.
Three-tier network availability has not yet launched nationwide. It is currently limited to specific zip codes, with coverage expanding each month. If a group you're quoting does not meet the eligibility criteria for a three-tier network, the quote creation endpoint will return a Bad Request with details about the exception.
Below are some common questions and answers about the AngleHealth Platforms API to help you get started quickly.
When a quote is flagged for manual review, it just means our underwriting team needs to take a closer look before we can release the final rates. This usually takes a couple of business days.
While it's under review, we recommend checking back for updated rates at least 2–3 times a day — midday, afternoon, and evening — as updates can happen asynchronously.
Manual review is expected to be rare; the majority of quotes should return rates automatically.
We ask for plan IDs because different groups care about different benefit designs. What might be a perfect fit for one group could be less appealing to another.
By sending us the specific plan IDs you're interested in — or all of them, if you prefer — we can make sure to attach the right plan options to each quote. All our plans are eligible to be attached to any quote.
Separate quotes will need to be created. Plans from different tiers cannot be combined in the same request, so you will need to submit two individual quotes.
We recommend starting in the test environment so you can safely explore the APIs, map responses, and understand the full flow.
Once your integration is stable, we can move to production for final testing. Just keep in mind that real data and real rates are only available in the production environment, so that step is essential for full validation.
Need help with something not covered here? Contact our engineering support team at platform_quoting@anglehealth.com.
2026-03-30
2026-03-02
currentCoverageType is now a required field on POST /quotes (Create Draft Quote) for new integrations.currentCoverageType option: peo_association (PEO Association).2026-01-28
POST /quotes/{id}/mark-sold endpoint to allow marking a quote as sold.GET /quotes/{id} 403 now documents detail instead of message.GET /quotes/{id} 404 now documents description and requestId.detail as the error message field for 4xx responses.2025-12-01
2025-11-19
POST /quote updates:
member.gender field to required.member.enrolled. All members are assumed to be enrolled.quote_type. level_funded is the only choice, we will default to it.eligible_employees.These changes are backward compatible.
Creates a draft quote. The basic information provided will be saved, an identifier will be returned which should be used in following requests.
Note: For the census, the minimum is 10 total members across all states. Additionally, a minimum number of subscribers applies per state — please inquire for more information.
💡 Testing Environment Tip:
For testing different scenarios in a test environment, include one of the following parameters in the group name:
•desired_status=quoted
•desired_status=need_review
•desired_status=dtq
Example:"My Ideal Group desired_status=quoted".
This makes the GET rates-status endpoint (explained later) return the desired status. This is necessary because in a test environment, we can't guarantee accurate information based on the information provided. Real rates require real information, and PHI/PII information can't be provided in a test environment.
| groupName required | string The name of the group. |
| effectiveDate required | string <date> Effective date for the quote (format: YYYY-MM-DD). |
| employerZipCode required | string Employer's ZIP code. |
required | Array of objects (Member) List of members' census data. |
| planIds required | Array of strings List of plan IDs to associate with the quote. |
object Broker information. | |
| prevMonthlyPremium | number <double> Current monthly health plan spend. |
| renewalMonthlyPremium | number <double> Renewal monthly health plan spend. |
| currentCoverageType required | string Enum: "aca" "non_aca_fully_insured" "level_funded" "self_funded" "no_coverage" "peo_association" Current coverage type.
|
{- "groupName": "Platform Group, Inc.",
- "effectiveDate": "2025-01-01",
- "employerZipCode": "84001",
- "groupCensus": [
- {
- "firstName": "John",
- "lastName": "Doe",
- "relationship": "employee",
- "gender": "male",
- "birthDate": "1980-01-01",
- "zipCode": "84001",
- "coverageTier": "single",
- "plan": ""
}, - {
- "firstName": "Jane",
- "lastName": "Doe",
- "relationship": "spouse",
- "gender": "female",
- "birthDate": "1982-05-15",
- "zipCode": "84001",
- "coverageTier": "employee_spouse",
- "plan": ""
}, - {
- "firstName": "Alice",
- "lastName": "Doe",
- "relationship": "child",
- "gender": "female",
- "birthDate": "2010-07-20",
- "zipCode": "84001",
- "coverageTier": "employee_children",
- "plan": ""
}, - {
- "firstName": "Bob",
- "lastName": "Doe",
- "relationship": "child",
- "gender": "male",
- "birthDate": "2012-11-05",
- "zipCode": "84001",
- "coverageTier": "employee_children",
- "plan": ""
}, - {
- "firstName": "Charlie",
- "lastName": "Doe",
- "relationship": "child",
- "gender": "male",
- "birthDate": "2015-09-30",
- "zipCode": "84001",
- "coverageTier": "employee_children",
- "plan": ""
}
], - "planIds": [
- "BENLFUT9001013",
- "BENLFUT9001020",
- "BENLFUT9001117",
- "BENLFUT9001017"
], - "broker": {
- "email": "user@example.com"
}, - "prevMonthlyPremium": 0.1,
- "renewalMonthlyPremium": 0.1,
- "currentCoverageType": "aca"
}{- "quoteId": 1234,
- "description": "Draft quote created successfully."
}Retrieve a paginated list of all quotes created by the platform.
| limit | integer The number of items to return. Max 75. |
| offset | integer The number of items to skip before starting to collect the result set. |
{- "count": 8414,
- "previous": null,
- "results": [
- {
- "id": 7301,
- "effectiveDate": "2025-01-01",
- "group": {
- "entryId": 1,
- "groupName": "Group Name"
}
}, - {
- "id": 12058,
- "effectiveDate": "2025-01-01",
- "group": {
- "entryId": 2,
- "groupName": "Group Name 2"
}
}
]
}The basic information provided will be retrieved. If the quote is processed it will return rates.
| id required | integer |
{- "quote_id": 1234,
- "effective_date": "2025-01-01",
- "plan_tiers": [
- {
- "plan_id": 1,
- "plan_name": "Standard Plan 2025",
- "tiers": [
- {
- "tier_name": "National",
- "total_rate": 99.99
}, - {
- "tier_name": "Preferred",
- "total_rate": 49.99
}
]
}, - {
- "plan_id": 2,
- "plan_name": "HDHP Plan 2025",
- "tiers": [
- {
- "tier_name": "National",
- "total_rate": 199.99
}, - {
- "tier_name": "Preferred",
- "total_rate": 149.99
}
]
}
]
}Attach documents to a draft quote. This is the main mechanism for comprehensive quoting. These files help in providing more accurate rates. Files must all be of the same type, with a limit of 10 files per request, and each file must not exceed 100 MiB.
Below is an example of how to use curl to attach files to a quote:
curl -X POST "https://api-test.anglewellness.com/quoting/v2/quotes/123/files" \
-H "Authorization: YOUR_API_KEY" \
-F "files=@/path/to/quote1.pdf" \
-F "files=@/path/to/quote2.pdf"
YOUR_API_KEY with your actual API key.123 with the target quote ID.-F argument.| id required | integer The ID of the quote to which files will be attached. |
| files required | Array of strings <binary> [ items <binary > ] |
{- "data": [
- {
- "entryId": 1,
- "fileName": "quote.pdf",
- "contentType": "application/pdf"
}
]
}Creates a past medical plan associated with a specific quote. The plan includes enrollment counts, rates, and cost-sharing details. It will automatically be linked to the provided quote.
When submitting a past medical plan, please ensure that current and renewal rates are provided only for major medical plans. Rates for other types of coverage (such as vision, AD&D, or life insurance) should not be included.
singleEnrollmentCount, employeeSpouseEnrollmentCount, employeeChildrenEnrollmentCount, and familyEnrollmentCount must be provided together.singleCurrentRate, employeeSpouseCurrentRate, employeeChildrenCurrentRate, and familyCurrentRate must be provided together.singleRenewalRate, employeeSpouseRenewalRate, employeeChildrenRenewalRate, and familyRenewalRate must be provided together.| id required | integer |
| planName required | string Name of the past medical plan. |
| isHsa required | boolean Indicates if the plan is HSA (true) or Traditional (false). |
| individualInnDeductible required | integer Individual in-network deductible. |
| individualInnOopMax required | integer Individual in-network out-of-pocket maximum. |
| coinsurance required | number <double> Coinsurance rate. |
| singleEnrollmentCount | integer Count of single enrollments. |
| employeeSpouseEnrollmentCount | integer Count of employee + spouse enrollments. |
| employeeChildrenEnrollmentCount | integer Count of employee + children enrollments. |
| familyEnrollmentCount | integer Count of family enrollments. |
| singleCurrentRate | integer Current rate for single enrollments. |
| employeeSpouseCurrentRate | integer Current rate for employee + spouse enrollments. |
| employeeChildrenCurrentRate | integer Current rate for employee + children enrollments. |
| familyCurrentRate | integer Current rate for family enrollments. |
| singleRenewalRate | integer Renewal rate for single enrollments. |
| employeeSpouseRenewalRate | integer Renewal rate for employee + spouse enrollments. |
| employeeChildrenRenewalRate | integer Renewal rate for employee + children enrollments. |
| familyRenewalRate | integer Renewal rate for family enrollments. |
{- "planName": "Gold Plan",
- "isHsa": true,
- "individualInnDeductible": 1050,
- "individualInnOopMax": 2000,
- "coinsurance": 0.1,
- "singleEnrollmentCount": 1,
- "employeeSpouseEnrollmentCount": 2,
- "employeeChildrenEnrollmentCount": 3,
- "familyEnrollmentCount": 4,
- "singleCurrentRate": 100,
- "employeeSpouseCurrentRate": 200,
- "employeeChildrenCurrentRate": 300,
- "familyCurrentRate": 400,
- "singleRenewalRate": 0,
- "employeeSpouseRenewalRate": 0,
- "employeeChildrenRenewalRate": 0,
- "familyRenewalRate": 0
}{- "planName": "Gold Plan",
- "isHsa": true,
- "individualInnDeductible": 1050,
- "individualInnOopMax": 2000,
- "coinsurance": 0.1,
- "singleEnrollmentCount": 1,
- "employeeSpouseEnrollmentCount": 2,
- "employeeChildrenEnrollmentCount": 3,
- "familyEnrollmentCount": 4,
- "singleCurrentRate": 100,
- "employeeSpouseCurrentRate": 200,
- "employeeChildrenCurrentRate": 300,
- "familyCurrentRate": 400,
- "singleRenewalRate": 0,
- "employeeSpouseRenewalRate": 0,
- "employeeChildrenRenewalRate": 0,
- "familyRenewalRate": 0
}Retrieves the status of the rates calculation process for a specific quote. If it is the first call, the process will be initiated, and subsequent calls will return the status. If the status returned is need_review, it means the quote has been flagged for manual review.
| id required | integer |
{- "status": "need_review",
- "description": "The quote's rate calculation is in progress."
}Marks an existing quote as sold. This endpoint does not require a request body.
| id required | integer |
{- "groupName": "Platform Group, Inc desired_status=quoted",
- "effectiveDate": "2026-02-01",
- "quoteType": "level_funded",
- "planNames": [
- "ANG HDHP 3400 3400"
], - "state": "UT",
- "groupSize": 5,
- "brokerFirstName": "Autogenerated",
- "brokerLastName": "External Quoting",
- "brokerAgency": "Agency Name Example",
- "quoteId": "20362"
}Set of API endpoints to get proposal documents such as proposal with rates and health scorecard. For the following endpoints, it is required that the GET /rates-status endpoint has returned completed; otherwise, these endpoints will fail to return results.
Retrieves the public URL for the health scorecard document associated with a specific quote.
The quote must be in a terminal state: either rates are available or the quote has been declined to quote (DTQ). In those cases, this endpoint returns 200 with the PDF link. If the request is made before rates are ready (i.e. the quote is not yet in a terminal state), the API returns 400 Bad Request.
| id required | integer |