ClarosAPI provides server-to-server access to Claros's actuarial rating engine. Submit a health plan scenario as XML and receive calculated stop-loss rates, PEPM figures, and underwriting summaries — delivered asynchronously via a polling model.
All requests are routed through Azure API Management. Every call requires two credentials
issued by Claros: a clientId and an Ocp-Apim-Subscription-Key.
https://claros-client-connect-api-management-service.azure-api.net
Prerequisites
Before making any API calls, Claros must provision your account. You will receive:
clientId or subscription key in client-side code,
source control, or logs. Store them in a secrets manager or environment variables.
Quick Start
Three calls to get a completed rate report:
clientId to /Auth. Receive a Bearer token valid for one hour./v1/Report. Receive a jobId GUID./v1/Report?jobid=… until status is Completed. The body is your result XML.Get Access Token
Exchange your clientId for an OAuth 2.0 access token. Include this token as a Bearer credential on all subsequent requests.
Request Headers
| Header | Type | Required | Description |
|---|---|---|---|
| Ocp-Apim-Subscription-Key | string | Required | Your APIM subscription key, provided by Claros. |
| Content-Type | string | Required | application/json |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| clientId | string (UUID) | Required | Your application client ID, provided by Claros. |
POST /Auth HTTP/1.1
Host: claros-client-connect-api-management-service.azure-api.net
Content-Type: application/json
Ocp-Apim-Subscription-Key: {your-subscription-key}
{
"clientId": "{your-client-id}"
}
Response
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIs..."
}
{
"error": "Invalid Client Credentials"
}
Submit a Report Request
Submit an XML scenario payload for asynchronous processing. Returns a jobId you use to poll for the result.
Request Headers
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Required | Bearer {access_token} — from Get Token. |
| Ocp-Apim-Subscription-Key | string | Required | Your APIM subscription key, provided by Claros. |
| Content-Type | string | Required | application/xml or text/xml |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| reportname | string | Required | The report type to generate. See Report Types. Case-insensitive. |
Request Body
Raw XML conforming to the Claros plan schema. Maximum size: 1 MB. See Request Format.
POST /v1/Report?reportname=RATEREPORT HTTP/1.1
Host: claros-client-connect-api-management-service.azure-api.net
Authorization: Bearer {access_token}
Content-Type: application/xml
Ocp-Apim-Subscription-Key: {your-subscription-key}
<?xml version="1.0" encoding="utf-16"?>
<Scenarios TotalPlans="1" DataYear="2024" ScenariosId="2623773">
<Scenario ScenarioId="2623111" ScenarioName="Plan A" TrendDate="2026-01-01">
...
</Scenario>
</Scenarios>
Response
The response body is the jobId — a UUID string. Store it to poll for the result.
"533555c4-2cf5-4b9b-848d-57742d5b76a7"
200 OK with a plain-text error message in the body —
not an HTTP error code. Check for non-XML content before parsing the response.
Get Report Status / Result
Poll this endpoint after submitting a report. When status is Completed, the response body contains the result XML.
Request Headers
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Required | Bearer {access_token} |
| Ocp-Apim-Subscription-Key | string | Required | Your APIM subscription key, provided by Claros. |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| jobid | string (UUID) | Required | The job ID returned from Submit a Report Request. |
GET /v1/Report?jobid=533555c4-2cf5-4b9b-848d-57742d5b76a7 HTTP/1.1
Host: claros-client-connect-api-management-service.azure-api.net
Authorization: Bearer {access_token}
Ocp-Apim-Subscription-Key: {your-subscription-key}
Responses by Job Status
{
"jobId": "533555c4-2cf5-4b9b-848d-57742d5b76a7",
"status": "Pending",
"message": "Job is still being processed. Please poll again."
}
<ClarosRateResults>
<Scenario>
<ScenarioId>2623111</ScenarioId>
<FirstDollarRates>...</FirstDollarRates>
<RateTable>...</RateTable>
<StopLossAggRates>...</StopLossAggRates>
<StopLossSummaries>...</StopLossSummaries>
</Scenario>
</ClarosRateResults>
{
"jobId": "533555c4-2cf5-4b9b-848d-57742d5b76a7",
"status": "Failed",
"error": "Something Went Wrong Please Try Again"
}
Request Format (XML)
The request body must be a valid XML document conforming to the Claros plan schema. The root element is <Scenarios>.
Root Element Attributes
| Attribute | Type | Description |
|---|---|---|
| TotalPlans | integer | Number of plans in the submission. |
| DataYear | integer | Data year for the rating analysis (e.g. 2024). |
| ScenariosId | integer | Unique identifier for this scenario group. |
Scenario Child Elements
| Element | Description |
|---|---|
| Population | Census data: enrollment tiers, ZIP codes, employee counts, and tier ratios. |
| StopLoss | Stop-loss configuration: specific deductible, aggregate settings, reimbursement percentages, incurred/paid periods, and expense loads. |
| Networks | Network definitions with medical discount rates by category (IP, OP, Rx, and subcategories). |
| Plan | Benefit plan design including deductibles, copays, co-insurance, and MOOP per medical grouping and subplan. |
<?xml version="1.0" encoding="utf-16"?>
<Scenarios TotalPlans="1" DataYear="2024" ScenariosId="2623773"
PlanYearEnabled="false" NormalizationEnabled="false">
<Scenario ScenarioId="2623111" ScenarioName="Plan A"
TrendDate="2026-01-01" HealthStatus="1.0"
UseInducedDemand="N" UseGeoHealth="N">
<Population PopulationId="1" CensusType="1" Industry="0"
EnrollmentTiers="4" T1Ratio="1.00" T2Ratio="2.20"
T4Ratio="1.80" T5Ratio="3.00">
<EmployeesInZip>
<Zip Zip3Code="606" EnrolledEmp="579" />
</EmployeesInZip>
</Population>
<StopLoss OptionNo="2"
SpIsMedical="Y" SpIsRx="Y"
SpDeductible="50000"
SpIncurred="12" SpPaid="24"
SpIsUnlimitedCoverage="Y" SpReimbPercent="1"
AgIsMedical="Y" AgIsRx="Y"
AgIncurred="12" AgPaid="24"
AgReimbPercent="1"
AgMargin="125" AgSpecCorridor="0"
OptionName="Standard" />
<Networks>
<Network NetworkId="1000" NetworkName="In Network">
<Discounts MedicalGrouping="GBL"
DiscountAmount="0.477"
DiscountOrPercentMedicare="D"
MedicalCompositeDiscount="47.7" />
</Network>
<Network NetworkId="3000" NetworkName="Out of Network">
<Discounts MedicalGrouping="GBL"
DiscountAmount="0.1"
DiscountOrPercentMedicare="D"
MedicalCompositeDiscount="10.0" />
</Network>
</Networks>
<Plan PlanNo="1" PlanName="Standard Plan">
<SubPlan SubPlanId="1" NetworkId="1000" InOutRxNetwork="I">
<!-- PlanElement entries per medical grouping (IP, OP, RAD, LP, PH, O, Rx) -->
</SubPlan>
</Plan>
</Scenario>
</Scenarios>
clarosplan-schema-definition.xsd (version 1.0.0).
Download it from Schema & Changelog.
Schema & Changelog
The request XSD is served by the API. It is the same file the API uses to validate /v1/Report requests, so it is always current.
| Resource | Endpoint | Current version |
|---|---|---|
| Request schema (XSD) | GET /v1/Schema/request |
1.0.0 |
| Changelog | GET /v1/Schema/changelog |
— |
Both endpoints require your Ocp-Apim-Subscription-Key header. No access token is needed.
curl -o clarosplan-schema-definition-v1.xsd \
-H "Ocp-Apim-Subscription-Key: {subscription_key}" \
https://claros-client-connect-api-management-service.azure-api.net/v1/Schema/request
The version is also in the file itself: <xs:schema ... version="1.0.0">.
Versioning rules
| Change | Version | Impact on your requests |
|---|---|---|
| Fix or loosen a rule, add an optional field | Minor (1.0.0 → 1.1.0) | None. Existing requests stay valid. |
| Remove or rename a field, make a field required, change a type | Major (2.0.0) | Published under new /v2 routes. /v1 keeps working unchanged. |
Changelog
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | 2026-10-06 |
First versioned release; replaces the unversioned September 2025 schema. All changes are non-breaking. Fixed
|
Response Format (XML)
When a job reaches Completed status, the response body is a <ClarosRateResults> XML document containing actuarial output for each submitted scenario.
Output Sections
| Element | Description |
|---|---|
| FirstDollarRates | Per-tier first-dollar PEPM rates before stop-loss adjustment. Tiers: EE, EE+SP, EE+CH(s), EE+Family, TOTAL. |
| FirstDollarSummaries | Factor-by-factor development of first-dollar rates: trend, area, network discount, age/gender, industry, utilization, and benefit design — for Medical, Rx, and combined. |
| RateTable | Net premium rates per tier after all underwriting adjustments. |
| StopLossAggRates | Aggregate stop-loss PEPM rates per tier. |
| StopLossAggRateAtts | Aggregate rates at the attachment point per tier. |
| StopLossSummaries | Detailed stop-loss development: LT/GT claim costs, area/network/age factors, aggregate attachment, and expense loads — split by Medical (M), Rx (R), and Total (T). |
<ClarosRateResults>
<Scenario>
<ScenarioId>2623111</ScenarioId>
<FirstDollarRates>
<FirstDollarRate>
<OptionNo>2</OptionNo>
<TierNo>1</TierNo>
<TierDesc>EE</TierDesc>
<CountOfEmployees>289.50</CountOfEmployees>
<RatePEPM>559.8327</RatePEPM>
</FirstDollarRate>
<FirstDollarRate>
<TierNo>2</TierNo>
<TierDesc>EE+SP</TierDesc>
<CountOfEmployees>86.34</CountOfEmployees>
<RatePEPM>1231.6318</RatePEPM>
</FirstDollarRate>
<!-- Additional tiers: EE+CH(s), EE+Family, TOTAL -->
</FirstDollarRates>
<RateTable>
<RateTable>
<TierDesc>EE</TierDesc>
<CountOfEmployees>289.50</CountOfEmployees>
<RatePEPM>119.3380</RatePEPM>
</RateTable>
<!-- Additional tiers -->
</RateTable>
<StopLossAggRates>...</StopLossAggRates>
<StopLossAggRateAtts>...</StopLossAggRateAtts>
<StopLossSummaries>...</StopLossSummaries>
</Scenario>
</ClarosRateResults>
Report Types
Access to each report type is controlled by roles assigned to your account. Submitting a report your account is not authorized for returns 403 Forbidden.
access-to-rate-reportreportname parameter is normalized to uppercase internally.
ratereport, RateReport, and RATEREPORT are all valid.
Job Lifecycle
Report processing is asynchronous. A job progresses through the following states:
Recommended Polling Strategy
Use exponential backoff — start at 5 seconds, doubling up to a 60-second ceiling:
interval = 5s
maxInterval = 60s
while true:
response = GET /v1/Report?jobid={jobId}
if response.status == "Completed":
return response.body // result XML
if response.status == "Failed":
throw Error(response.error)
wait(interval)
interval = min(interval * 2, maxInterval)
Rate Limits
Each subscription key is limited to 5 requests per second. Exceed that and the gateway rejects the call immediately with a 429 — no request reaches the API.
429 Response
When the rate limit is exceeded, the gateway returns the following response. Do not retry until the Retry-After interval has elapsed.
HTTP/1.1 429 Too Many Requests
Retry-After: 2
Content-Type: application/json
{
"statusCode": 429,
"message": "Rate limit is exceeded. Try again after 2 seconds."
}
Handling 429 in Your Client
MAX_RETRIES = 3
retries = 0
while retries < MAX_RETRIES:
response = POST /v1/Report?reportname=RATEREPORT
if response.status == 429:
retryAfter = response.headers["Retry-After"] ?? 1
wait(retryAfter * (2 ** retries)) // exponential backoff
retries += 1
continue
if response.status == 200:
return response.body // jobId
throw Error("Unexpected status: " + response.status)
Error Handling
jobId format, or empty request body.
clientId, or missing Ocp-Apim-Subscription-Key.
jobId does not exist or does not belong to your account.
2 seconds before retrying. See Rate Limits.
APIM Gateway: Missing Subscription Key
{
"statusCode": 401,
"message": "Access denied due to missing subscription key. Make sure to
include subscription key when making requests to an API."
}
Claros Client Connect API · v1.0 · For credentials or support, contact your Claros account team.
