Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.35.0"
".": "1.36.0"
}
6 changes: 3 additions & 3 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Or to pin the version:
<!-- x-release-please-start-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'
```

<!-- x-release-please-end -->
Expand Down
2 changes: 2 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,14 @@ Methods:

Response Types:

- <a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go">finchgo</a>.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#EnrolledIndividualBenefitResponse">EnrolledIndividualBenefitResponse</a>
- <a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go">finchgo</a>.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#IndividualBenefit">IndividualBenefit</a>
- <a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go">finchgo</a>.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#UnenrolledIndividualBenefitResponse">UnenrolledIndividualBenefitResponse</a>
- <a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go">finchgo</a>.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#HRISBenefitIndividualEnrolledIDsResponse">HRISBenefitIndividualEnrolledIDsResponse</a>

Methods:

- <code title="post /employer/benefits/{benefit_id}/individuals">client.HRIS.Benefits.Individuals.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#HRISBenefitIndividualService.EnrollMany">EnrollMany</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, benefitID <a href="https://pkg.go.dev/builtin#string">string</a>, params <a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go">finchgo</a>.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#HRISBenefitIndividualEnrollManyParams">HRISBenefitIndividualEnrollManyParams</a>) (\*<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go">finchgo</a>.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#EnrolledIndividualBenefitResponse">EnrolledIndividualBenefitResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /employer/benefits/{benefit_id}/enrolled">client.HRIS.Benefits.Individuals.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#HRISBenefitIndividualService.EnrolledIDs">EnrolledIDs</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, benefitID <a href="https://pkg.go.dev/builtin#string">string</a>, query <a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go">finchgo</a>.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#HRISBenefitIndividualEnrolledIDsParams">HRISBenefitIndividualEnrolledIDsParams</a>) (\*<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go">finchgo</a>.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#HRISBenefitIndividualEnrolledIDsResponse">HRISBenefitIndividualEnrolledIDsResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /employer/benefits/{benefit_id}/individuals">client.HRIS.Benefits.Individuals.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#HRISBenefitIndividualService.GetManyBenefits">GetManyBenefits</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, benefitID <a href="https://pkg.go.dev/builtin#string">string</a>, query <a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go">finchgo</a>.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#HRISBenefitIndividualGetManyBenefitsParams">HRISBenefitIndividualGetManyBenefitsParams</a>) (\*<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go/packages/pagination">pagination</a>.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go/packages/pagination#SinglePage">SinglePage</a>[<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go">finchgo</a>.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#IndividualBenefit">IndividualBenefit</a>], <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="delete /employer/benefits/{benefit_id}/individuals">client.HRIS.Benefits.Individuals.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#HRISBenefitIndividualService.UnenrollMany">UnenrollMany</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, benefitID <a href="https://pkg.go.dev/builtin#string">string</a>, params <a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go">finchgo</a>.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#HRISBenefitIndividualUnenrollManyParams">HRISBenefitIndividualUnenrollManyParams</a>) (\*<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go">finchgo</a>.<a href="https://pkg.go.dev/github.com/Finch-API/finch-api-go#UnenrolledIndividualBenefitResponse">UnenrolledIndividualBenefitResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
Expand Down
170 changes: 170 additions & 0 deletions hrisbenefitindividual.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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()}
Expand Down Expand Up @@ -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"`
Expand Down Expand Up @@ -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"`
Expand Down
52 changes: 52 additions & 0 deletions hrisbenefitindividual_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion internal/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

package internal

const PackageVersion = "1.35.0" // x-release-please-version
const PackageVersion = "1.36.0" // x-release-please-version
Loading