From 3a2cdfa1acd3082c96b6ccfefea742dfaab7361e Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 17:53:53 +0000
Subject: [PATCH 1/2] feat(api): add enroll many
---
.stats.yml | 6 +-
api.md | 2 +
hrisbenefitindividual.go | 170 ++++++++++++++++++++++++++++++++++
hrisbenefitindividual_test.go | 52 +++++++++++
4 files changed, 227 insertions(+), 3 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index b9153e4..2bdeb15 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 47
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch/finch-5092370ef89959c46138a85f9d6d3c919682a5492a0f9f85ac4421de702f35a8.yml
+configured_endpoints: 48
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch/finch-8a983c70d7cbbc4023463a85ebdabcee1645603ab46337aa9cfa18f1872f0ae1.yml
openapi_spec_hash: a4ca94b3405fc83934c949068943e16c
-config_hash: a1c4b7d897cbf8ed42c5f474b3161d79
+config_hash: 812b56df3e506bc2af056b2898327b8a
diff --git a/api.md b/api.md
index 4e3b557..7f3b6c2 100644
--- a/api.md
+++ b/api.md
@@ -179,12 +179,14 @@ Methods:
Response Types:
+- finchgo.EnrolledIndividualBenefitResponse
- finchgo.IndividualBenefit
- finchgo.UnenrolledIndividualBenefitResponse
- finchgo.HRISBenefitIndividualEnrolledIDsResponse
Methods:
+- client.HRIS.Benefits.Individuals.EnrollMany(ctx context.Context, benefitID string, params finchgo.HRISBenefitIndividualEnrollManyParams) (\*finchgo.EnrolledIndividualBenefitResponse, error)
- client.HRIS.Benefits.Individuals.EnrolledIDs(ctx context.Context, benefitID string, query finchgo.HRISBenefitIndividualEnrolledIDsParams) (\*finchgo.HRISBenefitIndividualEnrolledIDsResponse, error)
- client.HRIS.Benefits.Individuals.GetManyBenefits(ctx context.Context, benefitID string, query finchgo.HRISBenefitIndividualGetManyBenefitsParams) (\*pagination.SinglePage[finchgo.IndividualBenefit], error)
- client.HRIS.Benefits.Individuals.UnenrollMany(ctx context.Context, benefitID string, params finchgo.HRISBenefitIndividualUnenrollManyParams) (\*finchgo.UnenrolledIndividualBenefitResponse, error)
diff --git a/hrisbenefitindividual.go b/hrisbenefitindividual.go
index 9d13938..35417a4 100644
--- a/hrisbenefitindividual.go
+++ b/hrisbenefitindividual.go
@@ -10,6 +10,7 @@ import (
"net/url"
"reflect"
"slices"
+ "time"
"github.com/Finch-API/finch-api-go/internal/apijson"
"github.com/Finch-API/finch-api-go/internal/apiquery"
@@ -39,6 +40,22 @@ func NewHRISBenefitIndividualService(opts ...option.RequestOption) (r *HRISBenef
return
}
+// Enroll an individual into a deduction or contribution. This is an overwrite
+// operation. If the employee is already enrolled, the enrollment amounts will be
+// adjusted. Making the same request multiple times will not create new
+// enrollments, but will continue to set the state of the existing enrollment.
+func (r *HRISBenefitIndividualService) EnrollMany(ctx context.Context, benefitID string, params HRISBenefitIndividualEnrollManyParams, opts ...option.RequestOption) (res *EnrolledIndividualBenefitResponse, err error) {
+ var preClientOpts = []option.RequestOption{requestconfig.WithBearerAuthSecurity()}
+ opts = slices.Concat(preClientOpts, r.Options, opts)
+ if benefitID == "" {
+ err = errors.New("missing required benefit_id parameter")
+ return nil, err
+ }
+ path := fmt.Sprintf("employer/benefits/%s/individuals", benefitID)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...)
+ return res, err
+}
+
// Lists individuals currently enrolled in a given deduction.
func (r *HRISBenefitIndividualService) EnrolledIDs(ctx context.Context, benefitID string, query HRISBenefitIndividualEnrolledIDsParams, opts ...option.RequestOption) (res *HRISBenefitIndividualEnrolledIDsResponse, err error) {
var preClientOpts = []option.RequestOption{requestconfig.WithBearerAuthSecurity()}
@@ -93,6 +110,27 @@ func (r *HRISBenefitIndividualService) UnenrollMany(ctx context.Context, benefit
return res, err
}
+type EnrolledIndividualBenefitResponse struct {
+ JobID string `json:"job_id" api:"required" format:"uuid"`
+ JSON enrolledIndividualBenefitResponseJSON `json:"-"`
+}
+
+// enrolledIndividualBenefitResponseJSON contains the JSON metadata for the struct
+// [EnrolledIndividualBenefitResponse]
+type enrolledIndividualBenefitResponseJSON struct {
+ JobID apijson.Field
+ raw string
+ ExtraFields map[string]apijson.Field
+}
+
+func (r *EnrolledIndividualBenefitResponse) UnmarshalJSON(data []byte) (err error) {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+func (r enrolledIndividualBenefitResponseJSON) RawJSON() string {
+ return r.raw
+}
+
type IndividualBenefit struct {
Body IndividualBenefitBody `json:"body" api:"required"`
Code int64 `json:"code" api:"required"`
@@ -796,6 +834,138 @@ func (r hrisBenefitIndividualEnrolledIDsResponseJSON) RawJSON() string {
return r.raw
}
+type HRISBenefitIndividualEnrollManyParams struct {
+ // The entity IDs to specify which entities' data to access.
+ EntityIDs param.Field[[]string] `query:"entity_ids" format:"uuid"`
+ // Array of the individual_id to enroll and a configuration object.
+ Individuals []HRISBenefitIndividualEnrollManyParamsIndividual `json:"individuals"`
+}
+
+func (r HRISBenefitIndividualEnrollManyParams) MarshalJSON() (data []byte, err error) {
+ return apijson.MarshalRoot(r.Individuals)
+}
+
+// URLQuery serializes [HRISBenefitIndividualEnrollManyParams]'s query parameters
+// as `url.Values`.
+func (r HRISBenefitIndividualEnrollManyParams) URLQuery() (v url.Values) {
+ return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{
+ ArrayFormat: apiquery.ArrayQueryFormatBrackets,
+ NestedFormat: apiquery.NestedQueryFormatBrackets,
+ })
+}
+
+type HRISBenefitIndividualEnrollManyParamsIndividual struct {
+ Configuration param.Field[HRISBenefitIndividualEnrollManyParamsIndividualsConfiguration] `json:"configuration"`
+ // Finch id (uuidv4) for the individual to enroll
+ IndividualID param.Field[string] `json:"individual_id"`
+}
+
+func (r HRISBenefitIndividualEnrollManyParamsIndividual) MarshalJSON() (data []byte, err error) {
+ return apijson.MarshalRoot(r)
+}
+
+type HRISBenefitIndividualEnrollManyParamsIndividualsConfiguration struct {
+ // For HSA benefits only - whether the contribution limit is for an individual or
+ // family
+ AnnualContributionLimit param.Field[HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationAnnualContributionLimit] `json:"annual_contribution_limit"`
+ // Maximum annual amount in cents
+ AnnualMaximum param.Field[int64] `json:"annual_maximum"`
+ // For retirement benefits only - whether catch up contributions are enabled
+ CatchUp param.Field[bool] `json:"catch_up"`
+ CompanyContribution param.Field[HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContribution] `json:"company_contribution"`
+ // The date the enrollment will take effect
+ EffectiveDate param.Field[time.Time] `json:"effective_date" format:"date"`
+ EmployeeDeduction param.Field[HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeduction] `json:"employee_deduction"`
+}
+
+func (r HRISBenefitIndividualEnrollManyParamsIndividualsConfiguration) MarshalJSON() (data []byte, err error) {
+ return apijson.MarshalRoot(r)
+}
+
+// For HSA benefits only - whether the contribution limit is for an individual or
+// family
+type HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationAnnualContributionLimit string
+
+const (
+ HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationAnnualContributionLimitIndividual HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationAnnualContributionLimit = "individual"
+ HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationAnnualContributionLimitFamily HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationAnnualContributionLimit = "family"
+)
+
+func (r HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationAnnualContributionLimit) IsKnown() bool {
+ switch r {
+ case HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationAnnualContributionLimitIndividual, HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationAnnualContributionLimitFamily:
+ return true
+ }
+ return false
+}
+
+type HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContribution struct {
+ // Amount in cents for fixed type or basis points (1/100th of a percent) for
+ // percent type
+ Amount param.Field[int64] `json:"amount"`
+ // Array of tier objects for tiered contribution matching (required when type is
+ // tiered)
+ Tiers param.Field[[]HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionTier] `json:"tiers"`
+ Type param.Field[HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionType] `json:"type"`
+}
+
+func (r HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContribution) MarshalJSON() (data []byte, err error) {
+ return apijson.MarshalRoot(r)
+}
+
+type HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionTier struct {
+ // The employer match percentage in basis points (0-10000 = 0-100%)
+ Match param.Field[int64] `json:"match" api:"required"`
+ // The employee contribution threshold in basis points (0-10000 = 0-100%)
+ Threshold param.Field[int64] `json:"threshold" api:"required"`
+}
+
+func (r HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionTier) MarshalJSON() (data []byte, err error) {
+ return apijson.MarshalRoot(r)
+}
+
+type HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionType string
+
+const (
+ HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionTypeFixed HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionType = "fixed"
+ HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionTypePercent HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionType = "percent"
+ HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionTypeTiered HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionType = "tiered"
+)
+
+func (r HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionType) IsKnown() bool {
+ switch r {
+ case HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionTypeFixed, HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionTypePercent, HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionTypeTiered:
+ return true
+ }
+ return false
+}
+
+type HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeduction struct {
+ // Amount in cents for fixed type or basis points (1/100th of a percent) for
+ // percent type
+ Amount param.Field[int64] `json:"amount"`
+ Type param.Field[HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeductionType] `json:"type"`
+}
+
+func (r HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeduction) MarshalJSON() (data []byte, err error) {
+ return apijson.MarshalRoot(r)
+}
+
+type HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeductionType string
+
+const (
+ HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeductionTypeFixed HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeductionType = "fixed"
+ HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeductionTypePercent HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeductionType = "percent"
+)
+
+func (r HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeductionType) IsKnown() bool {
+ switch r {
+ case HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeductionTypeFixed, HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeductionTypePercent:
+ return true
+ }
+ return false
+}
+
type HRISBenefitIndividualEnrolledIDsParams struct {
// The entity IDs to specify which entities' data to access.
EntityIDs param.Field[[]string] `query:"entity_ids" format:"uuid"`
diff --git a/hrisbenefitindividual_test.go b/hrisbenefitindividual_test.go
index a0aaff0..df4e4b2 100644
--- a/hrisbenefitindividual_test.go
+++ b/hrisbenefitindividual_test.go
@@ -7,12 +7,64 @@ import (
"errors"
"os"
"testing"
+ "time"
"github.com/Finch-API/finch-api-go"
"github.com/Finch-API/finch-api-go/internal/testutil"
"github.com/Finch-API/finch-api-go/option"
)
+func TestHRISBenefitIndividualEnrollManyWithOptionalParams(t *testing.T) {
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := finchgo.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAccessToken("My Access Token"),
+ option.WithClientID("4ab15e51-11ad-49f4-acae-f343b7794375"),
+ option.WithClientSecret("My Client Secret"),
+ )
+ _, err := client.HRIS.Benefits.Individuals.EnrollMany(
+ context.TODO(),
+ "benefit_id",
+ finchgo.HRISBenefitIndividualEnrollManyParams{
+ EntityIDs: finchgo.F([]string{"550e8400-e29b-41d4-a716-446655440000"}),
+ Individuals: []finchgo.HRISBenefitIndividualEnrollManyParamsIndividual{{
+ Configuration: finchgo.F(finchgo.HRISBenefitIndividualEnrollManyParamsIndividualsConfiguration{
+ AnnualContributionLimit: finchgo.F(finchgo.HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationAnnualContributionLimitIndividual),
+ AnnualMaximum: finchgo.Null[int64](),
+ CatchUp: finchgo.F(true),
+ CompanyContribution: finchgo.F(finchgo.HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContribution{
+ Amount: finchgo.F(int64(0)),
+ Tiers: finchgo.F([]finchgo.HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionTier{{
+ Match: finchgo.F(int64(0)),
+ Threshold: finchgo.F(int64(0)),
+ }}),
+ Type: finchgo.F(finchgo.HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationCompanyContributionTypeFixed),
+ }),
+ EffectiveDate: finchgo.F(time.Now()),
+ EmployeeDeduction: finchgo.F(finchgo.HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeduction{
+ Amount: finchgo.F(int64(10000)),
+ Type: finchgo.F(finchgo.HRISBenefitIndividualEnrollManyParamsIndividualsConfigurationEmployeeDeductionTypeFixed),
+ }),
+ }),
+ IndividualID: finchgo.F("d02a6346-1f08-4312-a064-49ff3cafaa7a"),
+ }},
+ },
+ )
+ if err != nil {
+ var apierr *finchgo.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
+
func TestHRISBenefitIndividualEnrolledIDsWithOptionalParams(t *testing.T) {
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
From f431b39c5bf92f517e1814d51d6e74cc4f7089da Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 17:54:18 +0000
Subject: [PATCH 2/2] release: 1.36.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 8 ++++++++
README.md | 2 +-
internal/version.go | 2 +-
4 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 44959ac..f29e96b 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "1.35.0"
+ ".": "1.36.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cd6d398..8d19304 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 1.36.0 (2026-05-15)
+
+Full Changelog: [v1.35.0...v1.36.0](https://github.com/Finch-API/finch-api-go/compare/v1.35.0...v1.36.0)
+
+### Features
+
+* **api:** add enroll many ([3a2cdfa](https://github.com/Finch-API/finch-api-go/commit/3a2cdfa1acd3082c96b6ccfefea742dfaab7361e))
+
## 1.35.0 (2026-05-13)
Full Changelog: [v1.34.1...v1.35.0](https://github.com/Finch-API/finch-api-go/compare/v1.34.1...v1.35.0)
diff --git a/README.md b/README.md
index 58c4055..77ce6c5 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ Or to pin the version:
```sh
-go get -u 'github.com/Finch-API/finch-api-go@v1.35.0'
+go get -u 'github.com/Finch-API/finch-api-go@v1.36.0'
```
diff --git a/internal/version.go b/internal/version.go
index 33b1bc6..d6caaff 100644
--- a/internal/version.go
+++ b/internal/version.go
@@ -2,4 +2,4 @@
package internal
-const PackageVersion = "1.35.0" // x-release-please-version
+const PackageVersion = "1.36.0" // x-release-please-version