Repository: cloudflare/cloudflare-go
Pull request #3714 (2024-12-09 23:51:32)

feat(content_scanning): introduce support


Patch:
diff --git a/.stats.yml b/.stats.yml
index ab5ab2be2..5b02944f4 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,2 @@
-configured_endpoints: 1454
+configured_endpoints: 1460
 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-24f32ff8cc230aecb28b850e99ed99f6f66fba898e64194d21052c4c2b869a24.yml
diff --git a/api.md b/api.md
index fdabfa613..e633233c3 100644
--- a/api.md
+++ b/api.md
@@ -7561,3 +7561,39 @@ Methods:
 - <code title="put /zones/{zone_id}/leaked-credential-checks/detections/{detection_id}">client.LeakedCredentialChecks.Detections.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#LeakedCredentialCheckDetectionService.Update">Update</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, detectionID <a href="https://pkg.go.dev/builtin#string">string</a>, params <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#LeakedCredentialCheckDetectionUpdateParams">LeakedCredentialCheckDetectionUpdateParams</a>) (<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#LeakedCredentialCheckDetectionUpdateResponse">LeakedCredentialCheckDetectionUpdateResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
 - <code title="get /zones/{zone_id}/leaked-credential-checks/detections">client.LeakedCredentialChecks.Detections.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#LeakedCredentialCheckDetectionService.List">List</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, query <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#LeakedCredentialCheckDetectionListParams">LeakedCredentialCheckDetectionListParams</a>) (<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/packages/pagination">pagination</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/packages/pagination#SinglePage">SinglePage</a>[<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#LeakedCredentialCheckDetectionListResponse">LeakedCredentialCheckDetectionListResponse</a>], <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
 - <code title="delete /zones/{zone_id}/leaked-credential-checks/detections/{detection_id}">client.LeakedCredentialChecks.Detections.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#LeakedCredentialCheckDetectionService.Delete">Delete</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, detectionID <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#LeakedCredentialCheckDetectionDeleteParams">LeakedCredentialCheckDetectionDeleteParams</a>) (<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#LeakedCredentialCheckDetectionDeleteResponse">LeakedCredentialCheckDetectionDeleteResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
+
+# ContentScanning
+
+Response Types:
+
+- <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningDisableResponse">ContentScanningDisableResponse</a>
+- <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningEnableResponse">ContentScanningEnableResponse</a>
+
+Methods:
+
+- <code title="post /zones/{zone_id}/content-upload-scan/disable">client.ContentScanning.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningService.Disable">Disable</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, body <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningDisableParams">ContentScanningDisableParams</a>) (<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningDisableResponse">ContentScanningDisableResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
+- <code title="post /zones/{zone_id}/content-upload-scan/enable">client.ContentScanning.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningService.Enable">Enable</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, body <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningEnableParams">ContentScanningEnableParams</a>) (<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningEnableResponse">ContentScanningEnableResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
+
+## Payloads
+
+Response Types:
+
+- <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningPayloadNewResponse">ContentScanningPayloadNewResponse</a>
+- <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningPayloadListResponse">ContentScanningPayloadListResponse</a>
+- <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningPayloadDeleteResponse">ContentScanningPayloadDeleteResponse</a>
+
+Methods:
+
+- <code title="post /zones/{zone_id}/content-upload-scan/payloads">client.ContentScanning.Payloads.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningPayloadService.New">New</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, params <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningPayloadNewParams">ContentScanningPayloadNewParams</a>) ([]<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningPayloadNewResponse">ContentScanningPayloadNewResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
+- <code title="get /zones/{zone_id}/content-upload-scan/payloads">client.ContentScanning.Payloads.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningPayloadService.List">List</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, query <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningPayloadListParams">ContentScanningPayloadListParams</a>) (<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/packages/pagination">pagination</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3/packages/pagination#SinglePage">SinglePage</a>[<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningPayloadListResponse">ContentScanningPayloadListResponse</a>], <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
+- <code title="delete /zones/{zone_id}/content-upload-scan/payloads/{expression_id}">client.ContentScanning.Payloads.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningPayloadService.Delete">Delete</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, expressionID <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningPayloadDeleteParams">ContentScanningPayloadDeleteParams</a>) ([]<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningPayloadDeleteResponse">ContentScanningPayloadDeleteResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
+
+## Settings
+
+Response Types:
+
+- <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningSettingGetResponse">ContentScanningSettingGetResponse</a>
+
+Methods:
+
+- <code title="get /zones/{zone_id}/content-upload-scan/settings">client.ContentScanning.Settings.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningSettingService.Get">Get</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, query <a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningSettingGetParams">ContentScanningSettingGetParams</a>) (<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3">cloudflare</a>.<a href="https://pkg.go.dev/github.com/cloudflare/cloudflare-go/v3#ContentScanningSettingGetResponse">ContentScanningSettingGetResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
diff --git a/client.go b/client.go
index 2e238ac03..e189bb10c 100644
--- a/client.go
+++ b/client.go
@@ -181,6 +181,7 @@ type Client struct {
 	Workflows                   *workflows.WorkflowService
 	ResourceSharing             *resource_sharing.ResourceSharingService
 	LeakedCredentialChecks      *LeakedCredentialCheckService
+	ContentScanning             *ContentScanningService
 }
 
 // NewClient generates a new client with the default option read from the
@@ -289,6 +290,7 @@ func NewClient(opts ...option.RequestOption) (r *Client) {
 	r.Workflows = workflows.NewWorkflowService(opts...)
 	r.ResourceSharing = resource_sharing.NewResourceSharingService(opts...)
 	r.LeakedCredentialChecks = NewLeakedCredentialCheckService(opts...)
+	r.ContentScanning = NewContentScanningService(opts...)
 
 	return
 }
diff --git a/contentscanning.go b/contentscanning.go
new file mode 100644
index 000000000..54e8ffae1
--- /dev/null
+++ b/contentscanning.go
@@ -0,0 +1,173 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package cloudflare
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"net/http"
+
+	"github.com/cloudflare/cloudflare-go/v3/internal/apijson"
+	"github.com/cloudflare/cloudflare-go/v3/internal/param"
+	"github.com/cloudflare/cloudflare-go/v3/internal/requestconfig"
+	"github.com/cloudflare/cloudflare-go/v3/option"
+	"github.com/cloudflare/cloudflare-go/v3/shared"
+)
+
+// ContentScanningService contains methods and other services that help with
+// interacting with the cloudflare API.
+//
+// Note, unlike clients, this service does not read variables from the environment
+// automatically. You should not instantiate this service directly, and instead use
+// the [NewContentScanningService] method instead.
+type ContentScanningService struct {
+	Options  []option.RequestOption
+	Payloads *ContentScanningPayloadService
+	Settings *ContentScanningSettingService
+}
+
+// NewContentScanningService generates a new service that applies the given options
+// to each request. These options are applied after the parent client's options (if
+// there is one), and before any request-specific options.
+func NewContentScanningService(opts ...option.RequestOption) (r *ContentScanningService) {
+	r = &ContentScanningService{}
+	r.Options = opts
+	r.Payloads = NewContentScanningPayloadService(opts...)
+	r.Settings = NewContentScanningSettingService(opts...)
+	return
+}
+
+// Disable Content Scanning
+func (r *ContentScanningService) Disable(ctx context.Context, body ContentScanningDisableParams, opts ...option.RequestOption) (res *ContentScanningDisableResponse, err error) {
+	var env ContentScanningDisableResponseEnvelope
+	opts = append(r.Options[:], opts...)
+	if body.ZoneID.Value == "" {
+		err = errors.New("missing required zone_id parameter")
+		return
+	}
+	path := fmt.Sprintf("zones/%s/content-upload-scan/disable", body.ZoneID)
+	err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &env, opts...)
+	if err != nil {
+		return
+	}
+	res = &env.Result
+	return
+}
+
+// Enable Content Scanning
+func (r *ContentScanningService) Enable(ctx context.Context, body ContentScanningEnableParams, opts ...option.RequestOption) (res *ContentScanningEnableResponse, err error) {
+	var env ContentScanningEnableResponseEnvelope
+	opts = append(r.Options[:], opts...)
+	if body.ZoneID.Value == "" {
+		err = errors.New("missing required zone_id parameter")
+		return
+	}
+	path := fmt.Sprintf("zones/%s/content-upload-scan/enable", body.ZoneID)
+	err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &env, opts...)
+	if err != nil {
+		return
+	}
+	res = &env.Result
+	return
+}
+
+type ContentScanningDisableResponse = interface{}
+
+type ContentScanningEnableResponse = interface{}
+
+type ContentScanningDisableParams struct {
+	// Identifier
+	ZoneID param.Field[string] `path:"zone_id,required"`
+}
+
+type ContentScanningDisableResponseEnvelope struct {
+	Errors   []shared.ResponseInfo          `json:"errors,required"`
+	Messages []shared.ResponseInfo          `json:"messages,required"`
+	Result   ContentScanningDisableResponse `json:"result,required"`
+	// Whether the API call was successful
+	Success ContentScanningDisableResponseEnvelopeSuccess `json:"success,required"`
+	JSON    contentScanningDisableResponseEnvelopeJSON    `json:"-"`
+}
+
+// contentScanningDisableResponseEnvelopeJSON contains the JSON metadata for the
+// struct [ContentScanningDisableResponseEnvelope]
+type contentScanningDisableResponseEnvelopeJSON struct {
+	Errors      apijson.Field
+	Messages    apijson.Field
+	Result      apijson.Field
+	Success     apijson.Field
+	raw         string
+	ExtraFields map[string]apijson.Field
+}
+
+func (r *ContentScanningDisableResponseEnvelope) UnmarshalJSON(data []byte) (err error) {
+	return apijson.UnmarshalRoot(data, r)
+}
+
+func (r contentScanningDisableResponseEnvelopeJSON) RawJSON() string {
+	return r.raw
+}
+
+// Whether the API call was successful
+type ContentScanningDisableResponseEnvelopeSuccess bool
+
+const (
+	ContentScanningDisableResponseEnvelopeSuccessTrue ContentScanningDisableResponseEnvelopeSuccess = true
+)
+
+func (r ContentScanningDisableResponseEnvelopeSuccess) IsKnown() bool {
+	switch r {
+	case ContentScanningDisableResponseEnvelopeSuccessTrue:
+		return true
+	}
+	return false
+}
+
+type ContentScanningEnableParams struct {
+	// Identifier
+	ZoneID param.Field[string] `path:"zone_id,required"`
+}
+
+type ContentScanningEnableResponseEnvelope struct {
+	Errors   []shared.ResponseInfo         `json:"errors,required"`
+	Messages []shared.ResponseInfo         `json:"messages,required"`
+	Result   ContentScanningEnableResponse `json:"result,required"`
+	// Whether the API call was successful
+	Success ContentScanningEnableResponseEnvelopeSuccess `json:"success,required"`
+	JSON    contentScanningEnableResponseEnvelopeJSON    `json:"-"`
+}
+
+// contentScanningEnableResponseEnvelopeJSON contains the JSON metadata for the
+// struct [ContentScanningEnableResponseEnvelope]
+type contentScanningEnableResponseEnvelopeJSON struct {
+	Errors      apijson.Field
+	Messages    apijson.Field
+	Result      apijson.Field
+	Success     apijson.Field
+	raw         string
+	ExtraFields map[string]apijson.Field
+}
+
+func (r *ContentScanningEnableResponseEnvelope) UnmarshalJSON(data []byte) (err error) {
+	return apijson.UnmarshalRoot(data, r)
+}
+
+func (r contentScanningEnableResponseEnvelopeJSON) RawJSON() string {
+	return r.raw
+}
+
+// Whether the API call was successful
+type ContentScanningEnableResponseEnvelopeSuccess bool
+
+const (
+	ContentScanningEnableResponseEnvelopeSuccessTrue ContentScanningEnableResponseEnvelopeSuccess = true
+)
+
+func (r ContentScanningEnableResponseEnvelopeSuccess) IsKnown() bool {
+	switch r {
+	case ContentScanningEnableResponseEnvelopeSuccessTrue:
+		return true
+	}
+	return false
+}
diff --git a/contentscanningpayload.go b/contentscanningpayload.go
new file mode 100644
index 000000000..1c3a8bc3e
--- /dev/null
+++ b/contentscanningpayload.go
@@ -0,0 +1,294 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package cloudflare
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"net/http"
+
+	"github.com/cloudflare/cloudflare-go/v3/internal/apijson"
+	"github.com/cloudflare/cloudflare-go/v3/internal/param"
+	"github.com/cloudflare/cloudflare-go/v3/internal/requestconfig"
+	"github.com/cloudflare/cloudflare-go/v3/option"
+	"github.com/cloudflare/cloudflare-go/v3/packages/pagination"
+	"github.com/cloudflare/cloudflare-go/v3/shared"
+)
+
+// ContentScanningPayloadService contains methods and other services that help with
+// interacting with the cloudflare API.
+//
+// Note, unlike clients, this service does not read variables from the environment
+// automatically. You should not instantiate this service directly, and instead use
+// the [NewContentScanningPayloadService] method instead.
+type ContentScanningPayloadService struct {
+	Options []option.RequestOption
+}
+
+// NewContentScanningPayloadService generates a new service that applies the given
+// options to each request. These options are applied after the parent client's
+// options (if there is one), and before any request-specific options.
+func NewContentScanningPayloadService(opts ...option.RequestOption) (r *ContentScanningPayloadService) {
+	r = &ContentScanningPayloadService{}
+	r.Options = opts
+	return
+}
+
+// Add custom scan expressions for Content Scanning
+func (r *ContentScanningPayloadService) New(ctx context.Context, params ContentScanningPayloadNewParams, opts ...option.RequestOption) (res *[]ContentScanningPayloadNewResponse, err error) {
+	var env ContentScanningPayloadNewResponseEnvelope
+	opts = append(r.Options[:], opts...)
+	if params.ZoneID.Value == "" {
+		err = errors.New("missing required zone_id parameter")
+		return
+	}
+	path := fmt.Sprintf("zones/%s/content-upload-scan/payloads", params.ZoneID)
+	err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &env, opts...)
+	if err != nil {
+		return
+	}
+	res = &env.Result
+	return
+}
+
+// Get a list of existing custom scan expressions for Content Scanning
+func (r *ContentScanningPayloadService) List(ctx context.Context, query ContentScanningPayloadListParams, opts ...option.RequestOption) (res *pagination.SinglePage[ContentScanningPayloadListResponse], err error) {
+	var raw *http.Response
+	opts = append(r.Options[:], opts...)
+	opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...)
+	if query.ZoneID.Value == "" {
+		err = errors.New("missing required zone_id parameter")
+		return
+	}
+	path := fmt.Sprintf("zones/%s/content-upload-scan/payloads", query.ZoneID)
+	cfg, err := requestconfig.NewRequestConfig(ctx, http.MethodGet, path, nil, &res, opts...)
+	if err != nil {
+		return nil, err
+	}
+	err = cfg.Execute()
+	if err != nil {
+		return nil, err
+	}
+	res.SetPageConfig(cfg, raw)
+	return res, nil
+}
+
+// Get a list of existing custom scan expressions for Content Scanning
+func (r *ContentScanningPayloadService) ListAutoPaging(ctx context.Context, query ContentScanningPayloadListParams, opts ...option.RequestOption) *pagination.SinglePageAutoPager[ContentScanningPayloadListResponse] {
+	return pagination.NewSinglePageAutoPager(r.List(ctx, query, opts...))
+}
+
+// Delete a Content Scan Custom Expression
+func (r *ContentScanningPayloadService) Delete(ctx context.Context, expressionID string, body ContentScanningPayloadDeleteParams, opts ...option.RequestOption) (res *[]ContentScanningPayloadDeleteResponse, err error) {
+	var env ContentScanningPayloadDeleteResponseEnvelope
+	opts = append(r.Options[:], opts...)
+	if body.ZoneID.Value == "" {
+		err = errors.New("missing required zone_id parameter")
+		return
+	}
+	if expressionID == "" {
+		err = errors.New("missing required expression_id parameter")
+		return
+	}
+	path := fmt.Sprintf("zones/%s/content-upload-scan/payloads/%s", body.ZoneID, expressionID)
+	err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, &env, opts...)
+	if err != nil {
+		return
+	}
+	res = &env.Result
+	return
+}
+
+// A custom scan expression to match Content Scanning on
+type ContentScanningPayloadNewResponse struct {
+	// The unique ID for this custom scan expression
+	ID string `json:"id"`
+	// Ruleset expression to use in matching content objects
+	Payload string                                `json:"payload"`
+	JSON    contentScanningPayloadNewResponseJSON `json:"-"`
+}
+
+// contentScanningPayloadNewResponseJSON contains the JSON metadata for the struct
+// [ContentScanningPayloadNewResponse]
+type contentScanningPayloadNewResponseJSON struct {
+	ID          apijson.Field
+	Payload     apijson.Field
+	raw         string
+	ExtraFields map[string]apijson.Field
+}
+
+func (r *ContentScanningPayloadNewResponse) UnmarshalJSON(data []byte) (err error) {
+	return apijson.UnmarshalRoot(data, r)
+}
+
+func (r contentScanningPayloadNewResponseJSON) RawJSON() string {
+	return r.raw
+}
+
+// A custom scan expression to match Content Scanning on
+type ContentScanningPayloadListResponse struct {
+	// The unique ID for this custom scan expression
+	ID string `json:"id"`
+	// Ruleset expression to use in matching content objects
+	Payload string                                 `json:"payload"`
+	JSON    contentScanningPayloadListResponseJSON `json:"-"`
+}
+
+// contentScanningPayloadListResponseJSON contains the JSON metadata for the struct
+// [ContentScanningPayloadListResponse]
+type contentScanningPayloadListResponseJSON struct {
+	ID          apijson.Field
+	Payload     apijson.Field
+	raw         string
+	ExtraFields map[string]apijson.Field
+}
+
+func (r *ContentScanningPayloadListResponse) UnmarshalJSON(data []byte) (err error) {
+	return apijson.UnmarshalRoot(data, r)
+}
+
+func (r contentScanningPayloadListResponseJSON) RawJSON() string {
+	return r.raw
+}
+
+// A custom scan expression to match Content Scanning on
+type ContentScanningPayloadDeleteResponse struct {
+	// The unique ID for this custom scan expression
+	ID string `json:"id"`
+	// Ruleset expression to use in matching content objects
+	Payload string                                   `json:"payload"`
+	JSON    contentScanningPayloadDeleteResponseJSON `json:"-"`
+}
+
+// contentScanningPayloadDeleteResponseJSON contains the JSON metadata for the
+// struct [ContentScanningPayloadDeleteResponse]
+type contentScanningPayloadDeleteResponseJSON struct {
+	ID          apijson.Field
+	Payload     apijson.Field
+	raw         string
+	ExtraFields map[string]apijson.Field
+}
+
+func (r *ContentScanningPayloadDeleteResponse) UnmarshalJSON(data []byte) (err error) {
+	return apijson.UnmarshalRoot(data, r)
+}
+
+func (r contentScanningPayloadDeleteResponseJSON) RawJSON() string {
+	return r.raw
+}
+
+type ContentScanningPayloadNewParams struct {
+	// Identifier
+	ZoneID param.Field[string]                   `path:"zone_id,required"`
+	Body   []ContentScanningPayloadNewParamsBody `json:"body,required"`
+}
+
+func (r ContentScanningPayloadNewParams) MarshalJSON() (data []byte, err error) {
+	return apijson.MarshalRoot(r.Body)
+}
+
+type ContentScanningPayloadNewParamsBody struct {
+	// Ruleset expression to use in matching content objects
+	Payload param.Field[string] `json:"payload,required"`
+}
+
+func (r ContentScanningPayloadNewParamsBody) MarshalJSON() (data []byte, err error) {
+	return apijson.MarshalRoot(r)
+}
+
+type ContentScanningPayloadNewResponseEnvelope struct {
+	Errors   []shared.ResponseInfo               `json:"errors,required"`
+	Messages []shared.ResponseInfo               `json:"messages,required"`
+	Result   []ContentScanningPayloadNewResponse `json:"result,required,nullable"`
+	// Whether the API call was successful
+	Success ContentScanningPayloadNewResponseEnvelopeSuccess `json:"success,required"`
+	JSON    contentScanningPayloadNewResponseEnvelopeJSON    `json:"-"`
+}
+
+// contentScanningPayloadNewResponseEnvelopeJSON contains the JSON metadata for the
+// struct [ContentScanningPayloadNewResponseEnvelope]
+type contentScanningPayloadNewResponseEnvelopeJSON struct {
+	Errors      apijson.Field
+	Messages    apijson.Field
+	Result      apijson.Field
+	Success     apijson.Field
+	raw         string
+	ExtraFields map[string]apijson.Field
+}
+
+func (r *ContentScanningPayloadNewResponseEnvelope) UnmarshalJSON(data []byte) (err error) {
+	return apijson.UnmarshalRoot(data, r)
+}
+
+func (r contentScanningPayloadNewResponseEnvelopeJSON) RawJSON() string {
+	return r.raw
+}
+
+// Whether the API call was successful
+type ContentScanningPayloadNewResponseEnvelopeSuccess bool
+
+const (
+	ContentScanningPayloadNewResponseEnvelopeSuccessTrue ContentScanningPayloadNewResponseEnvelopeSuccess = true
+)
+
+func (r ContentScanningPayloadNewResponseEnvelopeSuccess) IsKnown() bool {
+	switch r {
+	case ContentScanningPayloadNewResponseEnvelopeSuccessTrue:
+		return true
+	}
+	return false
+}
+
+type ContentScanningPayloadListParams struct {
+	// Identifier
+	ZoneID param.Field[string] `path:"zone_id,required"`
+}
+
+type ContentScanningPayloadDeleteParams struct {
+	// Identifier
+	ZoneID param.Field[string] `path:"zone_id,required"`
+}
+
+type ContentScanningPayloadDeleteResponseEnvelope struct {
+	Errors   []shared.ResponseInfo                  `json:"errors,required"`
+	Messages []shared.ResponseInfo                  `json:"messages,required"`
+	Result   []ContentScanningPayloadDeleteResponse `json:"result,required,nullable"`
+	// Whether the API call was successful
+	Success ContentScanningPayloadDeleteResponseEnvelopeSuccess `json:"success,required"`
+	JSON    contentScanningPayloadDeleteResponseEnvelopeJSON    `json:"-"`
+}
+
+// contentScanningPayloadDeleteResponseEnvelopeJSON contains the JSON metadata for
+// the struct [ContentScanningPayloadDeleteResponseEnvelope]
+type contentScanningPayloadDeleteResponseEnvelopeJSON struct {
+	Errors      apijson.Field
+	Messages    apijson.Field
+	Result      apijson.Field
+	Success     apijson.Field
+	raw         string
+	ExtraFields map[string]apijson.Field
+}
+
+func (r *ContentScanningPayloadDeleteResponseEnvelope) UnmarshalJSON(data []byte) (err error) {
+	return apijson.UnmarshalRoot(data, r)
+}
+
+func (r contentScanningPayloadDeleteResponseEnvelopeJSON) RawJSON() string {
+	return r.raw
+}
+
+// Whether the API call was successful
+type ContentScanningPayloadDeleteResponseEnvelopeSuccess bool
+
+const (
+	ContentScanningPayloadDeleteResponseEnvelopeSuccessTrue ContentScanningPayloadDeleteResponseEnvelopeSuccess = true
+)
+
+func (r ContentScanningPayloadDeleteResponseEnvelopeSuccess) IsKnown() bool {
+	switch r {
+	case ContentScanningPayloadDeleteResponseEnvelopeSuccessTrue:
+		return true
+	}
+	return false
+}
diff --git a/contentscanningsetting.go b/contentscanningsetting.go
new file mode 100644
index 000000000..bd0e20852
--- /dev/null
+++ b/contentscanningsetting.go
@@ -0,0 +1,127 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package cloudflare
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"net/http"
+
+	"github.com/cloudflare/cloudflare-go/v3/internal/apijson"
+	"github.com/cloudflare/cloudflare-go/v3/internal/param"
+	"github.com/cloudflare/cloudflare-go/v3/internal/requestconfig"
+	"github.com/cloudflare/cloudflare-go/v3/option"
+	"github.com/cloudflare/cloudflare-go/v3/shared"
+)
+
+// ContentScanningSettingService contains methods and other services that help with
+// interacting with the cloudflare API.
+//
+// Note, unlike clients, this service does not read variables from the environment
+// automatically. You should not instantiate this service directly, and instead use
+// the [NewContentScanningSettingService] method instead.
+type ContentScanningSettingService struct {
+	Options []option.RequestOption
+}
+
+// NewContentScanningSettingService generates a new service that applies the given
+// options to each request. These options are applied after the parent client's
+// options (if there is one), and before any request-specific options.
+func NewContentScanningSettingService(opts ...option.RequestOption) (r *ContentScanningSettingService) {
+	r = &ContentScanningSettingService{}
+	r.Options = opts
+	return
+}
+
+// Retrieve the current status of Content Scanning
+func (r *ContentScanningSettingService) Get(ctx context.Context, query ContentScanningSettingGetParams, opts ...option.RequestOption) (res *ContentScanningSettingGetResponse, err error) {
+	var env ContentScanningSettingGetResponseEnvelope
+	opts = append(r.Options[:], opts...)
+	if query.ZoneID.Value == "" {
+		err = errors.New("missing required zone_id parameter")
+		return
+	}
+	path := fmt.Sprintf("zones/%s/content-upload-scan/settings", query.ZoneID)
+	err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &env, opts...)
+	if err != nil {
+		return
+	}
+	res = &env.Result
+	return
+}
+
+// The status for Content Scanning
+type ContentScanningSettingGetResponse struct {
+	// Last modification date (ISO 8601) of the Content Scanning status
+	Modified string `json:"modified"`
+	// Status of Content Scanning
+	Value string                                `json:"value"`
+	JSON  contentScanningSettingGetResponseJSON `json:"-"`
+}
+
+// contentScanningSettingGetResponseJSON contains the JSON metadata for the struct
+// [ContentScanningSettingGetResponse]
+type contentScanningSettingGetResponseJSON struct {
+	Modified    apijson.Field
+	Value       apijson.Field
+	raw         string
+	ExtraFields map[string]apijson.Field
+}
+
+func (r *ContentScanningSettingGetResponse) UnmarshalJSON(data []byte) (err error) {
+	return apijson.UnmarshalRoot(data, r)
+}
+
+func (r contentScanningSettingGetResponseJSON) RawJSON() string {
+	return r.raw
+}
+
+type ContentScanningSettingGetParams struct {
+	// Identifier
+	ZoneID param.Field[string] `path:"zone_id,required"`
+}
+
+type ContentScanningSettingGetResponseEnvelope struct {
+	Errors   []shared.ResponseInfo `json:"errors,required"`
+	Messages []shared.ResponseInfo `json:"messages,required"`
+	// The status for Content Scanning
+	Result ContentScanningSettingGetResponse `json:"result,required"`
+	// Whether the API call was successful
+	Success ContentScanningSettingGetResponseEnvelopeSuccess `json:"success,required"`
+	JSON    contentScanningSettingGetResponseEnvelopeJSON    `json:"-"`
+}
+
+// contentScanningSettingGetResponseEnvelopeJSON contains the JSON metadata for the
+// struct [ContentScanningSettingGetResponseEnvelope]
+type contentScanningSettingGetResponseEnvelopeJSON struct {
+	Errors      apijson.Field
+	Messages    apijson.Field
+	Result      apijson.Field
+	Success     apijson.Field
+	raw         string
+	ExtraFields map[string]apijson.Field
+}
+
+func (r *ContentScanningSettingGetResponseEnvelope) UnmarshalJSON(data []byte) (err error) {
+	return apijson.UnmarshalRoot(data, r)
+}
+
+func (r contentScanningSettingGetResponseEnvelopeJSON) RawJSON() string {
+	return r.raw
+}
+
+// Whether the API call was successful
+type ContentScanningSettingGetResponseEnvelopeSuccess bool
+
+const (
+	ContentScanningSettingGetResponseEnvelopeSuccessTrue ContentScanningSettingGetResponseEnvelopeSuccess = true
+)
+
+func (r ContentScanningSettingGetResponseEnvelopeSuccess) IsKnown() bool {
+	switch r {
+	case ContentScanningSettingGetResponseEnvelopeSuccessTrue:
+		return true
+	}
+	return false
+}


Test patch:
diff --git a/contentscanning_test.go b/contentscanning_test.go
new file mode 100644
index 000000000..552ee0d36
--- /dev/null
+++ b/contentscanning_test.go
@@ -0,0 +1,64 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package cloudflare_test
+
+import (
+	"context"
+	"errors"
+	"os"
+	"testing"
+
+	"github.com/cloudflare/cloudflare-go/v3"
+	"github.com/cloudflare/cloudflare-go/v3/internal/testutil"
+	"github.com/cloudflare/cloudflare-go/v3/option"
+)
+
+func TestContentScanningDisable(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 := cloudflare.NewClient(
+		option.WithBaseURL(baseURL),
+		option.WithAPIKey("144c9defac04969c7bfad8efaa8ea194"),
+		option.WithAPIEmail("user@example.com"),
+	)
+	_, err := client.ContentScanning.Disable(context.TODO(), cloudflare.ContentScanningDisableParams{
+		ZoneID: cloudflare.F("023e105f4ecef8ad9ca31a8372d0c353"),
+	})
+	if err != nil {
+		var apierr *cloudflare.Error
+		if errors.As(err, &apierr) {
+			t.Log(string(apierr.DumpRequest(true)))
+		}
+		t.Fatalf("err should be nil: %s", err.Error())
+	}
+}
+
+func TestContentScanningEnable(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 := cloudflare.NewClient(
+		option.WithBaseURL(baseURL),
+		option.WithAPIKey("144c9defac04969c7bfad8efaa8ea194"),
+		option.WithAPIEmail("user@example.com"),
+	)
+	_, err := client.ContentScanning.Enable(context.TODO(), cloudflare.ContentScanningEnableParams{
+		ZoneID: cloudflare.F("023e105f4ecef8ad9ca31a8372d0c353"),
+	})
+	if err != nil {
+		var apierr *cloudflare.Error
+		if errors.As(err, &apierr) {
+			t.Log(string(apierr.DumpRequest(true)))
+		}
+		t.Fatalf("err should be nil: %s", err.Error())
+	}
+}
diff --git a/contentscanningpayload_test.go b/contentscanningpayload_test.go
new file mode 100644
index 000000000..155dba872
--- /dev/null
+++ b/contentscanningpayload_test.go
@@ -0,0 +1,96 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package cloudflare_test
+
+import (
+	"context"
+	"errors"
+	"os"
+	"testing"
+
+	"github.com/cloudflare/cloudflare-go/v3"
+	"github.com/cloudflare/cloudflare-go/v3/internal/testutil"
+	"github.com/cloudflare/cloudflare-go/v3/option"
+)
+
+func TestContentScanningPayloadNew(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 := cloudflare.NewClient(
+		option.WithBaseURL(baseURL),
+		option.WithAPIKey("144c9defac04969c7bfad8efaa8ea194"),
+		option.WithAPIEmail("user@example.com"),
+	)
+	_, err := client.ContentScanning.Payloads.New(context.TODO(), cloudflare.ContentScanningPayloadNewParams{
+		ZoneID: cloudflare.F("023e105f4ecef8ad9ca31a8372d0c353"),
+		Body: []cloudflare.ContentScanningPayloadNewParamsBody{{
+			Payload: cloudflare.F("lookup_json_string(http.request.body.raw, \"file\")"),
+		}},
+	})
+	if err != nil {
+		var apierr *cloudflare.Error
+		if errors.As(err, &apierr) {
+			t.Log(string(apierr.DumpRequest(true)))
+		}
+		t.Fatalf("err should be nil: %s", err.Error())
+	}
+}
+
+func TestContentScanningPayloadList(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 := cloudflare.NewClient(
+		option.WithBaseURL(baseURL),
+		option.WithAPIKey("144c9defac04969c7bfad8efaa8ea194"),
+		option.WithAPIEmail("user@example.com"),
+	)
+	_, err := client.ContentScanning.Payloads.List(context.TODO(), cloudflare.ContentScanningPayloadListParams{
+		ZoneID: cloudflare.F("023e105f4ecef8ad9ca31a8372d0c353"),
+	})
+	if err != nil {
+		var apierr *cloudflare.Error
+		if errors.As(err, &apierr) {
+			t.Log(string(apierr.DumpRequest(true)))
+		}
+		t.Fatalf("err should be nil: %s", err.Error())
+	}
+}
+
+func TestContentScanningPayloadDelete(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 := cloudflare.NewClient(
+		option.WithBaseURL(baseURL),
+		option.WithAPIKey("144c9defac04969c7bfad8efaa8ea194"),
+		option.WithAPIEmail("user@example.com"),
+	)
+	_, err := client.ContentScanning.Payloads.Delete(
+		context.TODO(),
+		"a350a054caa840c9becd89c3b4f0195b",
+		cloudflare.ContentScanningPayloadDeleteParams{
+			ZoneID: cloudflare.F("023e105f4ecef8ad9ca31a8372d0c353"),
+		},
+	)
+	if err != nil {
+		var apierr *cloudflare.Error
+		if errors.As(err, &apierr) {
+			t.Log(string(apierr.DumpRequest(true)))
+		}
+		t.Fatalf("err should be nil: %s", err.Error())
+	}
+}
diff --git a/contentscanningsetting_test.go b/contentscanningsetting_test.go
new file mode 100644
index 000000000..6a96d4137
--- /dev/null
+++ b/contentscanningsetting_test.go
@@ -0,0 +1,39 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package cloudflare_test
+
+import (
+	"context"
+	"errors"
+	"os"
+	"testing"
+
+	"github.com/cloudflare/cloudflare-go/v3"
+	"github.com/cloudflare/cloudflare-go/v3/internal/testutil"
+	"github.com/cloudflare/cloudflare-go/v3/option"
+)
+
+func TestContentScanningSettingGet(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 := cloudflare.NewClient(
+		option.WithBaseURL(baseURL),
+		option.WithAPIKey("144c9defac04969c7bfad8efaa8ea194"),
+		option.WithAPIEmail("user@example.com"),
+	)
+	_, err := client.ContentScanning.Settings.Get(context.TODO(), cloudflare.ContentScanningSettingGetParams{
+		ZoneID: cloudflare.F("023e105f4ecef8ad9ca31a8372d0c353"),
+	})
+	if err != nil {
+		var apierr *cloudflare.Error
+		if errors.As(err, &apierr) {
+			t.Log(string(apierr.DumpRequest(true)))
+		}
+		t.Fatalf("err should be nil: %s", err.Error())
+	}
+}