From 6f1d278d7a13f2a81556c0f0f15869c619d49b23 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 21 Aug 2026 11:46:25 +0000 Subject: [PATCH 01/10] feat(api): api update --- .stats.yml | 4 ++-- src/vitable_connect/resources/employers.py | 10 +++++---- src/vitable_connect/resources/members.py | 6 +++-- ..._benefit_plan_year_enrollments_response.py | 3 ++- .../employer_list_hris_providers_response.py | 8 ++++++- .../types/employer_list_response.py | 8 ++++++- .../types/employer_retrieve_hris_response.py | 22 ++++++++++++++----- .../employer_retrieve_invoice_pdf_response.py | 10 +++++++-- .../types/member_list_enrollments_response.py | 9 +++++++- 9 files changed, 61 insertions(+), 19 deletions(-) diff --git a/.stats.yml b/.stats.yml index f5b4c94..cecf7d3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 45 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-0b1ba028eafcc1352b38e7cf4c5e1be2092f615b2b0debbb3b190417d6e5c790.yml -openapi_spec_hash: 321675c35fd5b32a2c43fac714820d5a +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-432b6616730ff9adebc6c6b6da92ca13216a515870aa952173c5bc6b6daee599.yml +openapi_spec_hash: a0da70c7636bafbdba3adb49fd6528b8 config_hash: 0b4d62a9a1e0cc71998bcfc3d15c4db7 diff --git a/src/vitable_connect/resources/employers.py b/src/vitable_connect/resources/employers.py index d743c94..5b33f02 100644 --- a/src/vitable_connect/resources/employers.py +++ b/src/vitable_connect/resources/employers.py @@ -543,8 +543,9 @@ def list_hris_providers( """ Returns the distinct HRIS/payroll providers across the same book `GET /v1/employers` returns, sorted for display. Use these as the values for the - employers list's `hris_provider` filter — the providers are free text, so they - cannot be enumerated in advance. + employers list's `hris_provider` filter — filter on `provider`, show + `provider_label`. The stored providers are free text, so they cannot be + enumerated in advance. """ return self._get( "/v1/employers/hris-providers", @@ -1516,8 +1517,9 @@ async def list_hris_providers( """ Returns the distinct HRIS/payroll providers across the same book `GET /v1/employers` returns, sorted for display. Use these as the values for the - employers list's `hris_provider` filter — the providers are free text, so they - cannot be enumerated in advance. + employers list's `hris_provider` filter — filter on `provider`, show + `provider_label`. The stored providers are free text, so they cannot be + enumerated in advance. """ return await self._get( "/v1/employers/hris-providers", diff --git a/src/vitable_connect/resources/members.py b/src/vitable_connect/resources/members.py index 0492d9f..c893294 100644 --- a/src/vitable_connect/resources/members.py +++ b/src/vitable_connect/resources/members.py @@ -229,7 +229,8 @@ def list_enrollments( Lists a member's benefit enrollments across every employer — benefit type and product, employer, carrier, plan, tier, employee deduction, employer contribution and total premium, the individual enrollment coverage boundary - (`coverage_end`), the distinct benefit plan-year boundary + (`coverage_end`), the separate pre-effective cancellation boundary + (`cancelled_date`), and the distinct benefit plan-year boundary (`plan_year_coverage_end`) used to determine whether the plan year itself has ended, whether a qualifying life event would currently be required for reissue under the product/open-enrollment rule, enrollment/open-enrollment window, and @@ -599,7 +600,8 @@ async def list_enrollments( Lists a member's benefit enrollments across every employer — benefit type and product, employer, carrier, plan, tier, employee deduction, employer contribution and total premium, the individual enrollment coverage boundary - (`coverage_end`), the distinct benefit plan-year boundary + (`coverage_end`), the separate pre-effective cancellation boundary + (`cancelled_date`), and the distinct benefit plan-year boundary (`plan_year_coverage_end`) used to determine whether the plan year itself has ended, whether a qualifying life event would currently be required for reissue under the product/open-enrollment rule, enrollment/open-enrollment window, and diff --git a/src/vitable_connect/types/employer_list_benefit_plan_year_enrollments_response.py b/src/vitable_connect/types/employer_list_benefit_plan_year_enrollments_response.py index 02a38e2..0e806fa 100644 --- a/src/vitable_connect/types/employer_list_benefit_plan_year_enrollments_response.py +++ b/src/vitable_connect/types/employer_list_benefit_plan_year_enrollments_response.py @@ -69,11 +69,12 @@ class EmployerListBenefitPlanYearEnrollmentsResponse(BaseModel): plan: Optional[str] = None """Chosen plan name, or null when unanswered/waived.""" - policy_status: Optional[Literal["Coverage Upcoming", "Coverage Effective", "Coverage Ended"]] = None + policy_status: Optional[Literal["Coverage Upcoming", "Coverage Effective", "Coverage Ended", "Cancelled"]] = None """ - `Coverage Upcoming` - Coverage Upcoming - `Coverage Effective` - Coverage Effective - `Coverage Ended` - Coverage Ended + - `Cancelled` - Cancelled """ premium_in_cents: Optional[int] = None diff --git a/src/vitable_connect/types/employer_list_hris_providers_response.py b/src/vitable_connect/types/employer_list_hris_providers_response.py index 2cf34fa..3d51ad9 100644 --- a/src/vitable_connect/types/employer_list_hris_providers_response.py +++ b/src/vitable_connect/types/employer_list_hris_providers_response.py @@ -9,7 +9,13 @@ class Data(BaseModel): provider: str - """HRIS/payroll provider name, as stored on the connection (e.g. `ADP RUN`).""" + """HRIS/payroll provider id, as stored on the connection (e.g. + + `adp_run`). Filter with this. + """ + + provider_label: str + """Display name of that provider (e.g. `ADP Run`).""" class EmployerListHRISProvidersResponse(BaseModel): diff --git a/src/vitable_connect/types/employer_list_response.py b/src/vitable_connect/types/employer_list_response.py index 7e33f93..7cf68cc 100644 --- a/src/vitable_connect/types/employer_list_response.py +++ b/src/vitable_connect/types/employer_list_response.py @@ -60,7 +60,13 @@ class HRISStatus(BaseModel): """HRIS connection, or null when the employer has none.""" provider: str - """HRIS/payroll provider the employer is connected to (e.g. `Paychex`).""" + """Id of the HRIS/payroll provider the employer is connected to (e.g. + + `paylocity`). + """ + + provider_label: str + """Display name of that provider (e.g. `Paylocity`).""" status: str """Connection status reported by the integration.""" diff --git a/src/vitable_connect/types/employer_retrieve_hris_response.py b/src/vitable_connect/types/employer_retrieve_hris_response.py index ed33764..9e80db7 100644 --- a/src/vitable_connect/types/employer_retrieve_hris_response.py +++ b/src/vitable_connect/types/employer_retrieve_hris_response.py @@ -5,17 +5,23 @@ from .._models import BaseModel -__all__ = ["EmployerRetrieveHRISResponse", "HRIS"] +__all__ = ["EmployerRetrieveHRISResponse", "Data", "DataHRIS"] -class HRIS(BaseModel): +class DataHRIS(BaseModel): """HRIS connection details, or null when the employer has no integration.""" last_sync_on: Optional[datetime] = None """When the last sync completed, or null when none has.""" provider: str - """HRIS/payroll provider the employer is connected to (e.g. `Paychex`).""" + """Id of the HRIS/payroll provider the employer is connected to (e.g. + + `paylocity`). + """ + + provider_label: str + """Display name of that provider (e.g. `Paylocity`).""" status: str """Connection status reported by the integration.""" @@ -24,6 +30,12 @@ class HRIS(BaseModel): """Rows in the latest completed sync, or null when none has.""" -class EmployerRetrieveHRISResponse(BaseModel): - hris: Optional[HRIS] = None +class Data(BaseModel): + hris: Optional[DataHRIS] = None """HRIS connection details, or null when the employer has no integration.""" + + +class EmployerRetrieveHRISResponse(BaseModel): + """Response containing a single employer hris resource.""" + + data: Data diff --git a/src/vitable_connect/types/employer_retrieve_invoice_pdf_response.py b/src/vitable_connect/types/employer_retrieve_invoice_pdf_response.py index 917952d..d8dbe7a 100644 --- a/src/vitable_connect/types/employer_retrieve_invoice_pdf_response.py +++ b/src/vitable_connect/types/employer_retrieve_invoice_pdf_response.py @@ -2,9 +2,15 @@ from .._models import BaseModel -__all__ = ["EmployerRetrieveInvoicePdfResponse"] +__all__ = ["EmployerRetrieveInvoicePdfResponse", "Data"] -class EmployerRetrieveInvoicePdfResponse(BaseModel): +class Data(BaseModel): download_url: str """Time-limited Chargebee PDF download link for the invoice.""" + + +class EmployerRetrieveInvoicePdfResponse(BaseModel): + """Response containing a single employer invoice pdf resource.""" + + data: Data diff --git a/src/vitable_connect/types/member_list_enrollments_response.py b/src/vitable_connect/types/member_list_enrollments_response.py index c5c4605..19f5d62 100644 --- a/src/vitable_connect/types/member_list_enrollments_response.py +++ b/src/vitable_connect/types/member_list_enrollments_response.py @@ -23,6 +23,12 @@ class Data(BaseModel): - `Hospital` - Hospital """ + cancelled_date: Optional[date] = None + """ + Earliest applicable coverage boundary (YYYY-MM-DD) when coverage was cancelled + before its effective start; null unless the enrollment was cancelled + """ + election_status: Literal["Enrolled", "Waived", "Pending", "Expired"] """ - `Enrolled` - Enrolled @@ -55,11 +61,12 @@ class Data(BaseModel): enrollment's coverage_end; null when the plan year is open-ended """ - policy_status: Optional[Literal["Coverage Upcoming", "Coverage Effective", "Coverage Ended"]] = None + policy_status: Optional[Literal["Coverage Upcoming", "Coverage Effective", "Coverage Ended", "Cancelled"]] = None """ - `Coverage Upcoming` - Coverage Upcoming - `Coverage Effective` - Coverage Effective - `Coverage Ended` - Coverage Ended + - `Cancelled` - Cancelled """ product_code: Literal[ From ea2c85dfb0474bbb27ec9541c2da9acee8d69c0f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 21 Aug 2026 20:23:28 +0000 Subject: [PATCH 02/10] feat(api): api update --- .stats.yml | 4 +-- src/vitable_connect/resources/enrollments.py | 14 +++------- src/vitable_connect/resources/members.py | 26 ++++++++++--------- src/vitable_connect/types/employer.py | 2 +- ...yer_retrieve_benefit_plan_year_response.py | 17 +++++++++--- .../types/member_list_enrollments_response.py | 6 +++++ 6 files changed, 40 insertions(+), 29 deletions(-) diff --git a/.stats.yml b/.stats.yml index cecf7d3..692ab1e 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 45 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-432b6616730ff9adebc6c6b6da92ca13216a515870aa952173c5bc6b6daee599.yml -openapi_spec_hash: a0da70c7636bafbdba3adb49fd6528b8 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-27fbfe021b5f9c1e66a3472ec16ce44bb081417a2599ac605c32bed99a133085.yml +openapi_spec_hash: c9634f7d3c2e420c02cf5eec452b843e config_hash: 0b4d62a9a1e0cc71998bcfc3d15c4db7 diff --git a/src/vitable_connect/resources/enrollments.py b/src/vitable_connect/resources/enrollments.py index 0896505..a04c972 100644 --- a/src/vitable_connect/resources/enrollments.py +++ b/src/vitable_connect/resources/enrollments.py @@ -100,11 +100,8 @@ def reissue( same member and plan year. VPC never requires a qualifying life event; other products require an accepted, member-owned event outside open enrollment. User-backed callers must provide a reason; it is optional for userless - organization callers. API keys and unbound access tokens may act across the - caller organization's book. Employer-bound access tokens may act only on that - employer's enrollments, and employee-bound access tokens may act only on that - employee's enrollment. Tenant or token-scope mismatches return the same - non-disclosing 404 before the request body is validated. + organization callers. Tenant mismatches return a non-disclosing 404 before the + request body is validated. Args: enrollment_id: Unique enrollment identifier (enrl\\__\\**) @@ -279,11 +276,8 @@ async def reissue( same member and plan year. VPC never requires a qualifying life event; other products require an accepted, member-owned event outside open enrollment. User-backed callers must provide a reason; it is optional for userless - organization callers. API keys and unbound access tokens may act across the - caller organization's book. Employer-bound access tokens may act only on that - employer's enrollments, and employee-bound access tokens may act only on that - employee's enrollment. Tenant or token-scope mismatches return the same - non-disclosing 404 before the request body is validated. + organization callers. Tenant mismatches return a non-disclosing 404 before the + request body is validated. Args: enrollment_id: Unique enrollment identifier (enrl\\__\\**) diff --git a/src/vitable_connect/resources/members.py b/src/vitable_connect/resources/members.py index c893294..14fca44 100644 --- a/src/vitable_connect/resources/members.py +++ b/src/vitable_connect/resources/members.py @@ -236,12 +236,13 @@ def list_enrollments( under the product/open-enrollment rule, enrollment/open-enrollment window, and two statuses: `election_status` (what the member answered) and `policy_status` (what became of their coverage, null unless they enrolled). Every row includes a - stable enrollment ID that can be used to target enrollment actions. The full - list is returned across all states so the client derives active plans (effective - and upcoming) and the enrollment history from those per-row statuses. For an - organization caller the rows are scoped to companies in that organization's - book; a member (self/household) or Vitable Admin sees all enrollments. A member - not visible to the caller returns a 404. + stable enrollment ID and the exact employer and benefit plan-year IDs used to + fetch that row's plan-year detail. The full list is returned across all states + so the client derives active plans (effective and upcoming) and the enrollment + history from those per-row statuses. For an organization caller the rows are + scoped to companies in that organization's book; a member (self/household) or + Vitable Admin sees all enrollments. A member not visible to the caller returns + a 404. Args: extra_headers: Send extra headers @@ -607,12 +608,13 @@ async def list_enrollments( under the product/open-enrollment rule, enrollment/open-enrollment window, and two statuses: `election_status` (what the member answered) and `policy_status` (what became of their coverage, null unless they enrolled). Every row includes a - stable enrollment ID that can be used to target enrollment actions. The full - list is returned across all states so the client derives active plans (effective - and upcoming) and the enrollment history from those per-row statuses. For an - organization caller the rows are scoped to companies in that organization's - book; a member (self/household) or Vitable Admin sees all enrollments. A member - not visible to the caller returns a 404. + stable enrollment ID and the exact employer and benefit plan-year IDs used to + fetch that row's plan-year detail. The full list is returned across all states + so the client derives active plans (effective and upcoming) and the enrollment + history from those per-row statuses. For an organization caller the rows are + scoped to companies in that organization's book; a member (self/household) or + Vitable Admin sees all enrollments. A member not visible to the caller returns + a 404. Args: extra_headers: Send extra headers diff --git a/src/vitable_connect/types/employer.py b/src/vitable_connect/types/employer.py index 554c571..57f168a 100644 --- a/src/vitable_connect/types/employer.py +++ b/src/vitable_connect/types/employer.py @@ -61,7 +61,7 @@ class Employer(BaseModel): """Timestamp when the employer was created""" ein: Optional[str] = None - """Employer Identification Number (masked in responses)""" + """Employer Identification Number (format: XX-XXXXXXX)""" legal_name: str """Legal business name for compliance and tax purposes""" diff --git a/src/vitable_connect/types/employer_retrieve_benefit_plan_year_response.py b/src/vitable_connect/types/employer_retrieve_benefit_plan_year_response.py index 4b54c91..ebea69e 100644 --- a/src/vitable_connect/types/employer_retrieve_benefit_plan_year_response.py +++ b/src/vitable_connect/types/employer_retrieve_benefit_plan_year_response.py @@ -43,6 +43,15 @@ class DataContributionStrategyContributionTier(BaseModel): cost_per_dependent: int """Monthly employee deduction per dependent, in cents.""" + coverage_tier: Literal["Unspecified", "EE", "ES", "EC", "EF"] + """ + - `Unspecified` - Unspecified + - `EE` - EE + - `ES` - ES + - `EC` - EC + - `EF` - EF + """ + dependents_required_in: bool """Whether dependents are required for this tier.""" @@ -83,10 +92,10 @@ class DataContributionStrategyIchraContributionClass(BaseModel): family_status: Literal["Unspecified", "EE", "ES", "EC", "EF"] """ - `Unspecified` - Unspecified - - `EE` - Ee - - `ES` - Es - - `EC` - Ec - - `EF` - Ef + - `EE` - EE + - `ES` - ES + - `EC` - EC + - `EF` - EF """ location: Literal["Unspecified", "State"] diff --git a/src/vitable_connect/types/member_list_enrollments_response.py b/src/vitable_connect/types/member_list_enrollments_response.py index 19f5d62..e5c29e3 100644 --- a/src/vitable_connect/types/member_list_enrollments_response.py +++ b/src/vitable_connect/types/member_list_enrollments_response.py @@ -15,6 +15,9 @@ class Data(BaseModel): id: str """Opaque, stable enrollment identifier used to target enrollment actions""" + benefit_plan_year_id: str + """Exact benefit plan-year identifier for this enrollment""" + benefit_type: Literal["Medical", "Dental", "Vision", "Hospital"] """ - `Medical` - Medical @@ -37,6 +40,9 @@ class Data(BaseModel): - `Expired` - Expired """ + employer_id: str + """Exact employer identifier for this enrollment""" + employer_name: str """Name of the employer the enrollment is through""" From dfd0e1142e5f9847e97c87c254bd86a60bc76fea Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 19:56:03 +0000 Subject: [PATCH 03/10] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 692ab1e..c86b747 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 45 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-27fbfe021b5f9c1e66a3472ec16ce44bb081417a2599ac605c32bed99a133085.yml -openapi_spec_hash: c9634f7d3c2e420c02cf5eec452b843e +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-d3626fb1a71d7914dd6351e760634f817d83b70454a6078181b499cd3a69f958.yml +openapi_spec_hash: 1dbcf45fedd63347137a93526bfe83da config_hash: 0b4d62a9a1e0cc71998bcfc3d15c4db7 From 506aa7ec53fc4dcd8c4008a919357620c6f627bb Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 25 Aug 2026 20:45:21 +0000 Subject: [PATCH 04/10] feat(api): api update --- .stats.yml | 4 +- src/vitable_connect/resources/employees.py | 8 +- src/vitable_connect/resources/enrollments.py | 12 +- src/vitable_connect/resources/members.py | 28 +++ .../types/employee_update_params.py | 4 +- src/vitable_connect/types/enrollment.py | 2 + .../types/enrollment_retrieve_response.py | 127 ++++++++++++- .../types/member_list_response.py | 131 ++++++++++++- .../types/member_retrieve_response.py | 175 +++++++++++++++++- tests/api_resources/test_members.py | 88 ++++----- 10 files changed, 513 insertions(+), 66 deletions(-) diff --git a/.stats.yml b/.stats.yml index c86b747..1f5e5b4 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 45 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-d3626fb1a71d7914dd6351e760634f817d83b70454a6078181b499cd3a69f958.yml -openapi_spec_hash: 1dbcf45fedd63347137a93526bfe83da +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-439ab918f9d9a7afa251ac75d7799cffb98dfa2e15afcb37932ce377835994d1.yml +openapi_spec_hash: 20a93e2fc4ef3e1f24ecceb29103f8b0 config_hash: 0b4d62a9a1e0cc71998bcfc3d15c4db7 diff --git a/src/vitable_connect/resources/employees.py b/src/vitable_connect/resources/employees.py index a6a5dfd..15c01a4 100644 --- a/src/vitable_connect/resources/employees.py +++ b/src/vitable_connect/resources/employees.py @@ -139,8 +139,8 @@ def update( gender: - `Male` - Male - `Female` - Female - `Transgender` - Transgender - - `Non-binary` - Non-binary - - `Prefer not to respond` - Prefer not to respond + - `Non-binary` - Non Binary + - `Prefer not to respond` - Prefer Not To Respond phone: Phone number @@ -340,8 +340,8 @@ async def update( gender: - `Male` - Male - `Female` - Female - `Transgender` - Transgender - - `Non-binary` - Non-binary - - `Prefer not to respond` - Prefer not to respond + - `Non-binary` - Non Binary + - `Prefer not to respond` - Prefer Not To Respond phone: Phone number diff --git a/src/vitable_connect/resources/enrollments.py b/src/vitable_connect/resources/enrollments.py index a04c972..357204b 100644 --- a/src/vitable_connect/resources/enrollments.py +++ b/src/vitable_connect/resources/enrollments.py @@ -58,7 +58,11 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> EnrollmentRetrieveResponse: """ - Retrieves detailed information for a specific enrollment by ID. + Retrieves a single enrollment: the employee and employer it belongs to, the + benefit product, its status, the coverage period, the employee payroll deduction + and employer contribution, and the enrolled plan's Summary of Benefits and + Coverage document when one is on file. An enrollment the caller cannot reach is + indistinguishable from one that does not exist. Args: enrollment_id: Unique enrollment identifier (enrl\\__\\**) @@ -234,7 +238,11 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> EnrollmentRetrieveResponse: """ - Retrieves detailed information for a specific enrollment by ID. + Retrieves a single enrollment: the employee and employer it belongs to, the + benefit product, its status, the coverage period, the employee payroll deduction + and employer contribution, and the enrolled plan's Summary of Benefits and + Coverage document when one is on file. An enrollment the caller cannot reach is + indistinguishable from one that does not exist. Args: enrollment_id: Unique enrollment identifier (enrl\\__\\**) diff --git a/src/vitable_connect/resources/members.py b/src/vitable_connect/resources/members.py index 14fca44..b3367a4 100644 --- a/src/vitable_connect/resources/members.py +++ b/src/vitable_connect/resources/members.py @@ -70,6 +70,8 @@ def retrieve( authenticated principal; a member not visible to the caller returns a 404. Args: + member_id: Unique member identifier (mbr\\__\\**) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -159,6 +161,8 @@ def list_dependents( not visible to the caller returns a 404. Args: + member_id: Unique member identifier (mbr\\__\\**) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -196,6 +200,8 @@ def list_employments( not visible to the caller returns a 404. Args: + member_id: Unique member identifier (mbr\\__\\**) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -245,6 +251,8 @@ def list_enrollments( a 404. Args: + member_id: Unique member identifier (mbr\\__\\**) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -285,6 +293,8 @@ def list_id_cards( employers in its book; a member not visible to the caller returns a 404. Args: + member_id: Unique member identifier (mbr\\__\\**) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -329,6 +339,8 @@ def list_qualifying_life_events( before pagination is validated. Args: + member_id: Unique member identifier (mbr\\__\\**) + limit: Items per page (default: 20, max: 100) page: Page number (default: 1) @@ -384,6 +396,8 @@ def retrieve_household( a 404. Args: + member_id: Unique member identifier (mbr\\__\\**) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -442,6 +456,8 @@ async def retrieve( authenticated principal; a member not visible to the caller returns a 404. Args: + member_id: Unique member identifier (mbr\\__\\**) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -531,6 +547,8 @@ async def list_dependents( not visible to the caller returns a 404. Args: + member_id: Unique member identifier (mbr\\__\\**) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -568,6 +586,8 @@ async def list_employments( not visible to the caller returns a 404. Args: + member_id: Unique member identifier (mbr\\__\\**) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -617,6 +637,8 @@ async def list_enrollments( a 404. Args: + member_id: Unique member identifier (mbr\\__\\**) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -657,6 +679,8 @@ async def list_id_cards( employers in its book; a member not visible to the caller returns a 404. Args: + member_id: Unique member identifier (mbr\\__\\**) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -703,6 +727,8 @@ def list_qualifying_life_events( before pagination is validated. Args: + member_id: Unique member identifier (mbr\\__\\**) + limit: Items per page (default: 20, max: 100) page: Page number (default: 1) @@ -758,6 +784,8 @@ async def retrieve_household( a 404. Args: + member_id: Unique member identifier (mbr\\__\\**) + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/vitable_connect/types/employee_update_params.py b/src/vitable_connect/types/employee_update_params.py index 96eb41b..e97bf55 100644 --- a/src/vitable_connect/types/employee_update_params.py +++ b/src/vitable_connect/types/employee_update_params.py @@ -46,8 +46,8 @@ class EmployeeUpdateParams(TypedDict, total=False): - `Male` - Male - `Female` - Female - `Transgender` - Transgender - - `Non-binary` - Non-binary - - `Prefer not to respond` - Prefer not to respond + - `Non-binary` - Non Binary + - `Prefer not to respond` - Prefer Not To Respond """ phone: Optional[str] diff --git a/src/vitable_connect/types/enrollment.py b/src/vitable_connect/types/enrollment.py index e7694b9..3afb590 100644 --- a/src/vitable_connect/types/enrollment.py +++ b/src/vitable_connect/types/enrollment.py @@ -64,6 +64,8 @@ class Benefit(BaseModel): class Enrollment(BaseModel): + """One enrollment as it appears in a list row.""" + id: str """Unique enrollment identifier (enrl\\__\\**)""" diff --git a/src/vitable_connect/types/enrollment_retrieve_response.py b/src/vitable_connect/types/enrollment_retrieve_response.py index 22f2afb..71ddd56 100644 --- a/src/vitable_connect/types/enrollment_retrieve_response.py +++ b/src/vitable_connect/types/enrollment_retrieve_response.py @@ -1,12 +1,133 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from typing import Optional +from datetime import date, datetime +from typing_extensions import Literal + from .._models import BaseModel -from .enrollment import Enrollment +from .enrollment_status import EnrollmentStatus + +__all__ = ["EnrollmentRetrieveResponse", "Data", "DataBenefit"] + + +class DataBenefit(BaseModel): + """Nested benefit product summary""" + + id: str + """Benefit product ID (bprd\\__\\**)""" + + category: Literal["Medical", "Dental", "Vision", "Hospital"] + """ + - `Medical` - Medical + - `Dental` - Dental + - `Vision` - Vision + - `Hospital` - Hospital + """ + + name: str + """Display name of the benefit product""" + + product_code: Literal[ + "EBA", + "VPC", + "VPC_CORE", + "MEC", + "MEC2", + "MEC_PLUS", + "MVP", + "MVP2", + "MVPSL", + "MVPSL2", + "VD", + "VV", + "ICHRA", + "ICHRA_PREMIUM_PLUS", + "ICHRA_REIMBURSEMENT_ONLY", + ] + """ + - `EBA` - Eba Mec + - `VPC` - Vpc Enhanced + - `VPC_CORE` - Vpc Core + - `MEC` - Vpc Mec + - `MEC2` - Mec2 + - `MEC_PLUS` - Mec Plus + - `MVP` - Mvp + - `MVP2` - Mvp2 + - `MVPSL` - Mvpsl + - `MVPSL2` - Mvpsl2 + - `VD` - Dental + - `VV` - Vision + - `ICHRA` - Ichra + - `ICHRA_PREMIUM_PLUS` - Ichra Premium Plus + - `ICHRA_REIMBURSEMENT_ONLY` - Ichra Reimbursement Only + """ + + +class Data(BaseModel): + """A single enrollment, including the enrolled plan's documents. + + The plan documents are resolved one enrollment at a time and are therefore not part of the + list row. + """ + + id: str + """Unique enrollment identifier (enrl\\__\\**)""" + + answered_at: Optional[datetime] = None + """When the employee enrolled or waived""" -__all__ = ["EnrollmentRetrieveResponse"] + benefit: DataBenefit + """Nested benefit product summary""" + + coverage_end: Optional[date] = None + """Coverage period end date""" + + coverage_start: date + """Coverage period start date""" + + created_at: datetime + """When the enrollment was created""" + + employee_deduction_in_cents: Optional[int] = None + """Employee monthly payroll deduction in cents""" + + employee_id: str + """Employee ID (empl\\__\\**)""" + + employer_contribution_in_cents: Optional[int] = None + """Employer monthly contribution in cents""" + + employer_id: str + """Employer ID (empr\\__\\**)""" + + status: EnrollmentStatus + """ + - `pending` - Pending + - `enrolled` - Enrolled + - `waived` - Waived + - `inactive` - Inactive + """ + + terminated_at: Optional[datetime] = None + """When coverage was terminated""" + + updated_at: datetime + """When the enrollment was last updated""" + + sbc_url: Optional[str] = None + """ + Summary of Benefits and Coverage (SBC) document URL for the enrolled plan; null + when not on file. Only individual (ICHRA) plans carry an SBC — group plans have + no SBC on record and always resolve to null. + """ class EnrollmentRetrieveResponse(BaseModel): """Response containing a single enrollment resource.""" - data: Enrollment + data: Data + """A single enrollment, including the enrolled plan's documents. + + The plan documents are resolved one enrollment at a time and are therefore not + part of the list row. + """ diff --git a/src/vitable_connect/types/member_list_response.py b/src/vitable_connect/types/member_list_response.py index a7f4593..4bda986 100644 --- a/src/vitable_connect/types/member_list_response.py +++ b/src/vitable_connect/types/member_list_response.py @@ -1,6 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import Optional +from typing_extensions import Literal from .._models import BaseModel @@ -16,8 +17,134 @@ class Address(BaseModel): city: str """City name""" - state: str - """Two-letter state code (e.g., CA, NY)""" + state: Literal[ + "AL", + "AK", + "AZ", + "AR", + "CA", + "CO", + "CT", + "DC", + "DE", + "FL", + "GA", + "HI", + "ID", + "IL", + "IN", + "IA", + "KS", + "KY", + "LA", + "ME", + "MD", + "MA", + "MI", + "MN", + "MS", + "MO", + "MT", + "NE", + "NV", + "NH", + "NJ", + "NM", + "NY", + "NC", + "ND", + "OH", + "OK", + "OR", + "PA", + "RI", + "SC", + "SD", + "TN", + "TX", + "UT", + "VT", + "VA", + "WA", + "WI", + "WV", + "WY", + "PR", + "GU", + "AS", + "VI", + "MP", + "MH", + "PW", + "FM", + "AE", + "AA", + "AP", + ] + """ + - `AL` - AL + - `AK` - AK + - `AZ` - AZ + - `AR` - AR + - `CA` - CA + - `CO` - CO + - `CT` - CT + - `DC` - DC + - `DE` - DE + - `FL` - FL + - `GA` - GA + - `HI` - HI + - `ID` - ID + - `IL` - IL + - `IN` - IN + - `IA` - IA + - `KS` - KS + - `KY` - KY + - `LA` - LA + - `ME` - ME + - `MD` - MD + - `MA` - MA + - `MI` - MI + - `MN` - MN + - `MS` - MS + - `MO` - MO + - `MT` - MT + - `NE` - NE + - `NV` - NV + - `NH` - NH + - `NJ` - NJ + - `NM` - NM + - `NY` - NY + - `NC` - NC + - `ND` - ND + - `OH` - OH + - `OK` - OK + - `OR` - OR + - `PA` - PA + - `RI` - RI + - `SC` - SC + - `SD` - SD + - `TN` - TN + - `TX` - TX + - `UT` - UT + - `VT` - VT + - `VA` - VA + - `WA` - WA + - `WI` - WI + - `WV` - WV + - `WY` - WY + - `PR` - PR + - `GU` - GU + - `AS` - AS + - `VI` - VI + - `MP` - MP + - `MH` - MH + - `PW` - PW + - `FM` - FM + - `AE` - AE + - `AA` - AA + - `AP` - AP + """ zipcode: str """ZIP code (5 or 9 digit)""" diff --git a/src/vitable_connect/types/member_retrieve_response.py b/src/vitable_connect/types/member_retrieve_response.py index 6bf816d..e4dad37 100644 --- a/src/vitable_connect/types/member_retrieve_response.py +++ b/src/vitable_connect/types/member_retrieve_response.py @@ -18,8 +18,134 @@ class DataAddress(BaseModel): city: str """City name""" - state: str - """Two-letter state code (e.g., CA, NY)""" + state: Literal[ + "AL", + "AK", + "AZ", + "AR", + "CA", + "CO", + "CT", + "DC", + "DE", + "FL", + "GA", + "HI", + "ID", + "IL", + "IN", + "IA", + "KS", + "KY", + "LA", + "ME", + "MD", + "MA", + "MI", + "MN", + "MS", + "MO", + "MT", + "NE", + "NV", + "NH", + "NJ", + "NM", + "NY", + "NC", + "ND", + "OH", + "OK", + "OR", + "PA", + "RI", + "SC", + "SD", + "TN", + "TX", + "UT", + "VT", + "VA", + "WA", + "WI", + "WV", + "WY", + "PR", + "GU", + "AS", + "VI", + "MP", + "MH", + "PW", + "FM", + "AE", + "AA", + "AP", + ] + """ + - `AL` - AL + - `AK` - AK + - `AZ` - AZ + - `AR` - AR + - `CA` - CA + - `CO` - CO + - `CT` - CT + - `DC` - DC + - `DE` - DE + - `FL` - FL + - `GA` - GA + - `HI` - HI + - `ID` - ID + - `IL` - IL + - `IN` - IN + - `IA` - IA + - `KS` - KS + - `KY` - KY + - `LA` - LA + - `ME` - ME + - `MD` - MD + - `MA` - MA + - `MI` - MI + - `MN` - MN + - `MS` - MS + - `MO` - MO + - `MT` - MT + - `NE` - NE + - `NV` - NV + - `NH` - NH + - `NJ` - NJ + - `NM` - NM + - `NY` - NY + - `NC` - NC + - `ND` - ND + - `OH` - OH + - `OK` - OK + - `OR` - OR + - `PA` - PA + - `RI` - RI + - `SC` - SC + - `SD` - SD + - `TN` - TN + - `TX` - TX + - `UT` - UT + - `VT` - VT + - `VA` - VA + - `WA` - WA + - `WI` - WI + - `WV` - WV + - `WY` - WY + - `PR` - PR + - `GU` - GU + - `AS` - AS + - `VI` - VI + - `MP` - MP + - `MH` - MH + - `PW` - PW + - `FM` - FM + - `AE` - AE + - `AA` - AA + - `AP` - AP + """ zipcode: str """ZIP code (5 or 9 digit)""" @@ -49,7 +175,7 @@ class Data(BaseModel): """Member's legal last name""" name: str - """Member's full name""" + """Member's full legal name""" status: Literal["onboarded", "pending_onboarding"] """Member profile status (onboarded or pending onboarding)""" @@ -60,14 +186,49 @@ class Data(BaseModel): email: Optional[str] = None """Email address""" + gender: Optional[Literal["Male", "Female", "Transgender", "Non-binary", "Prefer not to respond"]] = None + """ + - `Male` - Male + - `Female` - Female + - `Transgender` - Transgender + - `Non-binary` - Non Binary + - `Prefer not to respond` - Prefer Not To Respond + """ + + middle_name: Optional[str] = None + """Member's legal middle name""" + phone: Optional[str] = None """Phone number (10-digit US domestic string)""" - preferred_language: Optional[str] = None - """Member's preferred language code (e.g., en, es)""" + preferred_language: Optional[Literal["en", "es", "zh", "ru", "sw", "th"]] = None + """ + - `en` - English + - `es` - Spanish + - `zh` - Chinese + - `ru` - Russian + - `sw` - Swahili + - `th` - Thai + """ + + sex_at_birth: Optional[Literal["Male", "Female", "Other", "Unknown"]] = None + """ + - `Male` - Male + - `Female` - Female + - `Other` - Other + - `Unknown` - Unknown + """ - sex_at_birth: Optional[str] = None - """Sex assigned at birth, if provided""" + suffix: Optional[Literal["Sr", "Jr", "I", "II", "III", "IV", "V"]] = None + """ + - `Sr` - Sr + - `Jr` - Jr + - `I` - I + - `II` - II + - `III` - III + - `IV` - IV + - `V` - V + """ tobacco_status: Optional[bool] = None """Whether the member uses tobacco, if known""" diff --git a/tests/api_resources/test_members.py b/tests/api_resources/test_members.py index ee43b05..4c81407 100644 --- a/tests/api_resources/test_members.py +++ b/tests/api_resources/test_members.py @@ -31,7 +31,7 @@ class TestMembers: @parametrize def test_method_retrieve(self, client: VitableConnect) -> None: member = client.members.retrieve( - "member_id", + "mbr_abc123def456", ) assert_matches_type(MemberRetrieveResponse, member, path=["response"]) @@ -39,7 +39,7 @@ def test_method_retrieve(self, client: VitableConnect) -> None: @parametrize def test_raw_response_retrieve(self, client: VitableConnect) -> None: response = client.members.with_raw_response.retrieve( - "member_id", + "mbr_abc123def456", ) assert response.is_closed is True @@ -51,7 +51,7 @@ def test_raw_response_retrieve(self, client: VitableConnect) -> None: @parametrize def test_streaming_response_retrieve(self, client: VitableConnect) -> None: with client.members.with_streaming_response.retrieve( - "member_id", + "mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -111,7 +111,7 @@ def test_streaming_response_list(self, client: VitableConnect) -> None: @parametrize def test_method_list_dependents(self, client: VitableConnect) -> None: member = client.members.list_dependents( - "member_id", + "mbr_abc123def456", ) assert_matches_type(MemberListDependentsResponse, member, path=["response"]) @@ -119,7 +119,7 @@ def test_method_list_dependents(self, client: VitableConnect) -> None: @parametrize def test_raw_response_list_dependents(self, client: VitableConnect) -> None: response = client.members.with_raw_response.list_dependents( - "member_id", + "mbr_abc123def456", ) assert response.is_closed is True @@ -131,7 +131,7 @@ def test_raw_response_list_dependents(self, client: VitableConnect) -> None: @parametrize def test_streaming_response_list_dependents(self, client: VitableConnect) -> None: with client.members.with_streaming_response.list_dependents( - "member_id", + "mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -153,7 +153,7 @@ def test_path_params_list_dependents(self, client: VitableConnect) -> None: @parametrize def test_method_list_employments(self, client: VitableConnect) -> None: member = client.members.list_employments( - "member_id", + "mbr_abc123def456", ) assert_matches_type(MemberListEmploymentsResponse, member, path=["response"]) @@ -161,7 +161,7 @@ def test_method_list_employments(self, client: VitableConnect) -> None: @parametrize def test_raw_response_list_employments(self, client: VitableConnect) -> None: response = client.members.with_raw_response.list_employments( - "member_id", + "mbr_abc123def456", ) assert response.is_closed is True @@ -173,7 +173,7 @@ def test_raw_response_list_employments(self, client: VitableConnect) -> None: @parametrize def test_streaming_response_list_employments(self, client: VitableConnect) -> None: with client.members.with_streaming_response.list_employments( - "member_id", + "mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -195,7 +195,7 @@ def test_path_params_list_employments(self, client: VitableConnect) -> None: @parametrize def test_method_list_enrollments(self, client: VitableConnect) -> None: member = client.members.list_enrollments( - "member_id", + "mbr_abc123def456", ) assert_matches_type(MemberListEnrollmentsResponse, member, path=["response"]) @@ -203,7 +203,7 @@ def test_method_list_enrollments(self, client: VitableConnect) -> None: @parametrize def test_raw_response_list_enrollments(self, client: VitableConnect) -> None: response = client.members.with_raw_response.list_enrollments( - "member_id", + "mbr_abc123def456", ) assert response.is_closed is True @@ -215,7 +215,7 @@ def test_raw_response_list_enrollments(self, client: VitableConnect) -> None: @parametrize def test_streaming_response_list_enrollments(self, client: VitableConnect) -> None: with client.members.with_streaming_response.list_enrollments( - "member_id", + "mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -237,7 +237,7 @@ def test_path_params_list_enrollments(self, client: VitableConnect) -> None: @parametrize def test_method_list_id_cards(self, client: VitableConnect) -> None: member = client.members.list_id_cards( - "member_id", + "mbr_abc123def456", ) assert_matches_type(MemberListIDCardsResponse, member, path=["response"]) @@ -245,7 +245,7 @@ def test_method_list_id_cards(self, client: VitableConnect) -> None: @parametrize def test_raw_response_list_id_cards(self, client: VitableConnect) -> None: response = client.members.with_raw_response.list_id_cards( - "member_id", + "mbr_abc123def456", ) assert response.is_closed is True @@ -257,7 +257,7 @@ def test_raw_response_list_id_cards(self, client: VitableConnect) -> None: @parametrize def test_streaming_response_list_id_cards(self, client: VitableConnect) -> None: with client.members.with_streaming_response.list_id_cards( - "member_id", + "mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -279,7 +279,7 @@ def test_path_params_list_id_cards(self, client: VitableConnect) -> None: @parametrize def test_method_list_qualifying_life_events(self, client: VitableConnect) -> None: member = client.members.list_qualifying_life_events( - member_id="member_id", + member_id="mbr_abc123def456", ) assert_matches_type(SyncPageNumberPage[MemberListQualifyingLifeEventsResponse], member, path=["response"]) @@ -287,7 +287,7 @@ def test_method_list_qualifying_life_events(self, client: VitableConnect) -> Non @parametrize def test_method_list_qualifying_life_events_with_all_params(self, client: VitableConnect) -> None: member = client.members.list_qualifying_life_events( - member_id="member_id", + member_id="mbr_abc123def456", limit=20, page=1, status="approved", @@ -298,7 +298,7 @@ def test_method_list_qualifying_life_events_with_all_params(self, client: Vitabl @parametrize def test_raw_response_list_qualifying_life_events(self, client: VitableConnect) -> None: response = client.members.with_raw_response.list_qualifying_life_events( - member_id="member_id", + member_id="mbr_abc123def456", ) assert response.is_closed is True @@ -310,7 +310,7 @@ def test_raw_response_list_qualifying_life_events(self, client: VitableConnect) @parametrize def test_streaming_response_list_qualifying_life_events(self, client: VitableConnect) -> None: with client.members.with_streaming_response.list_qualifying_life_events( - member_id="member_id", + member_id="mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -332,7 +332,7 @@ def test_path_params_list_qualifying_life_events(self, client: VitableConnect) - @parametrize def test_method_retrieve_household(self, client: VitableConnect) -> None: member = client.members.retrieve_household( - "member_id", + "mbr_abc123def456", ) assert_matches_type(MemberRetrieveHouseholdResponse, member, path=["response"]) @@ -340,7 +340,7 @@ def test_method_retrieve_household(self, client: VitableConnect) -> None: @parametrize def test_raw_response_retrieve_household(self, client: VitableConnect) -> None: response = client.members.with_raw_response.retrieve_household( - "member_id", + "mbr_abc123def456", ) assert response.is_closed is True @@ -352,7 +352,7 @@ def test_raw_response_retrieve_household(self, client: VitableConnect) -> None: @parametrize def test_streaming_response_retrieve_household(self, client: VitableConnect) -> None: with client.members.with_streaming_response.retrieve_household( - "member_id", + "mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -380,7 +380,7 @@ class TestAsyncMembers: @parametrize async def test_method_retrieve(self, async_client: AsyncVitableConnect) -> None: member = await async_client.members.retrieve( - "member_id", + "mbr_abc123def456", ) assert_matches_type(MemberRetrieveResponse, member, path=["response"]) @@ -388,7 +388,7 @@ async def test_method_retrieve(self, async_client: AsyncVitableConnect) -> None: @parametrize async def test_raw_response_retrieve(self, async_client: AsyncVitableConnect) -> None: response = await async_client.members.with_raw_response.retrieve( - "member_id", + "mbr_abc123def456", ) assert response.is_closed is True @@ -400,7 +400,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncVitableConnect) -> @parametrize async def test_streaming_response_retrieve(self, async_client: AsyncVitableConnect) -> None: async with async_client.members.with_streaming_response.retrieve( - "member_id", + "mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -460,7 +460,7 @@ async def test_streaming_response_list(self, async_client: AsyncVitableConnect) @parametrize async def test_method_list_dependents(self, async_client: AsyncVitableConnect) -> None: member = await async_client.members.list_dependents( - "member_id", + "mbr_abc123def456", ) assert_matches_type(MemberListDependentsResponse, member, path=["response"]) @@ -468,7 +468,7 @@ async def test_method_list_dependents(self, async_client: AsyncVitableConnect) - @parametrize async def test_raw_response_list_dependents(self, async_client: AsyncVitableConnect) -> None: response = await async_client.members.with_raw_response.list_dependents( - "member_id", + "mbr_abc123def456", ) assert response.is_closed is True @@ -480,7 +480,7 @@ async def test_raw_response_list_dependents(self, async_client: AsyncVitableConn @parametrize async def test_streaming_response_list_dependents(self, async_client: AsyncVitableConnect) -> None: async with async_client.members.with_streaming_response.list_dependents( - "member_id", + "mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -502,7 +502,7 @@ async def test_path_params_list_dependents(self, async_client: AsyncVitableConne @parametrize async def test_method_list_employments(self, async_client: AsyncVitableConnect) -> None: member = await async_client.members.list_employments( - "member_id", + "mbr_abc123def456", ) assert_matches_type(MemberListEmploymentsResponse, member, path=["response"]) @@ -510,7 +510,7 @@ async def test_method_list_employments(self, async_client: AsyncVitableConnect) @parametrize async def test_raw_response_list_employments(self, async_client: AsyncVitableConnect) -> None: response = await async_client.members.with_raw_response.list_employments( - "member_id", + "mbr_abc123def456", ) assert response.is_closed is True @@ -522,7 +522,7 @@ async def test_raw_response_list_employments(self, async_client: AsyncVitableCon @parametrize async def test_streaming_response_list_employments(self, async_client: AsyncVitableConnect) -> None: async with async_client.members.with_streaming_response.list_employments( - "member_id", + "mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -544,7 +544,7 @@ async def test_path_params_list_employments(self, async_client: AsyncVitableConn @parametrize async def test_method_list_enrollments(self, async_client: AsyncVitableConnect) -> None: member = await async_client.members.list_enrollments( - "member_id", + "mbr_abc123def456", ) assert_matches_type(MemberListEnrollmentsResponse, member, path=["response"]) @@ -552,7 +552,7 @@ async def test_method_list_enrollments(self, async_client: AsyncVitableConnect) @parametrize async def test_raw_response_list_enrollments(self, async_client: AsyncVitableConnect) -> None: response = await async_client.members.with_raw_response.list_enrollments( - "member_id", + "mbr_abc123def456", ) assert response.is_closed is True @@ -564,7 +564,7 @@ async def test_raw_response_list_enrollments(self, async_client: AsyncVitableCon @parametrize async def test_streaming_response_list_enrollments(self, async_client: AsyncVitableConnect) -> None: async with async_client.members.with_streaming_response.list_enrollments( - "member_id", + "mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -586,7 +586,7 @@ async def test_path_params_list_enrollments(self, async_client: AsyncVitableConn @parametrize async def test_method_list_id_cards(self, async_client: AsyncVitableConnect) -> None: member = await async_client.members.list_id_cards( - "member_id", + "mbr_abc123def456", ) assert_matches_type(MemberListIDCardsResponse, member, path=["response"]) @@ -594,7 +594,7 @@ async def test_method_list_id_cards(self, async_client: AsyncVitableConnect) -> @parametrize async def test_raw_response_list_id_cards(self, async_client: AsyncVitableConnect) -> None: response = await async_client.members.with_raw_response.list_id_cards( - "member_id", + "mbr_abc123def456", ) assert response.is_closed is True @@ -606,7 +606,7 @@ async def test_raw_response_list_id_cards(self, async_client: AsyncVitableConnec @parametrize async def test_streaming_response_list_id_cards(self, async_client: AsyncVitableConnect) -> None: async with async_client.members.with_streaming_response.list_id_cards( - "member_id", + "mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -628,7 +628,7 @@ async def test_path_params_list_id_cards(self, async_client: AsyncVitableConnect @parametrize async def test_method_list_qualifying_life_events(self, async_client: AsyncVitableConnect) -> None: member = await async_client.members.list_qualifying_life_events( - member_id="member_id", + member_id="mbr_abc123def456", ) assert_matches_type(AsyncPageNumberPage[MemberListQualifyingLifeEventsResponse], member, path=["response"]) @@ -636,7 +636,7 @@ async def test_method_list_qualifying_life_events(self, async_client: AsyncVitab @parametrize async def test_method_list_qualifying_life_events_with_all_params(self, async_client: AsyncVitableConnect) -> None: member = await async_client.members.list_qualifying_life_events( - member_id="member_id", + member_id="mbr_abc123def456", limit=20, page=1, status="approved", @@ -647,7 +647,7 @@ async def test_method_list_qualifying_life_events_with_all_params(self, async_cl @parametrize async def test_raw_response_list_qualifying_life_events(self, async_client: AsyncVitableConnect) -> None: response = await async_client.members.with_raw_response.list_qualifying_life_events( - member_id="member_id", + member_id="mbr_abc123def456", ) assert response.is_closed is True @@ -659,7 +659,7 @@ async def test_raw_response_list_qualifying_life_events(self, async_client: Asyn @parametrize async def test_streaming_response_list_qualifying_life_events(self, async_client: AsyncVitableConnect) -> None: async with async_client.members.with_streaming_response.list_qualifying_life_events( - member_id="member_id", + member_id="mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -681,7 +681,7 @@ async def test_path_params_list_qualifying_life_events(self, async_client: Async @parametrize async def test_method_retrieve_household(self, async_client: AsyncVitableConnect) -> None: member = await async_client.members.retrieve_household( - "member_id", + "mbr_abc123def456", ) assert_matches_type(MemberRetrieveHouseholdResponse, member, path=["response"]) @@ -689,7 +689,7 @@ async def test_method_retrieve_household(self, async_client: AsyncVitableConnect @parametrize async def test_raw_response_retrieve_household(self, async_client: AsyncVitableConnect) -> None: response = await async_client.members.with_raw_response.retrieve_household( - "member_id", + "mbr_abc123def456", ) assert response.is_closed is True @@ -701,7 +701,7 @@ async def test_raw_response_retrieve_household(self, async_client: AsyncVitableC @parametrize async def test_streaming_response_retrieve_household(self, async_client: AsyncVitableConnect) -> None: async with async_client.members.with_streaming_response.retrieve_household( - "member_id", + "mbr_abc123def456", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" From b7c3006f8caca5dc7410df4d95a0564394b47248 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 26 Aug 2026 15:32:19 +0000 Subject: [PATCH 05/10] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 1f5e5b4..61d27c8 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 45 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-439ab918f9d9a7afa251ac75d7799cffb98dfa2e15afcb37932ce377835994d1.yml -openapi_spec_hash: 20a93e2fc4ef3e1f24ecceb29103f8b0 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-4a3212ece8a1312a919e8f83afe8afe552e690ddbefdc09bec6166f2fca086c4.yml +openapi_spec_hash: ea7d83c6b3c714276b69829cb63ce466 config_hash: 0b4d62a9a1e0cc71998bcfc3d15c4db7 From dbc5eccd1e518cfde70217fb3f768c2753f08ba0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 27 Aug 2026 17:30:18 +0000 Subject: [PATCH 06/10] feat(api): api update --- .stats.yml | 4 ++-- src/vitable_connect/resources/employers.py | 16 ++++++++++------ .../types/employer_list_params.py | 6 +++++- .../types/member_retrieve_response.py | 6 ++++++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/.stats.yml b/.stats.yml index 61d27c8..ca14496 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 45 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-4a3212ece8a1312a919e8f83afe8afe552e690ddbefdc09bec6166f2fca086c4.yml -openapi_spec_hash: ea7d83c6b3c714276b69829cb63ce466 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-4de6983c584a057f5e39aab7ebd3299e4370b653fa29b0b028c9ec19036ecd41.yml +openapi_spec_hash: edcce8e119b6afff7964cfff6a0c0d2b config_hash: 0b4d62a9a1e0cc71998bcfc3d15c4db7 diff --git a/src/vitable_connect/resources/employers.py b/src/vitable_connect/resources/employers.py index 5b33f02..c911356 100644 --- a/src/vitable_connect/resources/employers.py +++ b/src/vitable_connect/resources/employers.py @@ -257,8 +257,9 @@ def list( benefit-lifecycle stage) merged with the employer's flat CRM fields (legal name, EIN, contact, address, timestamps). The book is derived from the authenticated principal: one organization's employers, or every organization's for a caller - whose reach is not a single organization. Supports name search, - benefit-family/lifecycle/HRIS filters, and page/limit pagination. + whose reach is not a single organization. Supports search by display name, legal + name or exact EIN, benefit-family/lifecycle/HRIS filters, and page/limit + pagination. Args: benefit_family: Filter to employers with at least one active benefit in these families. @@ -278,7 +279,8 @@ def list( page: Page number. - search: Case-insensitive employer-name substring filter. + search: Employer filter. Matches the display name or the legal name case-insensitively + as a substring, or the EIN exactly (with or without its dash). extra_headers: Send extra headers @@ -1228,8 +1230,9 @@ def list( benefit-lifecycle stage) merged with the employer's flat CRM fields (legal name, EIN, contact, address, timestamps). The book is derived from the authenticated principal: one organization's employers, or every organization's for a caller - whose reach is not a single organization. Supports name search, - benefit-family/lifecycle/HRIS filters, and page/limit pagination. + whose reach is not a single organization. Supports search by display name, legal + name or exact EIN, benefit-family/lifecycle/HRIS filters, and page/limit + pagination. Args: benefit_family: Filter to employers with at least one active benefit in these families. @@ -1249,7 +1252,8 @@ def list( page: Page number. - search: Case-insensitive employer-name substring filter. + search: Employer filter. Matches the display name or the legal name case-insensitively + as a substring, or the EIN exactly (with or without its dash). extra_headers: Send extra headers diff --git a/src/vitable_connect/types/employer_list_params.py b/src/vitable_connect/types/employer_list_params.py index e360d6d..76e0c29 100644 --- a/src/vitable_connect/types/employer_list_params.py +++ b/src/vitable_connect/types/employer_list_params.py @@ -40,4 +40,8 @@ class EmployerListParams(TypedDict, total=False): """Page number.""" search: Optional[str] - """Case-insensitive employer-name substring filter.""" + """Employer filter. + + Matches the display name or the legal name case-insensitively as a substring, or + the EIN exactly (with or without its dash). + """ diff --git a/src/vitable_connect/types/member_retrieve_response.py b/src/vitable_connect/types/member_retrieve_response.py index e4dad37..d75e8b4 100644 --- a/src/vitable_connect/types/member_retrieve_response.py +++ b/src/vitable_connect/types/member_retrieve_response.py @@ -195,6 +195,12 @@ class Data(BaseModel): - `Prefer not to respond` - Prefer Not To Respond """ + marital_status: Optional[Literal["Single", "Married"]] = None + """ + - `Single` - Single + - `Married` - Married + """ + middle_name: Optional[str] = None """Member's legal middle name""" From 137ed3fe713507914856d71e3fc318a7991483bf Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 31 Aug 2026 18:50:48 +0000 Subject: [PATCH 07/10] feat(api): api update --- .stats.yml | 4 +-- src/vitable_connect/resources/employers.py | 14 ++++---- src/vitable_connect/resources/members.py | 20 ++++++----- .../types/employer_list_params.py | 3 +- .../types/member_list_enrollments_response.py | 34 ++++++++++++++++++- 5 files changed, 57 insertions(+), 18 deletions(-) diff --git a/.stats.yml b/.stats.yml index ca14496..b1d360d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 45 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-4de6983c584a057f5e39aab7ebd3299e4370b653fa29b0b028c9ec19036ecd41.yml -openapi_spec_hash: edcce8e119b6afff7964cfff6a0c0d2b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-9d872b0ec44e36f57e59987ccbe088130190032b2fa5ff4a83a6ea62a05ce6b2.yml +openapi_spec_hash: 041f645c9a6d4d1a93ed338c054b8796 config_hash: 0b4d62a9a1e0cc71998bcfc3d15c4db7 diff --git a/src/vitable_connect/resources/employers.py b/src/vitable_connect/resources/employers.py index c911356..03c6efb 100644 --- a/src/vitable_connect/resources/employers.py +++ b/src/vitable_connect/resources/employers.py @@ -258,8 +258,8 @@ def list( EIN, contact, address, timestamps). The book is derived from the authenticated principal: one organization's employers, or every organization's for a caller whose reach is not a single organization. Supports search by display name, legal - name or exact EIN, benefit-family/lifecycle/HRIS filters, and page/limit - pagination. + name, or exact EIN, employer id or contact email, benefit-family/lifecycle/HRIS + filters, and page/limit pagination. Args: benefit_family: Filter to employers with at least one active benefit in these families. @@ -280,7 +280,8 @@ def list( page: Page number. search: Employer filter. Matches the display name or the legal name case-insensitively - as a substring, or the EIN exactly (with or without its dash). + as a substring, or one of these exactly: the EIN (with or without its dash), the + employer id, or the contact email of one of the employer's non-disabled admins. extra_headers: Send extra headers @@ -1231,8 +1232,8 @@ def list( EIN, contact, address, timestamps). The book is derived from the authenticated principal: one organization's employers, or every organization's for a caller whose reach is not a single organization. Supports search by display name, legal - name or exact EIN, benefit-family/lifecycle/HRIS filters, and page/limit - pagination. + name, or exact EIN, employer id or contact email, benefit-family/lifecycle/HRIS + filters, and page/limit pagination. Args: benefit_family: Filter to employers with at least one active benefit in these families. @@ -1253,7 +1254,8 @@ def list( page: Page number. search: Employer filter. Matches the display name or the legal name case-insensitively - as a substring, or the EIN exactly (with or without its dash). + as a substring, or one of these exactly: the EIN (with or without its dash), the + employer id, or the contact email of one of the employer's non-disabled admins. extra_headers: Send extra headers diff --git a/src/vitable_connect/resources/members.py b/src/vitable_connect/resources/members.py index b3367a4..92ee791 100644 --- a/src/vitable_connect/resources/members.py +++ b/src/vitable_connect/resources/members.py @@ -238,10 +238,12 @@ def list_enrollments( (`coverage_end`), the separate pre-effective cancellation boundary (`cancelled_date`), and the distinct benefit plan-year boundary (`plan_year_coverage_end`) used to determine whether the plan year itself has - ended, whether a qualifying life event would currently be required for reissue - under the product/open-enrollment rule, enrollment/open-enrollment window, and - two statuses: `election_status` (what the member answered) and `policy_status` - (what became of their coverage, null unless they enrolled). Every row includes a + ended, the date the enrollment record was created (`issued_date`, the value Ops + labels Issued on, reported for every row whatever the member answered), whether + a qualifying life event would currently be required for reissue under the + product/open-enrollment rule, enrollment/open-enrollment window, and two + statuses: `election_status` (what the member answered) and `policy_status` (what + became of their coverage, null unless they enrolled). Every row includes a stable enrollment ID and the exact employer and benefit plan-year IDs used to fetch that row's plan-year detail. The full list is returned across all states so the client derives active plans (effective and upcoming) and the enrollment @@ -624,10 +626,12 @@ async def list_enrollments( (`coverage_end`), the separate pre-effective cancellation boundary (`cancelled_date`), and the distinct benefit plan-year boundary (`plan_year_coverage_end`) used to determine whether the plan year itself has - ended, whether a qualifying life event would currently be required for reissue - under the product/open-enrollment rule, enrollment/open-enrollment window, and - two statuses: `election_status` (what the member answered) and `policy_status` - (what became of their coverage, null unless they enrolled). Every row includes a + ended, the date the enrollment record was created (`issued_date`, the value Ops + labels Issued on, reported for every row whatever the member answered), whether + a qualifying life event would currently be required for reissue under the + product/open-enrollment rule, enrollment/open-enrollment window, and two + statuses: `election_status` (what the member answered) and `policy_status` (what + became of their coverage, null unless they enrolled). Every row includes a stable enrollment ID and the exact employer and benefit plan-year IDs used to fetch that row's plan-year detail. The full list is returned across all states so the client derives active plans (effective and upcoming) and the enrollment diff --git a/src/vitable_connect/types/employer_list_params.py b/src/vitable_connect/types/employer_list_params.py index 76e0c29..e762199 100644 --- a/src/vitable_connect/types/employer_list_params.py +++ b/src/vitable_connect/types/employer_list_params.py @@ -43,5 +43,6 @@ class EmployerListParams(TypedDict, total=False): """Employer filter. Matches the display name or the legal name case-insensitively as a substring, or - the EIN exactly (with or without its dash). + one of these exactly: the EIN (with or without its dash), the employer id, or + the contact email of one of the employer's non-disabled admins. """ diff --git a/src/vitable_connect/types/member_list_enrollments_response.py b/src/vitable_connect/types/member_list_enrollments_response.py index e5c29e3..0f9159d 100644 --- a/src/vitable_connect/types/member_list_enrollments_response.py +++ b/src/vitable_connect/types/member_list_enrollments_response.py @@ -6,7 +6,23 @@ from .._models import BaseModel -__all__ = ["MemberListEnrollmentsResponse", "Data"] +__all__ = ["MemberListEnrollmentsResponse", "Data", "DataIchraAffordability"] + + +class DataIchraAffordability(BaseModel): + """ + How this member's monthly share compares with the ACA affordability line for their income. Null unless the row is an ICHRA election whose plan year, premium and the member's individual income are all on file. + """ + + is_affordable: bool + """ + True when `employee_deduction_in_cents` is at or below the IRS affordability + percentage of the member's individual income for the year this plan year + started. It measures what the member pays for the plan they chose, so it is + **not** a statement that the employer's offer satisfies the ACA employer + mandate: that test is benchmarked against the lowest-cost silver plan at + self-only coverage, which this does not use. + """ class Data(BaseModel): @@ -49,6 +65,13 @@ class Data(BaseModel): enrollment_window_start: date """Enrollment / open-enrollment window start date (YYYY-MM-DD)""" + ichra_affordability: Optional[DataIchraAffordability] = None + """ + How this member's monthly share compares with the ACA affordability line for + their income. Null unless the row is an ICHRA election whose plan year, premium + and the member's individual income are all on file. + """ + in_last_month_of_coverage: bool """ True when today falls in the final month of the plan-year coverage window; @@ -61,6 +84,15 @@ class Data(BaseModel): drives enrollment-action availability on the client. """ + issued_date: date + """ + Date the enrollment record was created (YYYY-MM-DD), the value Ops labels Issued + on. Present on every row whatever the member answered, and distinct from + `coverage_start`. It does not imply the member could answer the enrollment on + that date; the window they can answer in is + `enrollment_window_start`/`enrollment_window_end`. + """ + plan_year_coverage_end: Optional[date] = None """ Benefit plan-year coverage end date (YYYY-MM-DD), distinct from this From a054758a085dfe77508e13a8a72cc1acb2fb51ba Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2026 15:17:33 +0000 Subject: [PATCH 08/10] feat(api): api update --- .stats.yml | 4 +-- src/vitable_connect/resources/enrollments.py | 28 +++++++++---------- .../types/enrollment_reissue_params.py | 2 +- .../types/enrollment_terminate_params.py | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.stats.yml b/.stats.yml index b1d360d..5804410 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 45 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-9d872b0ec44e36f57e59987ccbe088130190032b2fa5ff4a83a6ea62a05ce6b2.yml -openapi_spec_hash: 041f645c9a6d4d1a93ed338c054b8796 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-3f53a93bd1945af083bb7db80295003ec3181c273e55dbe63b77b17c3eb2a025.yml +openapi_spec_hash: 5aab97a00d10ab9ebfe5b1db937b3f0b config_hash: 0b4d62a9a1e0cc71998bcfc3d15c4db7 diff --git a/src/vitable_connect/resources/enrollments.py b/src/vitable_connect/resources/enrollments.py index 357204b..7cfd4fd 100644 --- a/src/vitable_connect/resources/enrollments.py +++ b/src/vitable_connect/resources/enrollments.py @@ -103,8 +103,8 @@ def reissue( Closes the targeted enrollment and creates a new unanswered enrollment for the same member and plan year. VPC never requires a qualifying life event; other products require an accepted, member-owned event outside open enrollment. - User-backed callers must provide a reason; it is optional for userless - organization callers. Tenant mismatches return a non-disclosing 404 before the + User-backed callers must provide a reason; it is optional for organization + API-key callers. Tenant mismatches return a non-disclosing 404 before the request body is validated. Args: @@ -113,7 +113,7 @@ def reissue( qualifying_life_event_id: Accepted member qualifying life event identifier (qle\\__\\**) reason: Audit reason for the reissue; required for user-backed callers and optional for - userless organization callers + long-lived organization API-key callers ticket_number: Optional support or operational ticket number @@ -161,9 +161,9 @@ def terminate( An accepted qualifying life event owned by the enrollment member is required unless the plan is VPC or ICHRA. - User-backed callers must provide a reason; it is optional for userless - organization callers. API keys may act across the caller organization's book. - Tenant mismatches return the same non-disclosing 404 before the request body is + User-backed callers must provide a reason; it is optional for organization + API-key callers. API keys may act across the caller organization's book. Tenant + mismatches return the same non-disclosing 404 before the request body is validated. Args: @@ -172,7 +172,7 @@ def terminate( qualifying_life_event_id: Accepted member qualifying life event identifier (qle\\__\\**) reason: Audit reason for the termination; required for user-backed callers and optional - for userless organization callers + for long-lived organization API-key callers ticket_number: Optional support or operational ticket number @@ -283,8 +283,8 @@ async def reissue( Closes the targeted enrollment and creates a new unanswered enrollment for the same member and plan year. VPC never requires a qualifying life event; other products require an accepted, member-owned event outside open enrollment. - User-backed callers must provide a reason; it is optional for userless - organization callers. Tenant mismatches return a non-disclosing 404 before the + User-backed callers must provide a reason; it is optional for organization + API-key callers. Tenant mismatches return a non-disclosing 404 before the request body is validated. Args: @@ -293,7 +293,7 @@ async def reissue( qualifying_life_event_id: Accepted member qualifying life event identifier (qle\\__\\**) reason: Audit reason for the reissue; required for user-backed callers and optional for - userless organization callers + long-lived organization API-key callers ticket_number: Optional support or operational ticket number @@ -341,9 +341,9 @@ async def terminate( An accepted qualifying life event owned by the enrollment member is required unless the plan is VPC or ICHRA. - User-backed callers must provide a reason; it is optional for userless - organization callers. API keys may act across the caller organization's book. - Tenant mismatches return the same non-disclosing 404 before the request body is + User-backed callers must provide a reason; it is optional for organization + API-key callers. API keys may act across the caller organization's book. Tenant + mismatches return the same non-disclosing 404 before the request body is validated. Args: @@ -352,7 +352,7 @@ async def terminate( qualifying_life_event_id: Accepted member qualifying life event identifier (qle\\__\\**) reason: Audit reason for the termination; required for user-backed callers and optional - for userless organization callers + for long-lived organization API-key callers ticket_number: Optional support or operational ticket number diff --git a/src/vitable_connect/types/enrollment_reissue_params.py b/src/vitable_connect/types/enrollment_reissue_params.py index bb02828..a0fa2e5 100644 --- a/src/vitable_connect/types/enrollment_reissue_params.py +++ b/src/vitable_connect/types/enrollment_reissue_params.py @@ -15,7 +15,7 @@ class EnrollmentReissueParams(TypedDict, total=False): reason: Optional[str] """ Audit reason for the reissue; required for user-backed callers and optional for - userless organization callers + long-lived organization API-key callers """ ticket_number: Optional[str] diff --git a/src/vitable_connect/types/enrollment_terminate_params.py b/src/vitable_connect/types/enrollment_terminate_params.py index ff554e4..28c7273 100644 --- a/src/vitable_connect/types/enrollment_terminate_params.py +++ b/src/vitable_connect/types/enrollment_terminate_params.py @@ -15,7 +15,7 @@ class EnrollmentTerminateParams(TypedDict, total=False): reason: Optional[str] """ Audit reason for the termination; required for user-backed callers and optional - for userless organization callers + for long-lived organization API-key callers """ ticket_number: Optional[str] From 237aa95839319894ce5dd0db4cc45ea0a8582e1e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 2 Sep 2026 20:30:46 +0000 Subject: [PATCH 09/10] feat(api): api update --- .stats.yml | 4 +- src/vitable_connect/resources/members.py | 26 +++++---- .../types/member_list_enrollments_response.py | 34 +++--------- .../types/member_list_params.py | 5 +- ...er_list_qualifying_life_events_response.py | 54 ++++++++++++++++--- 5 files changed, 78 insertions(+), 45 deletions(-) diff --git a/.stats.yml b/.stats.yml index 5804410..16480ef 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 45 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-3f53a93bd1945af083bb7db80295003ec3181c273e55dbe63b77b17c3eb2a025.yml -openapi_spec_hash: 5aab97a00d10ab9ebfe5b1db937b3f0b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/vitable/vitable-connect-cd9d35eb40d6a406e4d901e824529d80793822b71f51bdde49f500819a2bc0cd.yml +openapi_spec_hash: da172f56435db4a245e85f6647414dce config_hash: 0b4d62a9a1e0cc71998bcfc3d15c4db7 diff --git a/src/vitable_connect/resources/members.py b/src/vitable_connect/resources/members.py index 92ee791..4071581 100644 --- a/src/vitable_connect/resources/members.py +++ b/src/vitable_connect/resources/members.py @@ -107,14 +107,15 @@ def list( Retrieves a paginated list of the members in the authenticated organization's book — identity, contact details, and address. The book covers members reached through an employer in the organization's book as well as members of a group it - owns. Supports free-text search (name, email, or exact member id). + owns. Supports free-text search (name, email, phone number, or exact member id). Args: limit: Items per page (default: 20, max: 100) page: Page number (default: 1) - search: Case-insensitive search across member name and email; exact match on member id + search: Case-insensitive search across member name, email, and phone number; exact match + on member id (prefixed or raw uuid) extra_headers: Send extra headers @@ -239,9 +240,11 @@ def list_enrollments( (`cancelled_date`), and the distinct benefit plan-year boundary (`plan_year_coverage_end`) used to determine whether the plan year itself has ended, the date the enrollment record was created (`issued_date`, the value Ops - labels Issued on, reported for every row whatever the member answered), whether - a qualifying life event would currently be required for reissue under the - product/open-enrollment rule, enrollment/open-enrollment window, and two + labels Issued on, reported for every row whatever the member answered), the + window the member could answer in -- which never opens before the enrollment was + issued, so a row issued mid-open-enrollment starts its window on its issue date + -- whether a qualifying life event would currently be required for reissue under + the product/open-enrollment rule, enrollment/open-enrollment window, and two statuses: `election_status` (what the member answered) and `policy_status` (what became of their coverage, null unless they enrolled). Every row includes a stable enrollment ID and the exact employer and benefit plan-year IDs used to @@ -495,14 +498,15 @@ def list( Retrieves a paginated list of the members in the authenticated organization's book — identity, contact details, and address. The book covers members reached through an employer in the organization's book as well as members of a group it - owns. Supports free-text search (name, email, or exact member id). + owns. Supports free-text search (name, email, phone number, or exact member id). Args: limit: Items per page (default: 20, max: 100) page: Page number (default: 1) - search: Case-insensitive search across member name and email; exact match on member id + search: Case-insensitive search across member name, email, and phone number; exact match + on member id (prefixed or raw uuid) extra_headers: Send extra headers @@ -627,9 +631,11 @@ async def list_enrollments( (`cancelled_date`), and the distinct benefit plan-year boundary (`plan_year_coverage_end`) used to determine whether the plan year itself has ended, the date the enrollment record was created (`issued_date`, the value Ops - labels Issued on, reported for every row whatever the member answered), whether - a qualifying life event would currently be required for reissue under the - product/open-enrollment rule, enrollment/open-enrollment window, and two + labels Issued on, reported for every row whatever the member answered), the + window the member could answer in -- which never opens before the enrollment was + issued, so a row issued mid-open-enrollment starts its window on its issue date + -- whether a qualifying life event would currently be required for reissue under + the product/open-enrollment rule, enrollment/open-enrollment window, and two statuses: `election_status` (what the member answered) and `policy_status` (what became of their coverage, null unless they enrolled). Every row includes a stable enrollment ID and the exact employer and benefit plan-year IDs used to diff --git a/src/vitable_connect/types/member_list_enrollments_response.py b/src/vitable_connect/types/member_list_enrollments_response.py index 0f9159d..9abd4d0 100644 --- a/src/vitable_connect/types/member_list_enrollments_response.py +++ b/src/vitable_connect/types/member_list_enrollments_response.py @@ -6,23 +6,7 @@ from .._models import BaseModel -__all__ = ["MemberListEnrollmentsResponse", "Data", "DataIchraAffordability"] - - -class DataIchraAffordability(BaseModel): - """ - How this member's monthly share compares with the ACA affordability line for their income. Null unless the row is an ICHRA election whose plan year, premium and the member's individual income are all on file. - """ - - is_affordable: bool - """ - True when `employee_deduction_in_cents` is at or below the IRS affordability - percentage of the member's individual income for the year this plan year - started. It measures what the member pays for the plan they chose, so it is - **not** a statement that the employer's offer satisfies the ACA employer - mandate: that test is benchmarked against the lowest-cost silver plan at - self-only coverage, which this does not use. - """ +__all__ = ["MemberListEnrollmentsResponse", "Data"] class Data(BaseModel): @@ -63,13 +47,11 @@ class Data(BaseModel): """Name of the employer the enrollment is through""" enrollment_window_start: date - """Enrollment / open-enrollment window start date (YYYY-MM-DD)""" + """First date the member could answer this enrollment (YYYY-MM-DD). - ichra_affordability: Optional[DataIchraAffordability] = None - """ - How this member's monthly share compares with the ACA affordability line for - their income. Null unless the row is an ICHRA election whose plan year, premium - and the member's individual income are all on file. + Open enrollment's start date for a row issued before open enrollment opened, + otherwise the date the row was issued -- an enrollment is never answerable + before it exists, so this is never earlier than `issued_date`. """ in_last_month_of_coverage: bool @@ -88,9 +70,9 @@ class Data(BaseModel): """ Date the enrollment record was created (YYYY-MM-DD), the value Ops labels Issued on. Present on every row whatever the member answered, and distinct from - `coverage_start`. It does not imply the member could answer the enrollment on - that date; the window they can answer in is - `enrollment_window_start`/`enrollment_window_end`. + `coverage_start`. It equals `enrollment_window_start` for a row issued once its + open enrollment had already opened, and precedes it for a row issued ahead of + open enrollment. """ plan_year_coverage_end: Optional[date] = None diff --git a/src/vitable_connect/types/member_list_params.py b/src/vitable_connect/types/member_list_params.py index cfc3bb5..7626b78 100644 --- a/src/vitable_connect/types/member_list_params.py +++ b/src/vitable_connect/types/member_list_params.py @@ -15,4 +15,7 @@ class MemberListParams(TypedDict, total=False): """Page number (default: 1)""" search: str - """Case-insensitive search across member name and email; exact match on member id""" + """ + Case-insensitive search across member name, email, and phone number; exact match + on member id (prefixed or raw uuid) + """ diff --git a/src/vitable_connect/types/member_list_qualifying_life_events_response.py b/src/vitable_connect/types/member_list_qualifying_life_events_response.py index a0d0cd7..3d5fff1 100644 --- a/src/vitable_connect/types/member_list_qualifying_life_events_response.py +++ b/src/vitable_connect/types/member_list_qualifying_life_events_response.py @@ -13,15 +13,57 @@ class MemberListQualifyingLifeEventsResponse(BaseModel): id: str """Opaque qualifying life event identifier""" - event_type: Literal["Married", "Divorced", "New child", "Court ordered", "Other"] + event_type: Literal[ + "lost_job_based_coverage", + "aged_off_parent_plan", + "lost_medicaid_chip_medicare", + "lost_decertified_individual_plan", + "married", + "divorced", + "had_baby", + "adopted_child", + "foster_care_placement", + "death_of_spouse_or_dependent", + "court_ordered", + "moved_to_new_coverage_area", + "moved_to_us", + "moved_to_or_from_school_housing", + "moved_to_or_from_seasonal_work_housing", + "became_us_citizen", + "left_incarceration", + "gained_tribal_status", + "started_or_ended_americorps_service", + "new_child", + "other", + ] """ - - `Married` - Married - - `Divorced` - Divorced - - `New child` - New Child - - `Court ordered` - Court Ordered - - `Other` - Other + - `lost_job_based_coverage` - lost_job_based_coverage + - `aged_off_parent_plan` - aged_off_parent_plan + - `lost_medicaid_chip_medicare` - lost_medicaid_chip_medicare + - `lost_decertified_individual_plan` - lost_decertified_individual_plan + - `married` - married + - `divorced` - divorced + - `had_baby` - had_baby + - `adopted_child` - adopted_child + - `foster_care_placement` - foster_care_placement + - `death_of_spouse_or_dependent` - death_of_spouse_or_dependent + - `court_ordered` - court_ordered + - `moved_to_new_coverage_area` - moved_to_new_coverage_area + - `moved_to_us` - moved_to_us + - `moved_to_or_from_school_housing` - moved_to_or_from_school_housing + - `moved_to_or_from_seasonal_work_housing` - + moved_to_or_from_seasonal_work_housing + - `became_us_citizen` - became_us_citizen + - `left_incarceration` - left_incarceration + - `gained_tribal_status` - gained_tribal_status + - `started_or_ended_americorps_service` - started_or_ended_americorps_service + - `new_child` - new_child + - `other` - other """ + event_type_label: str + """Human-readable label for event_type""" + other_event: Optional[str] = None """Custom event description when event_type is Other; otherwise normally null""" From b2ccf7acde84f4d69d38d483f9f9cb28a2e8b60b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 2 Sep 2026 20:31:13 +0000 Subject: [PATCH 10/10] release: 0.10.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 14 ++++++++++++++ pyproject.toml | 2 +- src/vitable_connect/_version.py | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 6d78745..091cfb1 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.9.0" + ".": "0.10.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 3311c5f..6e38053 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 0.10.0 (2026-09-02) + +Full Changelog: [v0.9.0...v0.10.0](https://github.com/Vitable-Inc/vitable-connect-python/compare/v0.9.0...v0.10.0) + +### Features + +* **api:** api update ([237aa95](https://github.com/Vitable-Inc/vitable-connect-python/commit/237aa95839319894ce5dd0db4cc45ea0a8582e1e)) +* **api:** api update ([a054758](https://github.com/Vitable-Inc/vitable-connect-python/commit/a054758a085dfe77508e13a8a72cc1acb2fb51ba)) +* **api:** api update ([137ed3f](https://github.com/Vitable-Inc/vitable-connect-python/commit/137ed3fe713507914856d71e3fc318a7991483bf)) +* **api:** api update ([dbc5ecc](https://github.com/Vitable-Inc/vitable-connect-python/commit/dbc5eccd1e518cfde70217fb3f768c2753f08ba0)) +* **api:** api update ([506aa7e](https://github.com/Vitable-Inc/vitable-connect-python/commit/506aa7ec53fc4dcd8c4008a919357620c6f627bb)) +* **api:** api update ([ea2c85d](https://github.com/Vitable-Inc/vitable-connect-python/commit/ea2c85dfb0474bbb27ec9541c2da9acee8d69c0f)) +* **api:** api update ([6f1d278](https://github.com/Vitable-Inc/vitable-connect-python/commit/6f1d278d7a13f2a81556c0f0f15869c619d49b23)) + ## 0.9.0 (2026-08-20) Full Changelog: [v0.8.0...v0.9.0](https://github.com/Vitable-Inc/vitable-connect-python/compare/v0.8.0...v0.9.0) diff --git a/pyproject.toml b/pyproject.toml index d4b93dd..d1a40f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "vitable_connect" -version = "0.9.0" +version = "0.10.0" description = "The official Python library for the vitable-connect API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/vitable_connect/_version.py b/src/vitable_connect/_version.py index f000ac5..107d57d 100644 --- a/src/vitable_connect/_version.py +++ b/src/vitable_connect/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "vitable_connect" -__version__ = "0.9.0" # x-release-please-version +__version__ = "0.10.0" # x-release-please-version