From 9c9cddffcc4830255cd39227f5159dd244e92a3f Mon Sep 17 00:00:00 2001 From: Guillaume Winter <8502556+DocEmmetBrown@users.noreply.github.com> Date: Thu, 26 Jun 2025 17:07:22 +0200 Subject: [PATCH 1/5] add new Enhanced billing platform the new endpoints are available as per this doc: https://docs.github.com/en/enterprise-cloud@latest/rest/billing/enhanced-billing?apiVersion=2022-11-28#get-billing-usage-report-for-an-organization --- github/billing.go | 91 ++++++++++++++++++ github/billing_test.go | 164 ++++++++++++++++++++++++++++++++ github/github-accessors.go | 120 +++++++++++++++++++++++ github/github-accessors_test.go | 153 +++++++++++++++++++++++++++++ 4 files changed, 528 insertions(+) diff --git a/github/billing.go b/github/billing.go index 09b1a5d017a..70145773e36 100644 --- a/github/billing.go +++ b/github/billing.go @@ -63,6 +63,41 @@ type AdvancedSecurityCommittersBreakdown struct { LastPushedDate *string `json:"last_pushed_date,omitempty"` } +// UsageReportOptions specifies optional parameters for the enhanced billing platform usage report. +type UsageReportOptions struct { + // If specified, only return results for a single year. The value of year is an integer with four digits representing a year. + Year *int `url:"year,omitempty"` + + // If specified, only return results for a single month. The value of month is an integer between 1 and 12. + Month *int `url:"month,omitempty"` + + // If specified, only return results for a single day. The value of day is an integer between 1 and 31. + Day *int `url:"day,omitempty"` + + // If specified, only return results for a single hour. The value of hour is an integer between 0 and 23. + Hour *int `url:"hour,omitempty"` +} + +// UsageItem represents a single usage item in the enhanced billing platform report. +type UsageItem struct { + Date *string `json:"date,omitempty"` + Product *string `json:"product,omitempty"` + SKU *string `json:"sku,omitempty"` + Quantity *int `json:"quantity,omitempty"` + UnitType *string `json:"unitType,omitempty"` + PricePerUnit *float64 `json:"pricePerUnit,omitempty"` + GrossAmount *float64 `json:"grossAmount,omitempty"` + DiscountAmount *float64 `json:"discountAmount,omitempty"` + NetAmount *float64 `json:"netAmount,omitempty"` + OrganizationName *string `json:"organizationName,omitempty"` + RepositoryName *string `json:"repositoryName,omitempty"` +} + +// UsageReport represents the enhanced billing platform usage report response. +type UsageReport struct { + UsageItems []*UsageItem `json:"usageItems,omitempty"` +} + // GetActionsBillingOrg returns the summary of the free and paid GitHub Actions minutes used for an Org. // // GitHub API docs: https://docs.github.com/rest/billing/billing#get-github-actions-billing-for-an-organization @@ -216,3 +251,59 @@ func (s *BillingService) GetStorageBillingUser(ctx context.Context, user string) return storageUserBilling, resp, nil } + +// GetUsageReportOrg returns a report of the total usage for an organization using the enhanced billing platform. +// +// Note: This endpoint is only available to organizations with access to the enhanced billing platform. +// +// GitHub API docs: https://docs.github.com/rest/billing/enhanced-billing#get-billing-usage-report-for-an-organization +// +//meta:operation GET /organizations/{org}/settings/billing/usage +func (s *BillingService) GetUsageReportOrg(ctx context.Context, org string, opts *UsageReportOptions) (*UsageReport, *Response, error) { + u := fmt.Sprintf("organizations/%v/settings/billing/usage", org) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + usageReport := new(UsageReport) + resp, err := s.client.Do(ctx, req, usageReport) + if err != nil { + return nil, resp, err + } + + return usageReport, resp, nil +} + +// GetUsageReportUser returns a report of the total usage for a user using the enhanced billing platform. +// +// Note: This endpoint is only available to users with access to the enhanced billing platform. +// +// GitHub API docs: https://docs.github.com/rest/billing/enhanced-billing#get-billing-usage-report-for-a-user +// +//meta:operation GET /users/{username}/settings/billing/usage +func (s *BillingService) GetUsageReportUser(ctx context.Context, user string, opts *UsageReportOptions) (*UsageReport, *Response, error) { + u := fmt.Sprintf("users/%v/settings/billing/usage", user) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + usageReport := new(UsageReport) + resp, err := s.client.Do(ctx, req, usageReport) + if err != nil { + return nil, resp, err + } + + return usageReport, resp, nil +} diff --git a/github/billing_test.go b/github/billing_test.go index 8fb6499c186..ffbb94d112f 100644 --- a/github/billing_test.go +++ b/github/billing_test.go @@ -510,3 +510,167 @@ func TestBillingService_GetAdvancedSecurityActiveCommittersOrg_invalidOrg(t *tes _, _, err := client.Billing.GetAdvancedSecurityActiveCommittersOrg(ctx, "%", nil) testURLParseError(t, err) } + +func TestBillingService_GetUsageReportOrg(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/organizations/o/settings/billing/usage", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{ + "year": "2023", + "month": "8", + }) + fmt.Fprint(w, `{ + "usageItems": [ + { + "date": "2023-08-01", + "product": "Actions", + "sku": "Actions Linux", + "quantity": 100, + "unitType": "minutes", + "pricePerUnit": 0.008, + "grossAmount": 0.8, + "discountAmount": 0, + "netAmount": 0.8, + "organizationName": "GitHub", + "repositoryName": "github/example" + } + ] + }`) + }) + + ctx := context.Background() + opts := &UsageReportOptions{ + Year: Ptr(2023), + Month: Ptr(8), + } + report, _, err := client.Billing.GetUsageReportOrg(ctx, "o", opts) + if err != nil { + t.Errorf("Billing.GetUsageReportOrg returned error: %v", err) + } + + want := &UsageReport{ + UsageItems: []*UsageItem{ + { + Date: Ptr("2023-08-01"), + Product: Ptr("Actions"), + SKU: Ptr("Actions Linux"), + Quantity: Ptr(100), + UnitType: Ptr("minutes"), + PricePerUnit: Ptr(0.008), + GrossAmount: Ptr(0.8), + DiscountAmount: Ptr(0.0), + NetAmount: Ptr(0.8), + OrganizationName: Ptr("GitHub"), + RepositoryName: Ptr("github/example"), + }, + }, + } + if !cmp.Equal(report, want) { + t.Errorf("Billing.GetUsageReportOrg returned %+v, want %+v", report, want) + } + + const methodName = "GetUsageReportOrg" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Billing.GetUsageReportOrg(ctx, "\n", nil) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Billing.GetUsageReportOrg(ctx, "o", nil) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestBillingService_GetUsageReportOrg_invalidOrg(t *testing.T) { + t.Parallel() + client, _, _ := setup(t) + + ctx := context.Background() + _, _, err := client.Billing.GetUsageReportOrg(ctx, "%", nil) + testURLParseError(t, err) +} + +func TestBillingService_GetUsageReportUser(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/users/u/settings/billing/usage", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{ + "day": "15", + }) + fmt.Fprint(w, `{ + "usageItems": [ + { + "date": "2023-08-15", + "product": "Codespaces", + "sku": "Codespaces Linux", + "quantity": 50, + "unitType": "hours", + "pricePerUnit": 0.18, + "grossAmount": 9.0, + "discountAmount": 1.0, + "netAmount": 8.0, + "repositoryName": "user/example" + } + ] + }`) + }) + + ctx := context.Background() + opts := &UsageReportOptions{ + Day: Ptr(15), + } + report, _, err := client.Billing.GetUsageReportUser(ctx, "u", opts) + if err != nil { + t.Errorf("Billing.GetUsageReportUser returned error: %v", err) + } + + want := &UsageReport{ + UsageItems: []*UsageItem{ + { + Date: Ptr("2023-08-15"), + Product: Ptr("Codespaces"), + SKU: Ptr("Codespaces Linux"), + Quantity: Ptr(50), + UnitType: Ptr("hours"), + PricePerUnit: Ptr(0.18), + GrossAmount: Ptr(9.0), + DiscountAmount: Ptr(1.0), + NetAmount: Ptr(8.0), + RepositoryName: Ptr("user/example"), + }, + }, + } + if !cmp.Equal(report, want) { + t.Errorf("Billing.GetUsageReportUser returned %+v, want %+v", report, want) + } + + const methodName = "GetUsageReportUser" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Billing.GetUsageReportUser(ctx, "\n", nil) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Billing.GetUsageReportUser(ctx, "u", nil) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestBillingService_GetUsageReportUser_invalidUser(t *testing.T) { + t.Parallel() + client, _, _ := setup(t) + + ctx := context.Background() + _, _, err := client.Billing.GetUsageReportUser(ctx, "%", nil) + testURLParseError(t, err) +} diff --git a/github/github-accessors.go b/github/github-accessors.go index 135726bca85..2b832617c85 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -27574,6 +27574,126 @@ func (u *UpdateRunnerGroupRequest) GetVisibility() string { return *u.Visibility } +// GetDate returns the Date field if it's non-nil, zero value otherwise. +func (u *UsageItem) GetDate() string { + if u == nil || u.Date == nil { + return "" + } + return *u.Date +} + +// GetDiscountAmount returns the DiscountAmount field. +func (u *UsageItem) GetDiscountAmount() *float64 { + if u == nil { + return nil + } + return u.DiscountAmount +} + +// GetGrossAmount returns the GrossAmount field. +func (u *UsageItem) GetGrossAmount() *float64 { + if u == nil { + return nil + } + return u.GrossAmount +} + +// GetNetAmount returns the NetAmount field. +func (u *UsageItem) GetNetAmount() *float64 { + if u == nil { + return nil + } + return u.NetAmount +} + +// GetOrganizationName returns the OrganizationName field if it's non-nil, zero value otherwise. +func (u *UsageItem) GetOrganizationName() string { + if u == nil || u.OrganizationName == nil { + return "" + } + return *u.OrganizationName +} + +// GetPricePerUnit returns the PricePerUnit field. +func (u *UsageItem) GetPricePerUnit() *float64 { + if u == nil { + return nil + } + return u.PricePerUnit +} + +// GetProduct returns the Product field if it's non-nil, zero value otherwise. +func (u *UsageItem) GetProduct() string { + if u == nil || u.Product == nil { + return "" + } + return *u.Product +} + +// GetQuantity returns the Quantity field if it's non-nil, zero value otherwise. +func (u *UsageItem) GetQuantity() int { + if u == nil || u.Quantity == nil { + return 0 + } + return *u.Quantity +} + +// GetRepositoryName returns the RepositoryName field if it's non-nil, zero value otherwise. +func (u *UsageItem) GetRepositoryName() string { + if u == nil || u.RepositoryName == nil { + return "" + } + return *u.RepositoryName +} + +// GetSKU returns the SKU field if it's non-nil, zero value otherwise. +func (u *UsageItem) GetSKU() string { + if u == nil || u.SKU == nil { + return "" + } + return *u.SKU +} + +// GetUnitType returns the UnitType field if it's non-nil, zero value otherwise. +func (u *UsageItem) GetUnitType() string { + if u == nil || u.UnitType == nil { + return "" + } + return *u.UnitType +} + +// GetDay returns the Day field if it's non-nil, zero value otherwise. +func (u *UsageReportOptions) GetDay() int { + if u == nil || u.Day == nil { + return 0 + } + return *u.Day +} + +// GetHour returns the Hour field if it's non-nil, zero value otherwise. +func (u *UsageReportOptions) GetHour() int { + if u == nil || u.Hour == nil { + return 0 + } + return *u.Hour +} + +// GetMonth returns the Month field if it's non-nil, zero value otherwise. +func (u *UsageReportOptions) GetMonth() int { + if u == nil || u.Month == nil { + return 0 + } + return *u.Month +} + +// GetYear returns the Year field if it's non-nil, zero value otherwise. +func (u *UsageReportOptions) GetYear() int { + if u == nil || u.Year == nil { + return 0 + } + return *u.Year +} + // GetAssignment returns the Assignment field if it's non-nil, zero value otherwise. func (u *User) GetAssignment() string { if u == nil || u.Assignment == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index ca2f10ffb92..c0b94a55148 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -35456,6 +35456,159 @@ func TestUpdateRunnerGroupRequest_GetVisibility(tt *testing.T) { u.GetVisibility() } +func TestUsageItem_GetDate(tt *testing.T) { + tt.Parallel() + var zeroValue string + u := &UsageItem{Date: &zeroValue} + u.GetDate() + u = &UsageItem{} + u.GetDate() + u = nil + u.GetDate() +} + +func TestUsageItem_GetDiscountAmount(tt *testing.T) { + tt.Parallel() + u := &UsageItem{} + u.GetDiscountAmount() + u = nil + u.GetDiscountAmount() +} + +func TestUsageItem_GetGrossAmount(tt *testing.T) { + tt.Parallel() + u := &UsageItem{} + u.GetGrossAmount() + u = nil + u.GetGrossAmount() +} + +func TestUsageItem_GetNetAmount(tt *testing.T) { + tt.Parallel() + u := &UsageItem{} + u.GetNetAmount() + u = nil + u.GetNetAmount() +} + +func TestUsageItem_GetOrganizationName(tt *testing.T) { + tt.Parallel() + var zeroValue string + u := &UsageItem{OrganizationName: &zeroValue} + u.GetOrganizationName() + u = &UsageItem{} + u.GetOrganizationName() + u = nil + u.GetOrganizationName() +} + +func TestUsageItem_GetPricePerUnit(tt *testing.T) { + tt.Parallel() + u := &UsageItem{} + u.GetPricePerUnit() + u = nil + u.GetPricePerUnit() +} + +func TestUsageItem_GetProduct(tt *testing.T) { + tt.Parallel() + var zeroValue string + u := &UsageItem{Product: &zeroValue} + u.GetProduct() + u = &UsageItem{} + u.GetProduct() + u = nil + u.GetProduct() +} + +func TestUsageItem_GetQuantity(tt *testing.T) { + tt.Parallel() + var zeroValue int + u := &UsageItem{Quantity: &zeroValue} + u.GetQuantity() + u = &UsageItem{} + u.GetQuantity() + u = nil + u.GetQuantity() +} + +func TestUsageItem_GetRepositoryName(tt *testing.T) { + tt.Parallel() + var zeroValue string + u := &UsageItem{RepositoryName: &zeroValue} + u.GetRepositoryName() + u = &UsageItem{} + u.GetRepositoryName() + u = nil + u.GetRepositoryName() +} + +func TestUsageItem_GetSKU(tt *testing.T) { + tt.Parallel() + var zeroValue string + u := &UsageItem{SKU: &zeroValue} + u.GetSKU() + u = &UsageItem{} + u.GetSKU() + u = nil + u.GetSKU() +} + +func TestUsageItem_GetUnitType(tt *testing.T) { + tt.Parallel() + var zeroValue string + u := &UsageItem{UnitType: &zeroValue} + u.GetUnitType() + u = &UsageItem{} + u.GetUnitType() + u = nil + u.GetUnitType() +} + +func TestUsageReportOptions_GetDay(tt *testing.T) { + tt.Parallel() + var zeroValue int + u := &UsageReportOptions{Day: &zeroValue} + u.GetDay() + u = &UsageReportOptions{} + u.GetDay() + u = nil + u.GetDay() +} + +func TestUsageReportOptions_GetHour(tt *testing.T) { + tt.Parallel() + var zeroValue int + u := &UsageReportOptions{Hour: &zeroValue} + u.GetHour() + u = &UsageReportOptions{} + u.GetHour() + u = nil + u.GetHour() +} + +func TestUsageReportOptions_GetMonth(tt *testing.T) { + tt.Parallel() + var zeroValue int + u := &UsageReportOptions{Month: &zeroValue} + u.GetMonth() + u = &UsageReportOptions{} + u.GetMonth() + u = nil + u.GetMonth() +} + +func TestUsageReportOptions_GetYear(tt *testing.T) { + tt.Parallel() + var zeroValue int + u := &UsageReportOptions{Year: &zeroValue} + u.GetYear() + u = &UsageReportOptions{} + u.GetYear() + u = nil + u.GetYear() +} + func TestUser_GetAssignment(tt *testing.T) { tt.Parallel() var zeroValue string From a9244e0f55acdf2f6b3d6fbd9df193a8fe7b3247 Mon Sep 17 00:00:00 2001 From: Guillaume Winter <8502556+DocEmmetBrown@users.noreply.github.com> Date: Thu, 26 Jun 2025 23:15:54 +0200 Subject: [PATCH 2/5] update the UsageItem definition to account for required fields --- github/billing.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/github/billing.go b/github/billing.go index 70145773e36..3fd79f9abe0 100644 --- a/github/billing.go +++ b/github/billing.go @@ -80,16 +80,16 @@ type UsageReportOptions struct { // UsageItem represents a single usage item in the enhanced billing platform report. type UsageItem struct { - Date *string `json:"date,omitempty"` - Product *string `json:"product,omitempty"` - SKU *string `json:"sku,omitempty"` - Quantity *int `json:"quantity,omitempty"` - UnitType *string `json:"unitType,omitempty"` - PricePerUnit *float64 `json:"pricePerUnit,omitempty"` - GrossAmount *float64 `json:"grossAmount,omitempty"` - DiscountAmount *float64 `json:"discountAmount,omitempty"` - NetAmount *float64 `json:"netAmount,omitempty"` - OrganizationName *string `json:"organizationName,omitempty"` + Date *string `json:"date"` + Product *string `json:"product"` + SKU *string `json:"sku"` + Quantity *int `json:"quantity"` + UnitType *string `json:"unitType"` + PricePerUnit *float64 `json:"pricePerUnit"` + GrossAmount *float64 `json:"grossAmount"` + DiscountAmount *float64 `json:"discountAmount"` + NetAmount *float64 `json:"netAmount"` + OrganizationName *string `json:"organizationName"` RepositoryName *string `json:"repositoryName,omitempty"` } From 2a368b7805405081cb6495f75f854706223b3441 Mon Sep 17 00:00:00 2001 From: Guillaume Winter <8502556+DocEmmetBrown@users.noreply.github.com> Date: Thu, 26 Jun 2025 23:17:43 +0200 Subject: [PATCH 3/5] add extended descriptions for default return values --- github/billing.go | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/github/billing.go b/github/billing.go index 3fd79f9abe0..808af6914f4 100644 --- a/github/billing.go +++ b/github/billing.go @@ -65,32 +65,37 @@ type AdvancedSecurityCommittersBreakdown struct { // UsageReportOptions specifies optional parameters for the enhanced billing platform usage report. type UsageReportOptions struct { - // If specified, only return results for a single year. The value of year is an integer with four digits representing a year. + // If specified, only return results for a single year. The value of year is an integer with four digits representing a year. For example, 2025. Default value is the current year. + Year *int `url:"year,omitempty"` - // If specified, only return results for a single month. The value of month is an integer between 1 and 12. + // If specified, only return results for a single month. The value of month is an integer between 1 and 12. If no year is specified the default year is used. + Month *int `url:"month,omitempty"` - // If specified, only return results for a single day. The value of day is an integer between 1 and 31. + // If specified, only return results for a single day. The value of day is an integer between 1 and 31. If no year or month is specified, the default year and month are used. + Day *int `url:"day,omitempty"` - // If specified, only return results for a single hour. The value of hour is an integer between 0 and 23. + // If specified, only return results for a single hour. The value of hour is an integer between 0 and 23. If no year, month, or day is specified, the default year, month, and day are used. + Hour *int `url:"hour,omitempty"` } // UsageItem represents a single usage item in the enhanced billing platform report. type UsageItem struct { - Date *string `json:"date"` - Product *string `json:"product"` - SKU *string `json:"sku"` - Quantity *int `json:"quantity"` - UnitType *string `json:"unitType"` - PricePerUnit *float64 `json:"pricePerUnit"` - GrossAmount *float64 `json:"grossAmount"` - DiscountAmount *float64 `json:"discountAmount"` - NetAmount *float64 `json:"netAmount"` - OrganizationName *string `json:"organizationName"` - RepositoryName *string `json:"repositoryName,omitempty"` + Date *string `json:"date"` + Product *string `json:"product"` + SKU *string `json:"sku"` + Quantity *int `json:"quantity"` + UnitType *string `json:"unitType"` + PricePerUnit *float64 `json:"pricePerUnit"` + GrossAmount *float64 `json:"grossAmount"` + DiscountAmount *float64 `json:"discountAmount"` + NetAmount *float64 `json:"netAmount"` + RepositoryName *string `json:"repositoryName,omitempty"` + // Organization name is only used for organization-level reports. + OrganizationName *string `json:"organizationName,omitempty"` } // UsageReport represents the enhanced billing platform usage report response. From 1e99354b1a0de944dd81d1501f0d41e7de781927 Mon Sep 17 00:00:00 2001 From: Guillaume Winter <8502556+DocEmmetBrown@users.noreply.github.com> Date: Fri, 27 Jun 2025 09:00:01 +0200 Subject: [PATCH 4/5] fix coverage complaints --- github/billing_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github/billing_test.go b/github/billing_test.go index ffbb94d112f..3e9c9e7fc42 100644 --- a/github/billing_test.go +++ b/github/billing_test.go @@ -573,7 +573,7 @@ func TestBillingService_GetUsageReportOrg(t *testing.T) { const methodName = "GetUsageReportOrg" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.Billing.GetUsageReportOrg(ctx, "\n", nil) + _, _, err = client.Billing.GetUsageReportOrg(ctx, "\n", opts) return err }) @@ -653,7 +653,7 @@ func TestBillingService_GetUsageReportUser(t *testing.T) { const methodName = "GetUsageReportUser" testBadOptions(t, methodName, func() (err error) { - _, _, err = client.Billing.GetUsageReportUser(ctx, "\n", nil) + _, _, err = client.Billing.GetUsageReportUser(ctx, "\n", opts) return err }) From fb8b9a16188298f39e9beee09634408323315ecc Mon Sep 17 00:00:00 2001 From: Guillaume Winter <8502556+DocEmmetBrown@users.noreply.github.com> Date: Fri, 27 Jun 2025 11:51:24 +0200 Subject: [PATCH 5/5] fix: removing newline to improve docs readability --- github/billing.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/github/billing.go b/github/billing.go index 808af6914f4..2ce595d3349 100644 --- a/github/billing.go +++ b/github/billing.go @@ -65,20 +65,20 @@ type AdvancedSecurityCommittersBreakdown struct { // UsageReportOptions specifies optional parameters for the enhanced billing platform usage report. type UsageReportOptions struct { - // If specified, only return results for a single year. The value of year is an integer with four digits representing a year. For example, 2025. Default value is the current year. - + // If specified, only return results for a single year. The value of year is an integer with four digits representing a year. For example, 2025. + // Default value is the current year. Year *int `url:"year,omitempty"` - // If specified, only return results for a single month. The value of month is an integer between 1 and 12. If no year is specified the default year is used. - + // If specified, only return results for a single month. The value of month is an integer between 1 and 12. + // If no year is specified the default year is used. Month *int `url:"month,omitempty"` - // If specified, only return results for a single day. The value of day is an integer between 1 and 31. If no year or month is specified, the default year and month are used. - + // If specified, only return results for a single day. The value of day is an integer between 1 and 31. + // If no year or month is specified, the default year and month are used. Day *int `url:"day,omitempty"` - // If specified, only return results for a single hour. The value of hour is an integer between 0 and 23. If no year, month, or day is specified, the default year, month, and day are used. - + // If specified, only return results for a single hour. The value of hour is an integer between 0 and 23. + // If no year, month, or day is specified, the default year, month, and day are used. Hour *int `url:"hour,omitempty"` }