> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.kota.io/api/employer-health-insurance/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.kota.io/_mcp/server. # Employer Health Insurance Setup > Complete guide for building the employer experience for group health insurance using Kota's API This guide walks you through building the employer-facing experience for setting up group health insurance. You'll learn how to display available plans, request quotes, handle requirements, and activate group policies - all through Kota's API. > **Info** > > Before starting, ensure you've completed: > > * [Authentication setup](/core-components/authentication) - API key configuration > * [Employer and employee management](/core-components/employer-employee-management) - Syncing employer and employee data > * [Webhooks configuration](/core-components/webhooks-and-events) - Receiving asynchronous updates --- ## Overview The employer health insurance setup follows Kota's intent-based pattern. Two primary intents drive the flow: 1. **Group Quote Intent** - Initiates the quoting process and returns pricing from insurers 2. **Group Setup Intent** - Accepts a quote and establishes the group policy Each intent may require additional data from employers or employees before completion. The API returns dynamic requirements that your platform must collect and submit. ### High-Level Flow ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ DISCOVERY PART │ ├─────────────────────────────────────────────────────────────────────────┤ │ List Providers → List Plans → Display to Employer │ └─────────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────────┐ │ GROUP CREATION │ ├─────────────────────────────────────────────────────────────────────────┤ │ Employer selects plan → Create Group for the employer │ └─────────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────────┐ │ GROUP QUOTE INTENT │ ├─────────────────────────────────────────────────────────────────────────┤ │ Create Group Quote Intent → Handle Requirements → Quote Available │ └─────────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────────┐ │ GROUP SETUP INTENT │ ├─────────────────────────────────────────────────────────────────────────┤ │ Create Group Setup Intent → Handle Requirements → Policy Active │ └─────────────────────────────────────────────────────────────────────────┘ ``` --- ## Part 1: Discovery Before employers can request quotes, they need to see what's available. This part involves fetching providers and plans to display in your UI. ### Step 1: List Providers Retrieve the list of insurance providers available on your platform. Each provider includes the countries they support. **Endpoint:** [`GET /providers`](/api-reference/providers/list-providers) **`cURL`** ```bash cURL curl -X GET "https://api.kota.io/providers" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **Response:** ```json { "object": "list", "data": [ { "object": "provider", "id": "pr_hallesche", "name": "Hallesche", "description": "German private health insurance provider", "website_url": "https://www.hallesche.de", "logo_url": "https://...", "supported_countries": ["DE"] }, { "object": "provider", "id": "pr_allianz", "name": "Allianz", "description": "International insurance provider", "website_url": "https://www.allianz.com", "logo_url": "https://...", "supported_countries": ["DE", "ES", "NL", "IE"] } ], "has_more": false } ``` **Implementation notes:** * Filter providers by country based on your employer's location * Store provider IDs for use when fetching plans * Display provider logos and descriptions to help employers make informed choices ### Step 2: List Plans Retrieve available health insurance plans. Filter by provider and/or country to show relevant options. **Endpoint:** [`GET /plans`](/api-reference/plans/list-plans) **Query parameters:** | Parameter | Type | Description | | ------------- | ------ | --------------------------------------------------------------------------------------------------------------------------- | | `type` | string | Filter by benefit type. Use `health_insurance` | | `provider_id` | string | Filter by provider ID. Use the `id` field from the providers response (e.g., `pr_hallesche`). Comma-separated for multiple. | | `country` | string | Filter by country code (e.g., `DE`, `ES`, `IE`) | **`cURL`** ```bash cURL curl -X GET "https://api.kota.io/plans?type=health_insurance&country=DE&provider_id=pr_hallesche" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **Response:** ```json { "object": "list", "data": [ { "object": "plan", "id": "pl_abc123", "type": "health_insurance", "name": "Hallesche Premium Health", "description": "Comprehensive private health insurance", "country": "DE", "provider": { "id": "pr_hallesche", "name": "Hallesche", "description": "German private health insurance provider", "logo_url": "https://..." }, "documents": [ { "type": "ipid", "title": "Insurance Product Information Document", "link": "https://..." } ], "employer_eligibility_criteria": [ { "type": "employees_count", "description": "Minimum 3 employees required" } ], "employee_eligibility_criteria": [ { "type": "age_range", "description": "Employee must be under 65 years old" } ], "health_insurance": { "insurance_geographical_need": "international", "supported_cost_sharing_options": ["percentage", "fixed_amount", "member_count"], "supported_member_types": ["adult", "young_adult", "child"], "pricing": { "type": "per_member", "per_member": { "currency": "EUR", "member_type_pricing": [ { "code": "adult", "display_name": "Adult", "monthly_premium": 150.00 }, { "code": "young_adult", "display_name": "Young Adult", "monthly_premium": 100.00 }, { "code": "child", "display_name": "Child", "monthly_premium": 75.00 } ] } } } } ], "has_more": false } ``` **Implementation notes:** * Display plan details, coverage information, and eligibility criteria * Show plan documents (IPIDs, terms and conditions) for employer review * Highlight any eligibility restrictions that might affect the employer's decision like minimum employees, age, etc. * Use the `health_insurance.pricing` block to display plan costs per member type * Check `health_insurance.supported_cost_sharing_options` to determine which cost sharing options to offer in your UI ### Step 3: Create a Group Once the employer selects a plan, create a Group to represent their health insurance setup. The Group ties together the employer, the selected plan, and eventually the group policy. **Endpoint:** [`POST /groups`](/api-reference/groups/create-group) **Request body:** | Field | Type | Required | Description | | ------------- | ------ | -------- | ----------------------------------------------------- | | `employer_id` | string | Yes | The employer creating the group (prefixed with `er_`) | | `name` | string | Yes | Human-readable name for the group | | `description` | string | No | Optional description of the group's purpose | **`cURL`** ```bash cURL curl -X POST "https://api.kota.io/groups" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "employer_id": "er_abc123", "name": "Health Insurance - Hallesche Premium", "description": "Group health insurance for all employees" }' ``` **Response:** ```json { "object": "group", "id": "gr_abc123", "name": "Health Insurance - Hallesche Premium", "description": "Group health insurance for all employees", "status": "pending", "group_type": "single", "employer_id": "er_abc123", "group_policy_ids": [] } ``` The Group starts in `pending` status. It will transition to `ready` once the group policy is created and active. **Implementation notes:** * Store the `group_id` for use in the Group Quote Intent * Use a descriptive name that helps employers identify the group (e.g., include the plan or provider name) * The `group_type` will be `single` for a single health insurance policy --- ## Part 2: Group Quote Intent When an employer selects a plan, create a Group Quote Intent to initiate the quoting process. Different providers have different response times - some provide instant quotes, others may take up to a few days. ### Group Quote Intent Lifecycle ``` ┌──────────────┐ │ Created │ └──────┬───────┘ │ ↓ ┌──────────────┐ │ Processing │ └──────┬───────┘ │ ↓ ┌─────────────────────────┐ │ Missing requirements? │ └─────────────┬───────────┘ │ ┌──────────────┴──────────────┐ ↓ yes ↓ no ┌──────────────────┐ │ │ Action Required │ │ └────────┬─────────┘ │ │ │ │ (fulfill requirements) │ │ │ └──────────────┬───────────────┘ ↓ ┌─────────────────┐ │ Awaiting Quote │ └────────┬────────┘ │ ↓ ┌─────────────────┐ │ Quote Available │ └────────┬────────┘ │ ┌────────────────────┼────────────────────┐ ↓ ↓ ↓ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Accepted │ │ Rejected │ │ Expired │ │ (→ Setup) │ │ (by user │ │ │ │ │ │ or insurer)│ │ │ └─────────────┘ └─────────────┘ └─────────────┘ ``` ### Step 4: Create Group Quote Intent Create a Group Quote Intent when the employer is ready to request pricing for a specific plan. **Endpoint:** [`POST /group_quote_intents`](/api-reference/group-quote-intents/create-group-quote-intent) **Request body:** | Field | Type | Required | Description | | -------------- | ------ | -------- | ---------------------------------------------------- | | `group_id` | string | Yes | The group requesting the quote (prefixed with `gr_`) | | `plan_id` | string | Yes | The selected plan (prefixed with `pl_`) | | `cost_sharing` | object | Yes | How premiums are split between employer and employee | The `cost_sharing` object determines how costs are allocated. The available types depend on the plan - check the `health_insurance.supported_cost_sharing_options` field on the plan response to see which options are available. **Cost sharing types:** | Type | Description | Example | | ----------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `percentage` | Employer pays a percentage of the premium | `{ "type": "percentage", "percentage": { "employer_percentage": 100 } }` | | `member_count` | Coverage based on number of adults/children | `{ "type": "member_count", "member_count": { "adults": 1, "children": 0 } }` | | `member_selection` | Explicit partner/children coverage selection | `{ "type": "member_selection", "member_selection": { "partner": true, "children": false } }` | | `member_selection_percentage_based` | Partner/children coverage selection, each covered at a percentage of their premium | `{ "type": "member_selection_percentage_based", "member_selection_percentage_based": { "partner": true, "children": false, "percentage": 50 } }` | | `policyholder_only` | Coverage for employee only | `{ "type": "policyholder_only" }` | | `family_type` | Family structure based coverage | `{ "type": "family_type", "family_type": { "type": "single" } }` | **`cURL`** ```bash cURL curl -X POST "https://api.kota.io/group_quote_intents" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "group_id": "gr_abc123", "plan_id": "pl_xyz789", "cost_sharing": { "type": "percentage", "percentage": { "employer_percentage": 100 } } }' ``` **Response:** ```json { "object": "group_quote_intent", "id": "gqi_def456", "status": "processing", "group_id": "gr_abc123", "plan_id": "pl_xyz789", "cost_sharing": { "type": "percentage", "percentage": { "employer_percentage": 100 } } } ``` After creation, the Group Quote Intent enters `processing` state. Kota evaluates whether additional information is needed. ### Step 5: Handle Requirements (if any) If the Group Quote Intent transitions to `action_required`, requirements must be fulfilled before a quote can be generated. **Webhook:** [`group_quote_intent.action_required`](/api-reference/events-and-webhooks/types-of-events-v-2/group-quote-intent-action-required-v-2-webhook) ```json { "type": "group_quote_intent.action_required", "data": { "group_quote_intent_id": "gqi_def456", "group_id": "gr_abc123", "plan_id": "pl_xyz789", "status": "action_required" } } ``` **Fetching requirement details:** Use the Group Quote Intent Requirements API to get all requirements. Each requirement includes a JSON Schema that describes exactly what data is needed. **Endpoint:** [`GET /group_quote_intents/{groupQuoteIntentId}/requirements`](/api-reference/group-quote-intents/list-group-quote-intent-requirements) **`cURL`** ```bash cURL curl -X GET "https://api.kota.io/group_quote_intents/gqi_def456/requirements" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **Response:** ```json { "items": [ { "id": "ar_3b1333d87d9d4fd6ad83ba7f6b0e951a", "object_type": "employer", "object_id": "er_abc123", "is_fulfilled": false, "requirement_type": "company_registration" }, { "id": "ar_4c2444e98e0e50e7be94cb807c1f062b", "object_type": "employee", "object_id": "ee_xyz789", "is_fulfilled": false, "requirement_type": "date_of_birth" } ], "page": 1, "page_size": 20, "total_count": 2, "has_next_page": false, "has_previous_page": false } ``` For each open requirement, retrieve the schema and submit answers with the [Adaptive Requirements Guide](/api/adaptive-requirements). **Requirements Examples** #### Example 1: Canada Life (Health Insurance) ```json { "id": "dependant_in_canadalife", "version": 1, "object_type": "associated_person", "benefit_type": "health", "context": "dependant_management_intent", "title": { "default": "Add dependant" }, "datasets": [ { "id": "sex_at_birth", "items": [ { "value": "male", "label": { "default": "Male" } }, { "value": "female", "label": { "default": "Female" } } ] }, { "id": "canadalife_member_type", "items": [ { "value": "spouse", "label": { "default": "Spouse/Partner" } }, { "value": "child", "label": { "default": "Child" } } ] }, { "id": "yes_no", "items": [ { "value": true, "label": { "default": "Yes" } }, { "value": false, "label": { "default": "No" } } ] } ], "fields": [ { "id": "dependant_id", "type": "hidden", "label": { "default": "Dependant ID" } }, { "id": "insurer_id", "type": "hidden", "label": { "default": "Insurer ID" }, "defaultValue": "in_canadalife", "validation": { "required": true } }, { "id": "first_name", "type": "text", "label": { "default": "First name" }, "placeholder": "Jane", "validation": { "required": true, "minLength": 1 } }, { "id": "last_name", "type": "text", "label": { "default": "Last name" }, "placeholder": "Doe", "validation": { "required": true, "minLength": 1 } }, { "id": "date_of_birth", "type": "date", "label": { "default": "Date of birth" }, "validation": { "required": true, "pattern": "^\\d{4}-\\d{2}-\\d{2}$", "validators": [ { "name": "dob_not_in_future" }, { "name": "age_range", "params": { "min": 18, "max": 100, "inclusiveMax": true, "when": { "==": [{ "var": "answers.member_type" }, "spouse"] } } }, { "name": "age_range", "params": { "min": 0, "max": 21, "inclusiveMax": false, "when": { "and": [ { "==": [{ "var": "answers.member_type" }, "child"] }, { "==": [{ "var": "answers.is_a_student" }, false] } ] } } }, { "name": "age_range", "params": { "min": 0, "max": 25, "inclusiveMax": false, "when": { "and": [ { "==": [{ "var": "answers.member_type" }, "child"] }, { "==": [{ "var": "answers.is_a_student" }, true] } ] } } } ] } }, { "id": "member_type", "type": "radio", "label": { "default": "Dependant type" }, "optionsSource": { "dataset": "canadalife_member_type" }, "validation": { "required": true } }, { "id": "sex_at_birth", "type": "radio", "label": { "default": "Sex assigned at birth" }, "optionsSource": { "dataset": "sex_at_birth" }, "validation": { "required": true } }, { "id": "common_law_spouse", "type": "toggle", "label": { "default": "Common Law Relationship?" }, "description": "You live together in a long-term relationship.", "visibleWhen": { "==": [{ "var": "answers.member_type" }, "spouse"] }, "excludeWhen": { "!": { "==": [{ "var": "answers.member_type" }, "spouse"] } }, "validation": { "requireWhen": { "==": [{ "var": "answers.member_type" }, "spouse"] } } }, { "id": "is_already_covered", "type": "toggle", "label": { "default": "Is already covered by another insurer?" }, "description": "Does this spouse/partner already have health coverage through another insurer?", "visibleWhen": { "==": [{ "var": "answers.member_type" }, "spouse"] }, "excludeWhen": { "!": { "==": [{ "var": "answers.member_type" }, "spouse"] } }, "validation": { "requireWhen": { "==": [{ "var": "answers.member_type" }, "spouse"] } } }, { "id": "cohabitation_start_date", "type": "date", "label": { "default": "Cohabitation start date" }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.member_type" }, "spouse"] }, { "==": [{ "var": "answers.common_law_spouse" }, true] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.member_type" }, "spouse"] }, { "==": [{ "var": "answers.common_law_spouse" }, true] } ] } }, "validation": { "requireWhen": { "and": [ { "==": [{ "var": "answers.member_type" }, "spouse"] }, { "==": [{ "var": "answers.common_law_spouse" }, true] } ] }, "pattern": "^\\d{4}-\\d{2}-\\d{2}$" } }, { "id": "is_a_student", "type": "toggle", "label": { "default": "Full time Student" }, "visibleWhen": { "==": [{ "var": "answers.member_type" }, "child"] }, "excludeWhen": { "!": { "==": [{ "var": "answers.member_type" }, "child"] } }, "validation": { "requireWhen": { "==": [{ "var": "answers.member_type" }, "child"] } } }, { "id": "has_disability", "type": "toggle", "label": { "default": "Has Disability" }, "description": "Children who are incapable of supporting themselves because of physical or mental disorder are covered without age limit if the disorder begins before they turn 21, or while they are students under 25, and the disorder has been continuous since that time.", "visibleWhen": { "==": [{ "var": "answers.member_type" }, "child"] }, "excludeWhen": { "!": { "==": [{ "var": "answers.member_type" }, "child"] } }, "validation": { "requireWhen": { "==": [{ "var": "answers.member_type" }, "child"] } } }, { "id": "school_start_date", "type": "date", "label": { "default": "School start date" }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.member_type" }, "child"] }, { "==": [{ "var": "answers.is_a_student" }, true] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.member_type" }, "child"] }, { "==": [{ "var": "answers.is_a_student" }, true] } ] } }, "validation": { "requireWhen": { "and": [ { "==": [{ "var": "answers.member_type" }, "child"] }, { "==": [{ "var": "answers.is_a_student" }, true] } ] }, "pattern": "^\\d{4}-\\d{2}-\\d{2}$" } }, { "id": "school_end_date", "type": "date", "label": { "default": "School end date" }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.member_type" }, "child"] }, { "==": [{ "var": "answers.is_a_student" }, true] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.member_type" }, "child"] }, { "==": [{ "var": "answers.is_a_student" }, true] } ] } }, "validation": { "requireWhen": { "and": [ { "==": [{ "var": "answers.member_type" }, "child"] }, { "==": [{ "var": "answers.is_a_student" }, true] } ] }, "pattern": "^\\d{4}-\\d{2}-\\d{2}$", "validators": [{ "name": "date_after", "params": { "afterField": "school_start_date" } }] } } ], "flow": { "mode": "auto", "steps": [ { "id": "general_info", "title": { "default": "General information" }, "fields": [ "dependant_id", "insurer_id", "first_name", "last_name", "date_of_birth", "member_type", "sex_at_birth" ] }, { "id": "conditional_info", "title": { "default": "Additional information" }, "fields": [ "common_law_spouse", "is_already_covered", "cohabitation_start_date", "is_a_student", "has_disability", "school_start_date", "school_end_date" ] } ], "navigation": { "start": "general_info" } } } ``` #### Complex Example: Irish Life (Health Insurance) ```json { "id": "dependant_in_irishlifehealth", "version": 1, "object_type": "associated_person", "benefit_type": "health", "context": "dependant_management_intent", "title": { "default": "Add dependant" }, "datasets": [ { "id": "sex_at_birth", "items": [ { "value": "male", "label": { "default": "Male" } }, { "value": "female", "label": { "default": "Female" } } ] }, { "id": "dependant_type", "items": [ { "value": "partner_dependant", "label": { "default": "Spouse" } }, { "value": "child_dependant", "label": { "default": "Child" } } ] }, { "id": "yes_no", "items": [ { "value": true, "label": { "default": "Yes" } }, { "value": false, "label": { "default": "No" } } ] }, { "id": "health_insurers", "items": [], "dataSource": { "resolverKey": "previousInsurersToDatasets", "outputKey": "health_insurers" } }, { "id": "health_plans", "items": [], "dataSource": { "resolverKey": "previousInsurersToDatasets", "outputKey": "health_plans" } }, { "id": "addons", "items": [ { "value": "fertility_extra", "label": { "default": "Fertility Extra" }, "description": "Get enhanced cover for infertility treatment, fertility tests and counselling." }, { "value": "maternity_extra", "label": { "default": "Maternity Extra" }, "description": "Get access to a range of comprehensive extras including early pregnancy scans, ante-natal care and unique post natal recovery benefit." }, { "value": "children_extra", "label": { "default": "Children Extra" }, "description": "Get extra benefits for your children including money back for sports club memberships, parenting courses, counselling and orthodontics." }, { "value": "you_extra", "label": { "default": "You Extra" }, "description": "Get booster health benefits that includes money back on gym membership, a mindfulness course and visits to a dietician." }, { "value": "sports_extra", "label": { "default": "Sports Extra" }, "description": "Get money back on a range of sports benefits including physiotherapy and gym membership." }, { "value": "travel_extra", "label": { "default": "Travel Extra" }, "description": "Cover for travel vaccines and a FREE annual multi-trip travel insurance policy." }, { "value": "mind_extra", "label": { "default": "Mind Extra" }, "description": "Get cover towards self-care initiatives to help you look after your state of mind." }, { "value": "screening_extra", "label": { "default": "Screening Extra" }, "description": "Get help to proactively manage your current and future health." } ] } ], "fields": [ { "id": "first_name", "type": "text", "label": { "default": "First Name" }, "placeholder": "Jane", "validation": { "required": true, "minLength": 1 } }, { "id": "last_name", "type": "text", "label": { "default": "Last Name" }, "placeholder": "Doe", "validation": { "required": true, "minLength": 1 } }, { "id": "date_of_birth", "type": "date", "label": { "default": "Date of Birth" }, "validation": { "required": true, "validators": [ { "name": "dob_not_in_future" }, { "name": "age_range", "params": { "min": 0, "max": 25, "inclusiveMax": true, "when": { "==": [{ "var": "answers.type" }, "child_dependant"] } } }, { "name": "age_range", "params": { "min": 18, "max": 75, "inclusiveMax": true, "when": { "==": [{ "var": "answers.type" }, "partner_dependant"] } } } ] } }, { "id": "sex_at_birth", "type": "radio", "label": { "default": "Sex assigned at birth" }, "optionsSource": { "dataset": "sex_at_birth" }, "validation": { "required": true } }, { "id": "type", "type": "radio", "label": { "default": "Dependant type" }, "optionsSource": { "dataset": "dependant_type" }, "validation": { "required": true } }, { "id": "age", "type": "computed", "compute": { "age_from_date": { "var": "answers.date_of_birth" } } }, { "id": "lcr_applies", "type": "computed", "label": { "default": "LCR applies" }, "visibleWhen": false, "compute": { "and": [{ "==": [{ "var": "answers.type" }, "partner_dependant"] }, { ">=": [{ "var": "answers.age" }, 35] }] } }, { "id": "continuous_insurance_since_2015", "type": "radio", "label": { "default": "Have you had continuous health insurance since 1 May 2015?" }, "optionsSource": { "dataset": "yes_no" }, "visibleWhen": { "==": [{ "var": "answers.lcr_applies" }, true] }, "excludeWhen": { "!": { "==": [{ "var": "answers.lcr_applies" }, true] } }, "validation": { "requireWhen": { "==": [{ "var": "answers.lcr_applies" }, true] } } }, { "id": "ever_had_insurance_in_ireland", "type": "radio", "label": { "default": "Have you ever had health insurance in Ireland?" }, "optionsSource": { "dataset": "yes_no" }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.continuous_insurance_since_2015" }, false] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.continuous_insurance_since_2015" }, false] } ] } }, "validation": { "requireWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.continuous_insurance_since_2015" }, false] } ] } } }, { "id": "insured_continuously_between_2009_and_2015", "type": "radio", "label": { "default": "Were you insured continuously between 2009 and 2015?" }, "optionsSource": { "dataset": "yes_no" }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.ever_had_insurance_in_ireland" }, true] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.ever_had_insurance_in_ireland" }, true] } ] } }, "validation": { "requireWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.ever_had_insurance_in_ireland" }, true] } ] } } }, { "id": "how_long_have_you_held_insurance", "type": "number", "label": { "default": "How many months have you held health insurance?" }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.insured_continuously_between_2009_and_2015" }, false] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.insured_continuously_between_2009_and_2015" }, false] } ] } }, "validation": { "requireWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.insured_continuously_between_2009_and_2015" }, false] } ] }, "min": 0 } }, { "id": "resident_in_ireland_in_2015", "type": "radio", "label": { "default": "Were you resident in Ireland on 1 May 2015?" }, "optionsSource": { "dataset": "yes_no" }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "or": [ { "==": [{ "var": "answers.insured_continuously_between_2009_and_2015" }, false] }, { "==": [{ "var": "answers.ever_had_insurance_in_ireland" }, false] } ] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "or": [ { "==": [{ "var": "answers.insured_continuously_between_2009_and_2015" }, false] }, { "==": [{ "var": "answers.ever_had_insurance_in_ireland" }, false] } ] } ] } }, "validation": { "requireWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "or": [ { "==": [{ "var": "answers.insured_continuously_between_2009_and_2015" }, false] }, { "==": [{ "var": "answers.ever_had_insurance_in_ireland" }, false] } ] } ] } } }, { "id": "have_you_or_a_dependent_ever_received_social_welfare_since_2008", "type": "radio", "label": { "default": "Have you or a dependent ever received social welfare since 2008?" }, "optionsSource": { "dataset": "yes_no" }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.resident_in_ireland_in_2015" }, true] }, { "==": [{ "var": "answers.insured_continuously_between_2009_and_2015" }, false] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.resident_in_ireland_in_2015" }, true] }, { "==": [{ "var": "answers.insured_continuously_between_2009_and_2015" }, false] } ] } }, "validation": { "requireWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.resident_in_ireland_in_2015" }, true] }, { "==": [{ "var": "answers.insured_continuously_between_2009_and_2015" }, false] } ] } } }, { "id": "how_long_were_you_dependent_on_social_welfare_payment", "type": "number", "label": { "default": "How many months were you dependent on social welfare payment?" }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.have_you_or_a_dependent_ever_received_social_welfare_since_2008" }, true] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.have_you_or_a_dependent_ever_received_social_welfare_since_2008" }, true] } ] } }, "validation": { "requireWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.have_you_or_a_dependent_ever_received_social_welfare_since_2008" }, true] } ] }, "min": 6, "max": 36, "message": "The allowed ranges for Social Welfare are between 6 & 36 months" } }, { "id": "irish_residency_date", "type": "date", "label": { "default": "Date became resident in Ireland" }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.resident_in_ireland_in_2015" }, false] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.resident_in_ireland_in_2015" }, false] } ] } }, "validation": { "requireWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.resident_in_ireland_in_2015" }, false] } ] }, "validators": [ { "name": "date_after", "params": { "after": "2015-05-01", "message": "The date you became resident in Ireland must be after 1 May 2015", "when": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "==": [{ "var": "answers.resident_in_ireland_in_2015" }, false] } ] } } } ] } }, { "id": "communityRatingType", "type": "computed", "label": { "default": "Community Rating Type" }, "visibleWhen": false, "compute": { "if": [ { "==": [{ "var": "answers.lcr_applies" }, false] }, "standard", { "==": [{ "var": "answers.continuous_insurance_since_2015" }, true] }, "continuous", { "==": [{ "var": "answers.ever_had_insurance_in_ireland" }, false] }, "none", { "==": [{ "var": "answers.insured_continuously_between_2009_and_2015" }, true] }, "exclusion", { "and": [ { "!=": [{ "var": "answers.irish_residency_date" }, null] }, { "<": [{ "months_since": { "var": "answers.irish_residency_date" } }, 9] } ] }, "exclusion", "periodic" ] } }, { "id": "previous_insurer", "type": "select", "label": { "default": "Previous insurer" }, "optionsSource": { "dataset": "health_insurers" }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "!=": [{ "var": "answers.communityRatingType" }, "none"] }, { "!=": [{ "var": "answers.communityRatingType" }, "standard"] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "!=": [{ "var": "answers.communityRatingType" }, "none"] }, { "!=": [{ "var": "answers.communityRatingType" }, "standard"] } ] } }, "validation": { "requireWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "!=": [{ "var": "answers.communityRatingType" }, "none"] }, { "!=": [{ "var": "answers.communityRatingType" }, "standard"] } ] } } }, { "id": "previous_plan", "type": "select", "label": { "default": "Previous plan" }, "optionsSource": { "dataset": "health_plans", "filter": { "==": [{ "var": "item.insurerId" }, { "var": "answers.previous_insurer" }] } }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "!=": [{ "var": "answers.communityRatingType" }, "none"] }, { "!=": [{ "var": "answers.communityRatingType" }, "standard"] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "!=": [{ "var": "answers.communityRatingType" }, "none"] }, { "!=": [{ "var": "answers.communityRatingType" }, "standard"] } ] } }, "validation": { "requireWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "!=": [{ "var": "answers.communityRatingType" }, "none"] }, { "!=": [{ "var": "answers.communityRatingType" }, "standard"] } ] } } }, { "id": "previous_policy_end_date", "type": "date", "label": { "default": "Previous policy end date" }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "!=": [{ "var": "answers.communityRatingType" }, "none"] }, { "!=": [{ "var": "answers.communityRatingType" }, "standard"] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "!=": [{ "var": "answers.communityRatingType" }, "none"] }, { "!=": [{ "var": "answers.communityRatingType" }, "standard"] } ] } }, "validation": { "requireWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "!=": [{ "var": "answers.communityRatingType" }, "none"] }, { "!=": [{ "var": "answers.communityRatingType" }, "standard"] } ] }, "validators": [{ "name": "dob_not_in_future" }] } }, { "id": "previous_membership_number", "type": "text", "label": { "default": "Previous membership number" }, "visibleWhen": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "!=": [{ "var": "answers.communityRatingType" }, "none"] }, { "!=": [{ "var": "answers.communityRatingType" }, "standard"] } ] }, "excludeWhen": { "!": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "!=": [{ "var": "answers.communityRatingType" }, "none"] }, { "!=": [{ "var": "answers.communityRatingType" }, "standard"] } ] } } }, { "id": "addons_included", "type": "hidden", "label": { "default": "Number of add-ons included" }, "defaultValue": 0 }, { "id": "addons", "type": "multi_select", "label": { "default": "Select add-ons" }, "description": "Choose your add-on packages", "optionsSource": { "dataset": "addons" }, "visibleWhen": { ">": [{ "var": "answers.addons_included" }, 0] }, "excludeWhen": { "!": { ">": [{ "var": "answers.addons_included" }, 0] } }, "validation": { "requireWhen": { ">": [{ "var": "answers.addons_included" }, 0] } } } ], "flow": { "mode": "auto", "steps": [ { "id": "general_info", "title": { "default": "General information" }, "fields": ["first_name", "last_name", "date_of_birth", "sex_at_birth", "type"] }, { "id": "lcr", "title": { "default": "Lifetime Community Rating" }, "fields": [ "lcr_applies", "communityRatingType", "continuous_insurance_since_2015", "ever_had_insurance_in_ireland", "insured_continuously_between_2009_and_2015", "how_long_have_you_held_insurance", "resident_in_ireland_in_2015", "have_you_or_a_dependent_ever_received_social_welfare_since_2008", "how_long_were_you_dependent_on_social_welfare_payment", "irish_residency_date" ] }, { "id": "previous_insurance", "title": { "default": "Previous health insurance" }, "fields": ["previous_insurer", "previous_plan", "previous_policy_end_date", "previous_membership_number"] }, { "id": "addons", "title": { "default": "Select add-ons" }, "fields": ["addons_included", "addons"] } ], "navigation": { "start": "general_info", "rules": [ { "when": { "==": [{ "var": "answers.lcr_applies" }, false] }, "action": { "type": "goto", "stepId": "addons" } }, { "when": { "and": [ { "==": [{ "var": "answers.lcr_applies" }, true] }, { "or": [ { "==": [{ "var": "answers.communityRatingType" }, "none"] }, { "==": [{ "var": "answers.communityRatingType" }, "standard"] } ] } ] }, "action": { "type": "goto", "stepId": "addons" } } ] } } } ``` **Implementation notes:** * Requirements can be for the employer (`object_type: "employer"`) or employees (`object_type: "employee"`) * The `requirement_type` field indicates what data is needed (e.g., `company_registration`, `date_of_birth`) * Use `is_fulfilled` to track which requirements have been completed * The `object_id` tells you which employer or employee the requirement applies to **Submitting requirement data:** Use the Adaptive Requirements API to retrieve each requirement schema and submit answers. See the [Adaptive Requirements Guide](/api/adaptive-requirements) for the full retrieve, render, and submit flow. **Endpoint:** [`POST /requirements/{requirement_id}`](/api-reference/requirements/submit-answers) **`cURL`** ```bash cURL curl -X POST "https://api.kota.io/requirements/ar_3b1333d87d9d4fd6ad83ba7f6b0e951a" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 9d3d2a34-4a56-4a1e-9f8e-7b6a9d2c4f10" \ -d '{ "answers": { "registration_number": "HRB 12345", "registered_address": { "line1": "Hauptstraße 1", "city": "Berlin", "postal_code": "10115", "country": "DE" } } }' ``` Once all requirements are fulfilled, the Group Quote Intent automatically transitions to `awaiting_quote`. ### Step 6: Await Quote After requirements are satisfied (or if none were needed), the Group Quote Intent enters `awaiting_quote` state. This means Kota is waiting for the insurer to respond with pricing. **Webhook:** `group_quote_intent.awaiting_quote` ```json { "type": "group_quote_intent.awaiting_quote", "data": { "group_quote_intent_id": "gqi_def456", "group_id": "gr_abc123", "plan_id": "pl_xyz789", "status": "awaiting_quote" } } ``` > **Info** > > Response times vary by provider. Some providers return quotes almost instantly. Others may take 1-3 business days. Display an appropriate holding screen to set employer expectations. ### Step 7: Quote Available When the insurer responds, the Group Quote Intent transitions to `quote_available`. You can retrieve the full quote details using the quote endpoint. **Webhook:** `group_quote_intent.quote_available` ```json { "type": "group_quote_intent.quote_available", "data": { "group_quote_intent_id": "gqi_def456", "group_id": "gr_abc123", "plan_id": "pl_xyz789", "status": "quote_available" } } ``` **Fetching quote details:** **Endpoint:** [`GET /group_quote_intents/{groupQuoteIntentId}/quote`](/api-reference/group-quote-intents/get-group-quote-intent-quote) **`cURL`** ```bash cURL curl -X GET "https://api.kota.io/group_quote_intents/gqi_def456/quote" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **Response:** ```json { "object": "group_quote", "employee_count": 5, "total_monthly_premium": 1250.00, "currency": "EUR", "cost_sharing": { "type": "percentage", "percentage": { "employer_percentage": 100 } }, "pdf_url": "https://...", "pdf_expires_at": "2024-01-16T10:30:00Z", "generated_at": "2024-01-15T10:30:00Z", "expires_at": "2024-02-15T23:59:59Z" } ``` **Display the quote to the employer with options to:** * **Accept** - Proceed to setup (creates a Group Setup Intent) * **Reject** - Decline the quote * **Let expire** - Take no action (quote expires at `expires_at`) ### Alternative Outcomes **Quote rejected by insurer:** In some cases, the insurer may decline to provide a quote. **Webhook:** `group_quote_intent.rejected_by_insurer` ```json { "type": "group_quote_intent.rejected_by_insurer", "data": { "group_quote_intent_id": "gqi_def456", "group_id": "gr_abc123", "plan_id": "pl_xyz789", "status": "rejected_by_insurer" } } ``` **Quote expired:** If the employer doesn't act before `expires_at`, the quote expires. **Webhook:** [`group_quote_intent.quote_expired`](/api-reference/events-and-webhooks/types-of-events-v-2/group-quote-intent-quote-expired-v-2-webhook) **Rejecting a quote:** If the employer decides not to proceed: **Endpoint:** [`POST /group_quote_intents/{groupQuoteIntentId}/reject`](/api-reference/group-quote-intents/reject-group-quote-intent) **`cURL`** ```bash cURL curl -X POST "https://api.kota.io/group_quote_intents/gqi_def456/reject" \ -H "Authorization: Bearer YOUR_API_KEY" ``` --- ## Part 3: Group Setup Intent When the employer accepts a quote, create a Group Setup Intent to establish the group policy with the insurer. ### Group Setup Intent Lifecycle ``` ┌──────────────┐ │ Created │ └──────┬───────┘ │ ↓ ┌──────────────┐ │ Processing │ └──────┬───────┘ │ ↓ ┌─────────────────────────┐ │ Missing requirements? │ └─────────────┬───────────┘ │ ┌──────────────┴──────────────┐ ↓ yes ↓ no ┌──────────────────┐ │ │ Action Required │ │ └────────┬─────────┘ │ │ │ │ (fulfill requirements) │ │ │ └──────────────┬───────────────┘ ↓ ┌─────────────────────────┐ │ Pending Insurer │ │ Approval │ └───────────┬─────────────┘ │ ┌─────────────┴─────────────┐ ↓ ↓ ┌──────────────────┐ ┌─────────────────────┐ │ Group Policy │ │ Rejected by │ │ Scheduled/Active │ │ Insurer (rare) │ └──────────────────┘ └─────────────────────┘ ``` > **Info** > > After a successful setup, you'll receive either `group_policy.scheduled` (if the coverage start date is in the future) or `group_policy.active` (if coverage starts immediately). The setup intent can also be rejected by the insurer during final review. ### Step 8: Create Group Setup Intent Accept the quote and initiate policy setup. **Endpoint:** `POST /group_setup_intents` **Request body:** | Field | Type | Required | Description | | ----------------------- | ------ | -------- | ---------------------------------------------- | | `group_quote_intent_id` | string | Yes | The Group Quote Intent with the accepted quote | **`cURL`** ```bash cURL curl -X POST "https://api.kota.io/group_setup_intents" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "group_quote_intent_id": "gqi_def456" }' ``` **Response:** ```json { "object": "group_setup_intent", "id": "gsi_jkl012", "status": "processing", "group_quote_intent_id": "gqi_def456" } ``` > **Warning** > > Creating a Group Setup Intent signals acceptance of the quote. Ensure the employer has explicitly confirmed they want to proceed before making this call. > > **Important:** When a Group Setup Intent is created, all other quotes for this group are automatically rejected. Only one setup can proceed per group. ### Step 9: Handle Requirements (if any) Similar to Group Quote Intents, Group Setup Intents may require additional data. The flow is identical: fetch requirement schemas, collect data, and submit. **Webhook:** `group_setup_intent.action_required` ```json { "type": "group_setup_intent.action_required", "data": { "group_setup_intent_id": "gsi_jkl012", "group_id": "gr_abc123", "plan_id": "pl_xyz789", "status": "action_required" } } ``` ### Step 10: Pending Insurer Approval After requirements are satisfied, some providers require final approval before activating the policy. **Webhook:** `group_setup_intent.pending_provider_approval` ```json { "type": "group_setup_intent.pending_provider_approval", "data": { "group_setup_intent_id": "gsi_jkl012", "group_id": "gr_abc123", "plan_id": "pl_xyz789", "status": "pending_provider_approval" } } ``` Display a holding screen indicating the policy is being finalized with the insurer. ### Step 11: Group Policy Activated Once the provider approves (or if no approval was needed), the group policy is created and activated. If the policy start date is in the future, you'll receive `group_policy.scheduled` followed by `group_policy.active` when coverage begins. **Webhook:** `group_policy.scheduled` (if start date is in the future) ```json { "type": "group_policy.scheduled", "data": { "object": "group_policy", "id": "gp_mno345", "status": "scheduled", "employer_id": "er_abc123", "plan": { "id": "pl_xyz789", "name": "Hallesche Premium Health", "provider": { "id": "pr_hallesche", "name": "Hallesche" } }, "coverage_start_date": "2024-04-01", "renewal_date": "2025-04-01", "total_monthly_premium": { "amount": "1250.00", "currency": "EUR" }, "enrolled_employees": 5 } } ``` **Webhook:** `group_policy.active` (when coverage begins) ```json { "type": "group_policy.active", "data": { "object": "group_policy", "id": "gp_mno345", "status": "active", "employer_id": "er_abc123", "plan": { "id": "pl_xyz789", "name": "Hallesche Premium Health", "provider": { "id": "pr_hallesche", "name": "Hallesche" } }, "coverage_start_date": "2024-04-01", "renewal_date": "2025-04-01", "total_monthly_premium": { "amount": "1250.00", "currency": "EUR" }, "enrolled_employees": 5 } } ``` This completes the employer journey. Display the policy details and provide access to policy documents. ### Alternative Outcome: Setup Rejected by Insurer In some rare cases, the insurer may reject the setup during final review. **Webhook:** `group_setup_intent.rejected_by_insurer` ```json { "type": "group_setup_intent.rejected_by_insurer", "data": { "group_setup_intent_id": "gsi_jkl012", "group_id": "gr_abc123", "plan_id": "pl_xyz789", "status": "rejected_by_insurer" } } ``` --- ## Webhooks Summary Your integration should handle these webhooks to drive UI state transitions: ### Group Quote Intent Webhooks | Event | Description | Action | | ---------------------------------------- | -------------------------------- | ---------------------------------------- | | `group_quote_intent.processing` | Quote request is being evaluated | Show loading state | | `group_quote_intent.action_required` | Additional data needed | Display requirement forms | | `group_quote_intent.awaiting_quote` | Waiting for insurer response | Show holding screen | | `group_quote_intent.quote_available` | Quote ready for review | Display quote with accept/reject options | | `group_quote_intent.rejected_by_insurer` | Insurer declined to quote | Show rejection message | | `group_quote_intent.quote_expired` | Quote validity period ended | Prompt to request new quote | ### Group Setup Intent Webhooks | Event | Description | Action | | ---------------------------------------------- | -------------------------- | ------------------------- | | `group_setup_intent.processing` | Setup is being processed | Show loading state | | `group_setup_intent.action_required` | Additional data needed | Display requirement forms | | `group_setup_intent.pending_provider_approval` | Awaiting insurer approval | Show holding screen | | `group_setup_intent.rejected_by_insurer` | Insurer rejected the setup | Show rejection message | ### Group Policy Webhooks | Event | Description | Action | | ------------------------ | ----------------------------------------- | -------------------------------------- | | `group_policy.scheduled` | Policy created, coverage starts in future | Display policy details with start date | | `group_policy.active` | Policy is now active | Display policy details | --- ## UI States Reference Map these states to your employer dashboard: | State | Triggered By | Display | | --------------------- | ----------------------------------- | ---------------------------------------- | | **Browsing** | Initial load | Provider and plan selection | | **Quote Requested** | Group Quote Intent created | Appropriate holding screens | | **Action Required** | `action_required` webhook | Requirement forms with deadline | | **Awaiting Quote** | `awaiting_quote` webhook | Holding screen with expected timeline | | **Quote Available** | `quote_available` webhook | Quote details with accept/reject buttons | | **Quote Rejected** | `rejected_by_insurer` webhook | Rejection message with next steps | | **Setup In Progress** | Group Setup Intent created | Loading indicator | | **Pending Approval** | `pending_provider_approval` webhook | Holding screen | | **Policy Scheduled** | `group_policy.scheduled` webhook | Policy details with coverage start date | | **Policy Active** | `group_policy.active` webhook | Policy details view | --- ## Best Practices ### Error Handling * Always handle the `rejected_by_insurer` case for both quotes and setup intents gracefully * Provide clear messaging when quotes expire * Allow employers to restart the flow if needed ### User Experience * Display provider response time expectations during the quote waiting period * Show requirement deadlines prominently to prevent timeouts * Pre-fill requirement forms with any data you already have --- ## Next Steps Once employers have active group policies, employees can enroll in coverage: * **Employee enrollment** - Employees accept coverage through Enrollment Intents * **Dependents and beneficiaries** - Employees can add family members during enrollment * **Policy management** - Handle renewals, amendments, and cancellations **Resources:** * [API Reference](/api-reference) - Detailed endpoint documentation * [Webhooks and Events](/core-components/webhooks-and-events) - Event handling best practices * [Key Concepts](/key-concepts) - Understanding Groups, Policies, and Intents > Complete guide for building the employer experience for group health insurance using Kota's API