Repository: cloudflare/cloudflare-go
Pull request #1326 (2023-07-05 03:42:27)

logpush: modernise methods
Updates the logpush methods to:

- Use the newer client method signatures 
- Remove the duplicate internal methods
for account/zone level methods in favour of using `*ResourceContainer` 
- Stop using `AccessIdentifiers`

This introduces a bit more duplication in the `Create`/`Update` methods however
it does allow us to handle creation and updates separately explicitly instead
of bunching all the logic into a single method with conditionals.

github-actions[bot]: Oops! It looks like no changelog entry is attached to this PR. Please include a release note as described in https://github.com/cloudflare/cloudflare-go/blob/master/docs/changelog-process.md.

Example: 

~~~
```release-note:TYPE
Release note
```
~~~

If you do not require a release note to be included, please add the `workflow/skip-changelog-entry` label.

Patch:
diff --git a/.changelog/1326.txt b/.changelog/1326.txt
new file mode 100644
index 000000000..fd85096d0
--- /dev/null
+++ b/.changelog/1326.txt
@@ -0,0 +1,83 @@
+```release-note:breaking-change
+logpush: all methods are updated to use the newer client conventions for method signatures
+```
+
+```release-note:breaking-change
+logpush: `CreateAccountLogpushJob` is removed in favour of `CreateLogpushJob` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `CreateZoneLogpushJob` is removed in favour of `CreateLogpushJob` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `ListAccountLogpushJobs` is removed in favour of `ListLogpushJobs` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `ListZoneLogpushJobs` is removed in favour of `ListLogpushJobs` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `ListAccountLogpushJobsForDataset` is removed in favour of `ListLogpushJobsForDataset` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `ListZoneLogpushJobsForDataset` is removed in favour of `ListLogpushJobsForDataset` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `GetAccountLogpushFields` is removed in favour of `GetLogpushFields` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `GetZoneLogpushFields` is removed in favour of `GetLogpushFields` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `GetAccountLogpushJob` is removed in favour of `GetLogpushJob` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `GetZoneLogpushJob` is removed in favour of `GetLogpushJob` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `UpdateAccountLogpushJob` is removed in favour of `UpdateLogpushJob` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `UpdateZoneLogpushJob` is removed in favour of `UpdateLogpushJob` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `DeleteAccountLogpushJob` is removed in favour of `DeleteLogpushJob` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `DeleteZoneLogpushJob` is removed in favour of `DeleteLogpushJob` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `GetAccountLogpushOwnershipChallenge` is removed in favour of `GetLogpushOwnershipChallenge` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `GetZoneLogpushOwnershipChallenge` is removed in favour of `GetLogpushOwnershipChallenge` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `ValidateAccountLogpushOwnershipChallenge` is removed in favour of `ValidateLogpushOwnershipChallenge` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `ValidateZoneLogpushOwnershipChallenge` is removed in favour of `ValidateLogpushOwnershipChallenge` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `CheckAccountLogpushDestinationExists` is removed in favour of `CheckLogpushDestinationExists` with `ResourceContainer` method parameter
+```
+
+```release-note:breaking-change
+logpush: `CheckZoneLogpushDestinationExists` is removed in favour of `CheckLogpushDestinationExists` with `ResourceContainer` method parameter
+```
diff --git a/access_policy.go b/access_policy.go
index b6d10031d..f7da401fb 100644
--- a/access_policy.go
+++ b/access_policy.go
@@ -101,6 +101,33 @@ type CreateAccessPolicyParams struct {
 	Require []interface{} `json:"require"`
 }
 
+type UpdateAccessPolicyParams struct {
+	ApplicationID string `json:"-"`
+	PolicyID      string `json:"-"`
+
+	Precedence int    `json:"precedence"`
+	Decision   string `json:"decision"`
+	Name       string `json:"name"`
+
+	IsolationRequired            *bool                 `json:"isolation_required,omitempty"`
+	PurposeJustificationRequired *bool                 `json:"purpose_justification_required,omitempty"`
+	PurposeJustificationPrompt   *string               `json:"purpose_justification_prompt,omitempty"`
+	ApprovalRequired             *bool                 `json:"approval_required,omitempty"`
+	ApprovalGroups               []AccessApprovalGroup `json:"approval_groups"`
+
+	// The include policy works like an OR logical operator. The user must
+	// satisfy one of the rules.
+	Include []interface{} `json:"include"`
+
+	// The exclude policy works like a NOT logical operator. The user must
+	// not satisfy all the rules in exclude.
+	Exclude []interface{} `json:"exclude"`
+
+	// The require policy works like a AND logical operator. The user must
+	// satisfy all the rules in require.
+	Require []interface{} `json:"require"`
+}
+
 type DeleteAccessPolicyParams struct {
 	ApplicationID string `json:"-"`
 	PolicyID      string `json:"-"`
@@ -215,19 +242,20 @@ func (api *API) CreateAccessPolicy(ctx context.Context, rc *ResourceContainer, p
 //
 // Account API reference: https://developers.cloudflare.com/api/operations/access-policies-update-an-access-policy
 // Zone API reference: https://developers.cloudflare.com/api/operations/zone-level-access-policies-update-an-access-policy
-func (api *API) UpdateAccessPolicy(ctx context.Context, rc *ResourceContainer, applicationID string, accessPolicy AccessPolicy) (AccessPolicy, error) {
-	if accessPolicy.ID == "" {
+func (api *API) UpdateAccessPolicy(ctx context.Context, rc *ResourceContainer, params UpdateAccessPolicyParams) (AccessPolicy, error) {
+	if params.PolicyID == "" {
 		return AccessPolicy{}, fmt.Errorf("access policy ID cannot be empty")
 	}
+
 	uri := fmt.Sprintf(
 		"/%s/%s/access/apps/%s/policies/%s",
 		rc.Level,
 		rc.Identifier,
-		applicationID,
-		accessPolicy.ID,
+		params.ApplicationID,
+		params.PolicyID,
 	)
 
-	res, err := api.makeRequestContext(ctx, http.MethodPut, uri, accessPolicy)
+	res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params)
 	if err != nil {
 		return AccessPolicy{}, fmt.Errorf("%s: %w", errMakeRequestError, err)
 	}
diff --git a/logpush.go b/logpush.go
index 8b3a70cb1..8ddf4c219 100644
--- a/logpush.go
+++ b/logpush.go
@@ -181,6 +181,106 @@ func (f *LogpushJob) UnmarshalJSON(data []byte) error {
 	return nil
 }
 
+func (f CreateLogpushJobParams) MarshalJSON() ([]byte, error) {
+	type Alias CreateLogpushJobParams
+
+	var filter string
+
+	if f.Filter != nil {
+		b, err := json.Marshal(f.Filter)
+
+		if err != nil {
+			return nil, err
+		}
+
+		filter = string(b)
+	}
+
+	return json.Marshal(&struct {
+		Filter string `json:"filter,omitempty"`
+		Alias
+	}{
+		Filter: filter,
+		Alias:  (Alias)(f),
+	})
+}
+
+// Custom Unmarshaller for CreateLogpushJobParams filter key.
+func (f *CreateLogpushJobParams) UnmarshalJSON(data []byte) error {
+	type Alias CreateLogpushJobParams
+	aux := &struct {
+		Filter string `json:"filter,omitempty"`
+		*Alias
+	}{
+		Alias: (*Alias)(f),
+	}
+	if err := json.Unmarshal(data, &aux); err != nil {
+		return err
+	}
+
+	if aux != nil && aux.Filter != "" {
+		var filter LogpushJobFilters
+		if err := json.Unmarshal([]byte(aux.Filter), &filter); err != nil {
+			return err
+		}
+		if err := filter.Where.Validate(); err != nil {
+			return err
+		}
+		f.Filter = &filter
+	}
+	return nil
+}
+
+func (f UpdateLogpushJobParams) MarshalJSON() ([]byte, error) {
+	type Alias UpdateLogpushJobParams
+
+	var filter string
+
+	if f.Filter != nil {
+		b, err := json.Marshal(f.Filter)
+
+		if err != nil {
+			return nil, err
+		}
+
+		filter = string(b)
+	}
+
+	return json.Marshal(&struct {
+		Filter string `json:"filter,omitempty"`
+		Alias
+	}{
+		Filter: filter,
+		Alias:  (Alias)(f),
+	})
+}
+
+// Custom Unmarshaller for UpdateLogpushJobParams filter key.
+func (f *UpdateLogpushJobParams) UnmarshalJSON(data []byte) error {
+	type Alias UpdateLogpushJobParams
+	aux := &struct {
+		Filter string `json:"filter,omitempty"`
+		*Alias
+	}{
+		Alias: (*Alias)(f),
+	}
+	if err := json.Unmarshal(data, &aux); err != nil {
+		return err
+	}
+
+	if aux != nil && aux.Filter != "" {
+		var filter LogpushJobFilters
+		if err := json.Unmarshal([]byte(aux.Filter), &filter); err != nil {
+			return err
+		}
+		if err := filter.Where.Validate(); err != nil {
+			return err
+		}
+		f.Filter = &filter
+	}
+	return nil
+}
+
 func (filter *LogpushJobFilter) Validate() error {
 	if filter.And != nil {
 		if filter.Or != nil || filter.Key != "" || filter.Operator != "" || filter.Value != nil {
@@ -221,33 +321,66 @@ func (filter *LogpushJobFilter) Validate() error {
 	return nil
 }
 
-// CreateAccountLogpushJob creates a new account-level Logpush Job.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-create-logpush-job
-func (api *API) CreateAccountLogpushJob(ctx context.Context, accountID string, job LogpushJob) (*LogpushJob, error) {
-	return api.createLogpushJob(ctx, AccountRouteRoot, accountID, job)
+type CreateLogpushJobParams struct {
+	Dataset                  string             `json:"dataset"`
+	Enabled                  bool               `json:"enabled"`
+	Kind                     string             `json:"kind,omitempty"`
+	Name                     string             `json:"name"`
+	LogpullOptions           string             `json:"logpull_options"`
+	DestinationConf          string             `json:"destination_conf"`
+	OwnershipChallenge       string             `json:"ownership_challenge,omitempty"`
+	ErrorMessage             string             `json:"error_message,omitempty"`
+	Frequency                string             `json:"frequency,omitempty"`
+	Filter                   *LogpushJobFilters `json:"filter,omitempty"`
+	MaxUploadBytes           int                `json:"max_upload_bytes,omitempty"`
+	MaxUploadRecords         int                `json:"max_upload_records,omitempty"`
+	MaxUploadIntervalSeconds int                `json:"max_upload_interval_seconds,omitempty"`
 }
 
-// CreateZoneLogpushJob creates a new zone-level Logpush Job.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-create-logpush-job
-func (api *API) CreateZoneLogpushJob(ctx context.Context, zoneID string, job LogpushJob) (*LogpushJob, error) {
-	return api.createLogpushJob(ctx, ZoneRouteRoot, zoneID, job)
+type ListLogpushJobsParams struct{}
+
+type ListLogpushJobsForDatasetParams struct {
+	Dataset string `json:"-"`
+}
+
+type GetLogpushFieldsParams struct {
+	Dataset string `json:"-"`
+}
+
+type UpdateLogpushJobParams struct {
+	ID                       int                `json:"-"`
+	Dataset                  string             `json:"dataset"`
+	Enabled                  bool               `json:"enabled"`
+	Kind                     string             `json:"kind,omitempty"`
+	Name                     string             `json:"name"`
+	LogpullOptions           string             `json:"logpull_options"`
+	DestinationConf          string             `json:"destination_conf"`
+	OwnershipChallenge       string             `json:"ownership_challenge,omitempty"`
+	LastComplete             *time.Time         `json:"last_complete,omitempty"`
+	LastError                *time.Time         `json:"last_error,omitempty"`
+	ErrorMessage             string             `json:"error_message,omitempty"`
+	Frequency                string             `json:"frequency,omitempty"`
+	Filter                   *LogpushJobFilters `json:"filter,omitempty"`
+	MaxUploadBytes           int                `json:"max_upload_bytes,omitempty"`
+	MaxUploadRecords         int                `json:"max_upload_records,omitempty"`
+	MaxUploadIntervalSeconds int                `json:"max_upload_interval_seconds,omitempty"`
+}
+
+type ValidateLogpushOwnershipChallengeParams struct {
+	DestinationConf    string `json:"destination_conf"`
+	OwnershipChallenge string `json:"ownership_challenge"`
+}
+
+type GetLogpushOwnershipChallengeParams struct {
+	DestinationConf string `json:"destination_conf"`
 }
 
 // CreateLogpushJob creates a new zone-level Logpush Job.
 //
 // API reference: https://api.cloudflare.com/#logpush-jobs-create-logpush-job
-//
-// Deprecated: Use `CreateZoneLogpushJob` or `CreateAccountLogpushJob` depending
-// on the desired resource to target.
-func (api *API) CreateLogpushJob(ctx context.Context, zoneID string, job LogpushJob) (*LogpushJob, error) {
-	return api.createLogpushJob(ctx, ZoneRouteRoot, zoneID, job)
-}
-
-func (api *API) createLogpushJob(ctx context.Context, identifierType RouteRoot, identifier string, job LogpushJob) (*LogpushJob, error) {
-	uri := fmt.Sprintf("/%s/%s/logpush/jobs", identifierType, identifier)
-	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, job)
+func (api *API) CreateLogpushJob(ctx context.Context, rc *ResourceContainer, params CreateLogpushJobParams) (*LogpushJob, error) {
+	uri := fmt.Sprintf("/%s/%s/logpush/jobs", rc.Level, rc.Identifier)
+	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
 	if err != nil {
 		return nil, err
 	}
@@ -259,32 +392,11 @@ func (api *API) createLogpushJob(ctx context.Context, identifierType RouteRoot,
 	return &r.Result, nil
 }
 
-// ListAccountLogpushJobs returns all account-level Logpush Jobs for all datasets.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-list-logpush-jobs
-func (api *API) ListAccountLogpushJobs(ctx context.Context, accountID string) ([]LogpushJob, error) {
-	return api.listLogpushJobs(ctx, AccountRouteRoot, accountID)
-}
-
-// ListZoneLogpushJobs returns all zone-level Logpush Jobs for all datasets.
+// ListAccountLogpushJobs returns all Logpush Jobs for all datasets.
 //
 // API reference: https://api.cloudflare.com/#logpush-jobs-list-logpush-jobs
-func (api *API) ListZoneLogpushJobs(ctx context.Context, zoneID string) ([]LogpushJob, error) {
-	return api.listLogpushJobs(ctx, ZoneRouteRoot, zoneID)
-}
-
-// LogpushJobs returns all zone-level Logpush Jobs for all datasets.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-list-logpush-jobs
-//
-// Deprecated: Use `ListZoneLogpushJobs` or `ListAccountLogpushJobs`
-// depending on the desired resource to target.
-func (api *API) LogpushJobs(ctx context.Context, zoneID string) ([]LogpushJob, error) {
-	return api.listLogpushJobs(ctx, ZoneRouteRoot, zoneID)
-}
-
-func (api *API) listLogpushJobs(ctx context.Context, identifierType RouteRoot, identifier string) ([]LogpushJob, error) {
-	uri := fmt.Sprintf("/%s/%s/logpush/jobs", identifierType, identifier)
+func (api *API) ListLogpushJobs(ctx context.Context, rc *ResourceContainer, params ListLogpushJobsParams) ([]LogpushJob, error) {
+	uri := fmt.Sprintf("/%s/%s/logpush/jobs", rc.Level, rc.Identifier)
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
 		return []LogpushJob{}, err
@@ -297,33 +409,11 @@ func (api *API) listLogpushJobs(ctx context.Context, identifierType RouteRoot, i
 	return r.Result, nil
 }
 
-// ListAccountLogpushJobsForDataset returns all account-level Logpush Jobs for a dataset.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-list-logpush-jobs-for-a-dataset
-func (api *API) ListAccountLogpushJobsForDataset(ctx context.Context, accountID, dataset string) ([]LogpushJob, error) {
-	return api.listLogpushJobsForDataset(ctx, AccountRouteRoot, accountID, dataset)
-}
-
-// ListZoneLogpushJobsForDataset returns all zone-level Logpush Jobs for a dataset.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-list-logpush-jobs-for-a-dataset
-func (api *API) ListZoneLogpushJobsForDataset(ctx context.Context, zoneID, dataset string) ([]LogpushJob, error) {
-	return api.listLogpushJobsForDataset(ctx, ZoneRouteRoot, zoneID, dataset)
-}
-
-// LogpushJobsForDataset returns all zone-level Logpush Jobs for a dataset.
+// LogpushJobsForDataset returns all Logpush Jobs for a dataset.
 //
 // API reference: https://api.cloudflare.com/#logpush-jobs-list-logpush-jobs-for-a-dataset
-//
-// Deprecated: Use `ListZoneLogpushJobsForDataset` or
-// `ListAccountLogpushJobsForDataset` depending on the desired resource
-// to target.
-func (api *API) LogpushJobsForDataset(ctx context.Context, zoneID, dataset string) ([]LogpushJob, error) {
-	return api.listLogpushJobsForDataset(ctx, ZoneRouteRoot, zoneID, dataset)
-}
-
-func (api *API) listLogpushJobsForDataset(ctx context.Context, identifierType RouteRoot, identifier, dataset string) ([]LogpushJob, error) {
-	uri := fmt.Sprintf("/%s/%s/logpush/datasets/%s/jobs", identifierType, identifier, dataset)
+func (api *API) ListLogpushJobsForDataset(ctx context.Context, rc *ResourceContainer, params ListLogpushJobsForDatasetParams) ([]LogpushJob, error) {
+	uri := fmt.Sprintf("/%s/%s/logpush/datasets/%s/jobs", rc.Level, rc.Identifier, params.Dataset)
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
 		return []LogpushJob{}, err
@@ -336,36 +426,11 @@ func (api *API) listLogpushJobsForDataset(ctx context.Context, identifierType Ro
 	return r.Result, nil
 }
 
-// GetAccountLogpushFields returns fields for a given account-level dataset.
-//
-// Account fields documentation: https://developers.cloudflare.com/logs/reference/log-fields/account
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-list-logpush-jobs
-func (api *API) GetAccountLogpushFields(ctx context.Context, accountID, dataset string) (LogpushFields, error) {
-	return api.getLogpushFields(ctx, AccountRouteRoot, accountID, dataset)
-}
-
-// GetZoneLogpushFields returns fields for a given zone-level dataset.
-//
-// Zone fields documentation: https://developers.cloudflare.com/logs/reference/log-fields/zone
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-list-logpush-jobs
-func (api *API) GetZoneLogpushFields(ctx context.Context, zoneID, dataset string) (LogpushFields, error) {
-	return api.getLogpushFields(ctx, ZoneRouteRoot, zoneID, dataset)
-}
-
 // LogpushFields returns fields for a given dataset.
 //
 // API reference: https://api.cloudflare.com/#logpush-jobs-list-logpush-jobs
-//
-// Deprecated: Use `GetZoneLogpushFields` or `GetAccountLogpushFields`
-// depending on the desired resource to target.
-func (api *API) LogpushFields(ctx context.Context, zoneID, dataset string) (LogpushFields, error) {
-	return api.getLogpushFields(ctx, ZoneRouteRoot, zoneID, dataset)
-}
-
-func (api *API) getLogpushFields(ctx context.Context, identifierType RouteRoot, identifier, dataset string) (LogpushFields, error) {
-	uri := fmt.Sprintf("/%s/%s/logpush/datasets/%s/fields", identifierType, identifier, dataset)
+func (api *API) GetLogpushFields(ctx context.Context, rc *ResourceContainer, params GetLogpushFieldsParams) (LogpushFields, error) {
+	uri := fmt.Sprintf("/%s/%s/logpush/datasets/%s/fields", rc.Level, rc.Identifier, params.Dataset)
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
 		return LogpushFields{}, err
@@ -378,32 +443,11 @@ func (api *API) getLogpushFields(ctx context.Context, identifierType RouteRoot,
 	return r.Result, nil
 }
 
-// GetAccountLogpushJob fetches detail about one account-level Logpush Job.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-logpush-job-details
-func (api *API) GetAccountLogpushJob(ctx context.Context, accountID string, jobID int) (LogpushJob, error) {
-	return api.getLogpushJob(ctx, AccountRouteRoot, accountID, jobID)
-}
-
-// GetZoneLogpushJob fetches detail about one Logpush Job for a zone.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-logpush-job-details
-func (api *API) GetZoneLogpushJob(ctx context.Context, zoneID string, jobID int) (LogpushJob, error) {
-	return api.getLogpushJob(ctx, ZoneRouteRoot, zoneID, jobID)
-}
-
 // LogpushJob fetches detail about one Logpush Job for a zone.
 //
 // API reference: https://api.cloudflare.com/#logpush-jobs-logpush-job-details
-//
-// Deprecated: Use `GetZoneLogpushJob` or `GetAccountLogpushJob`
-// depending on the desired resource to target.
-func (api *API) LogpushJob(ctx context.Context, zoneID string, jobID int) (LogpushJob, error) {
-	return api.getLogpushJob(ctx, ZoneRouteRoot, zoneID, jobID)
-}
-
-func (api *API) getLogpushJob(ctx context.Context, identifierType RouteRoot, identifier string, jobID int) (LogpushJob, error) {
-	uri := fmt.Sprintf("/%s/%s/logpush/jobs/%d", identifierType, identifier, jobID)
+func (api *API) GetLogpushJob(ctx context.Context, rc *ResourceContainer, jobID int) (LogpushJob, error) {
+	uri := fmt.Sprintf("/%s/%s/logpush/jobs/%d", rc.Level, rc.Identifier, jobID)
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
 		return LogpushJob{}, err
@@ -416,33 +460,12 @@ func (api *API) getLogpushJob(ctx context.Context, identifierType RouteRoot, ide
 	return r.Result, nil
 }
 
-// UpdateAccountLogpushJob lets you update an account-level Logpush Job.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-update-logpush-job
-func (api *API) UpdateAccountLogpushJob(ctx context.Context, accountID string, jobID int, job LogpushJob) error {
-	return api.updateLogpushJob(ctx, AccountRouteRoot, accountID, jobID, job)
-}
-
-// UpdateZoneLogpushJob lets you update a Logpush Job for a zone.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-update-logpush-job
-func (api *API) UpdateZoneLogpushJob(ctx context.Context, zoneID string, jobID int, job LogpushJob) error {
-	return api.updateLogpushJob(ctx, ZoneRouteRoot, zoneID, jobID, job)
-}
-
 // UpdateLogpushJob lets you update a Logpush Job.
 //
 // API reference: https://api.cloudflare.com/#logpush-jobs-update-logpush-job
-//
-// Deprecated: Use `UpdateZoneLogpushJob` or `UpdateAccountLogpushJob`
-// depending on the desired resource to target.
-func (api *API) UpdateLogpushJob(ctx context.Context, zoneID string, jobID int, job LogpushJob) error {
-	return api.updateLogpushJob(ctx, ZoneRouteRoot, zoneID, jobID, job)
-}
-
-func (api *API) updateLogpushJob(ctx context.Context, identifierType RouteRoot, identifier string, jobID int, job LogpushJob) error {
-	uri := fmt.Sprintf("/%s/%s/logpush/jobs/%d", identifierType, identifier, jobID)
-	res, err := api.makeRequestContext(ctx, http.MethodPut, uri, job)
+func (api *API) UpdateLogpushJob(ctx context.Context, rc *ResourceContainer, params UpdateLogpushJobParams) error {
+	uri := fmt.Sprintf("/%s/%s/logpush/jobs/%d", rc.Level, rc.Identifier, params.ID)
+	res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params)
 	if err != nil {
 		return err
 	}
@@ -454,32 +477,11 @@ func (api *API) updateLogpushJob(ctx context.Context, identifierType RouteRoot,
 	return nil
 }
 
-// DeleteAccountLogpushJob deletes an account-level Logpush Job.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-delete-logpush-job
-func (api *API) DeleteAccountLogpushJob(ctx context.Context, accountID string, jobID int) error {
-	return api.deleteLogpushJob(ctx, AccountRouteRoot, accountID, jobID)
-}
-
-// DeleteZoneLogpushJob deletes a Logpush Job for a zone.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-delete-logpush-job
-func (api *API) DeleteZoneLogpushJob(ctx context.Context, zoneID string, jobID int) error {
-	return api.deleteLogpushJob(ctx, ZoneRouteRoot, zoneID, jobID)
-}
-
 // DeleteLogpushJob deletes a Logpush Job for a zone.
 //
 // API reference: https://api.cloudflare.com/#logpush-jobs-delete-logpush-job
-//
-// Deprecated: Use `DeleteZoneLogpushJob` or `DeleteAccountLogpushJob`
-// depending on the desired resource to target.
-func (api *API) DeleteLogpushJob(ctx context.Context, zoneID string, jobID int) error {
-	return api.deleteLogpushJob(ctx, ZoneRouteRoot, zoneID, jobID)
-}
-
-func (api *API) deleteLogpushJob(ctx context.Context, identifierType RouteRoot, identifier string, jobID int) error {
-	uri := fmt.Sprintf("/%s/%s/logpush/jobs/%d", identifierType, identifier, jobID)
+func (api *API) DeleteLogpushJob(ctx context.Context, rc *ResourceContainer, jobID int) error {
+	uri := fmt.Sprintf("/%s/%s/logpush/jobs/%d", rc.Level, rc.Identifier, jobID)
 	res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
 	if err != nil {
 		return err
@@ -492,36 +494,12 @@ func (api *API) deleteLogpushJob(ctx context.Context, identifierType RouteRoot,
 	return nil
 }
 
-// GetAccountLogpushOwnershipChallenge returns ownership challenge.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-get-ownership-challenge
-func (api *API) GetAccountLogpushOwnershipChallenge(ctx context.Context, accountID, destinationConf string) (*LogpushGetOwnershipChallenge, error) {
-	return api.getLogpushOwnershipChallenge(ctx, AccountRouteRoot, accountID, destinationConf)
-}
-
-// GetZoneLogpushOwnershipChallenge returns ownership challenge.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-get-ownership-challenge
-func (api *API) GetZoneLogpushOwnershipChallenge(ctx context.Context, zoneID, destinationConf string) (*LogpushGetOwnershipChallenge, error) {
-	return api.getLogpushOwnershipChallenge(ctx, ZoneRouteRoot, zoneID, destinationConf)
-}
-
 // GetLogpushOwnershipChallenge returns ownership challenge.
 //
 // API reference: https://api.cloudflare.com/#logpush-jobs-get-ownership-challenge
-//
-// Deprecated: Use `GetZoneLogpushOwnershipChallenge` or
-// `GetAccountLogpushOwnershipChallenge` depending on the
-// desired resource to target.
-func (api *API) GetLogpushOwnershipChallenge(ctx context.Context, zoneID, destinationConf string) (*LogpushGetOwnershipChallenge, error) {
-	return api.getLogpushOwnershipChallenge(ctx, ZoneRouteRoot, zoneID, destinationConf)
-}
-
-func (api *API) getLogpushOwnershipChallenge(ctx context.Context, identifierType RouteRoot, identifier, destinationConf string) (*LogpushGetOwnershipChallenge, error) {
-	uri := fmt.Sprintf("/%s/%s/logpush/ownership", identifierType, identifier)
-	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, LogpushGetOwnershipChallengeRequest{
-		DestinationConf: destinationConf,
-	})
+func (api *API) GetLogpushOwnershipChallenge(ctx context.Context, rc *ResourceContainer, params GetLogpushOwnershipChallengeParams) (*LogpushGetOwnershipChallenge, error) {
+	uri := fmt.Sprintf("/%s/%s/logpush/ownership", rc.Level, rc.Identifier)
+	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
 	if err != nil {
 		return nil, err
 	}
@@ -538,37 +516,12 @@ func (api *API) getLogpushOwnershipChallenge(ctx context.Context, identifierType
 	return &r.Result, nil
 }
 
-// ValidateAccountLogpushOwnershipChallenge returns account-level ownership challenge validation result.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-validate-ownership-challenge
-func (api *API) ValidateAccountLogpushOwnershipChallenge(ctx context.Context, accountID, destinationConf, ownershipChallenge string) (bool, error) {
-	return api.validateLogpushOwnershipChallenge(ctx, AccountRouteRoot, accountID, destinationConf, ownershipChallenge)
-}
-
-// ValidateZoneLogpushOwnershipChallenge returns zone-level ownership challenge validation result.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-validate-ownership-challenge
-func (api *API) ValidateZoneLogpushOwnershipChallenge(ctx context.Context, zoneID, destinationConf, ownershipChallenge string) (bool, error) {
-	return api.validateLogpushOwnershipChallenge(ctx, ZoneRouteRoot, zoneID, destinationConf, ownershipChallenge)
-}
-
 // ValidateLogpushOwnershipChallenge returns zone-level ownership challenge validation result.
 //
 // API reference: https://api.cloudflare.com/#logpush-jobs-validate-ownership-challenge
-//
-// Deprecated: Use `ValidateZoneLogpushOwnershipChallenge` or
-// `ValidateAccountLogpushOwnershipChallenge` depending on the
-// desired resource to target.
-func (api *API) ValidateLogpushOwnershipChallenge(ctx context.Context, zoneID, destinationConf, ownershipChallenge string) (bool, error) {
-	return api.validateLogpushOwnershipChallenge(ctx, ZoneRouteRoot, zoneID, destinationConf, ownershipChallenge)
-}
-
-func (api *API) validateLogpushOwnershipChallenge(ctx context.Context, identifierType RouteRoot, identifier, destinationConf, ownershipChallenge string) (bool, error) {
-	uri := fmt.Sprintf("/%s/%s/logpush/ownership/validate", identifierType, identifier)
-	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, LogpushValidateOwnershipChallengeRequest{
-		DestinationConf:    destinationConf,
-		OwnershipChallenge: ownershipChallenge,
-	})
+func (api *API) ValidateLogpushOwnershipChallenge(ctx context.Context, rc *ResourceContainer, params ValidateLogpushOwnershipChallengeParams) (bool, error) {
+	uri := fmt.Sprintf("/%s/%s/logpush/ownership/validate", rc.Level, rc.Identifier)
+	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
 	if err != nil {
 		return false, err
 	}
@@ -580,33 +533,11 @@ func (api *API) validateLogpushOwnershipChallenge(ctx context.Context, identifie
 	return r.Result.Valid, nil
 }
 
-// CheckAccountLogpushDestinationExists returns account-level destination exists check result.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-check-destination-exists
-func (api *API) CheckAccountLogpushDestinationExists(ctx context.Context, accountID, destinationConf string) (bool, error) {
-	return api.checkLogpushDestinationExists(ctx, AccountRouteRoot, accountID, destinationConf)
-}
-
-// CheckZoneLogpushDestinationExists returns zone-level destination exists check result.
-//
-// API reference: https://api.cloudflare.com/#logpush-jobs-check-destination-exists
-func (api *API) CheckZoneLogpushDestinationExists(ctx context.Context, zoneID, destinationConf string) (bool, error) {
-	return api.checkLogpushDestinationExists(ctx, ZoneRouteRoot, zoneID, destinationConf)
-}
-
 // CheckLogpushDestinationExists returns zone-level destination exists check result.
 //
 // API reference: https://api.cloudflare.com/#logpush-jobs-check-destination-exists
-//
-// Deprecated: Use `CheckZoneLogpushDestinationExists` or
-// `CheckAccountLogpushDestinationExists` depending
-// on the desired resource to target.
-func (api *API) CheckLogpushDestinationExists(ctx context.Context, zoneID, destinationConf string) (bool, error) {
-	return api.checkLogpushDestinationExists(ctx, ZoneRouteRoot, zoneID, destinationConf)
-}
-
-func (api *API) checkLogpushDestinationExists(ctx context.Context, identifierType RouteRoot, identifier, destinationConf string) (bool, error) {
-	uri := fmt.Sprintf("/%s/%s/logpush/validate/destination/exists", identifierType, identifier)
+func (api *API) CheckLogpushDestinationExists(ctx context.Context, rc *ResourceContainer, destinationConf string) (bool, error) {
+	uri := fmt.Sprintf("/%s/%s/logpush/validate/destination/exists", rc.Level, rc.Identifier)
 	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, LogpushDestinationExistsRequest{
 		DestinationConf: destinationConf,
 	})


Test patch:
diff --git a/access_policy_test.go b/access_policy_test.go
index f3f8a66fd..e0c163722 100644
--- a/access_policy_test.go
+++ b/access_policy_test.go
@@ -329,6 +329,36 @@ func TestUpdateAccessPolicy(t *testing.T) {
 	setup()
 	defer teardown()
 
+	accessPolicy := UpdateAccessPolicyParams{
+		ApplicationID: accessApplicationID,
+		PolicyID:      accessPolicyID,
+		Precedence:    1,
+		Decision:      "allow",
+		Name:          "Allow devs",
+		Include: []interface{}{
+			map[string]interface{}{"email": map[string]interface{}{"email": "test@example.com"}},
+		},
+		Exclude: []interface{}{
+			map[string]interface{}{"email": map[string]interface{}{"email": "test@example.com"}},
+		},
+		Require: []interface{}{
+			map[string]interface{}{"email": map[string]interface{}{"email": "test@example.com"}},
+		},
+		IsolationRequired:            &isolationRequired,
+		PurposeJustificationRequired: &purposeJustificationRequired,
+		ApprovalRequired:             &approvalRequired,
+		PurposeJustificationPrompt:   &purposeJustificationPrompt,
+		ApprovalGroups: []AccessApprovalGroup{
+			{
+				EmailListUuid:   "2413b6d7-bbe5-48bd-8fbb-e52069c85561",
+				ApprovalsNeeded: 3,
+			},
+			{
+				EmailAddresses:  []string{"email1@example.com", "email2@example.com"},
+				ApprovalsNeeded: 1,
+			},
+		},
+	}
 	handler := func(w http.ResponseWriter, r *http.Request) {
 		assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method)
 		w.Header().Set("content-type", "application/json")
@@ -384,14 +414,14 @@ func TestUpdateAccessPolicy(t *testing.T) {
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/access/apps/"+accessApplicationID+"/policies/"+accessPolicyID, handler)
-	actual, err := client.UpdateAccessPolicy(context.Background(), testAccountRC, accessApplicationID, expectedAccessPolicy)
+	actual, err := client.UpdateAccessPolicy(context.Background(), testAccountRC, accessPolicy)
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, expectedAccessPolicy, actual)
 	}
 
 	mux.HandleFunc("/zones/"+testZoneID+"/access/apps/"+accessApplicationID+"/policies/"+accessPolicyID, handler)
-	actual, err = client.UpdateAccessPolicy(context.Background(), testZoneRC, accessApplicationID, expectedAccessPolicy)
+	actual, err = client.UpdateAccessPolicy(context.Background(), testZoneRC, accessPolicy)
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, expectedAccessPolicy, actual)
@@ -402,10 +432,10 @@ func TestUpdateAccessPolicyWithMissingID(t *testing.T) {
 	setup()
 	defer teardown()
 
-	_, err := client.UpdateAccessPolicy(context.Background(), testAccountRC, accessApplicationID, AccessPolicy{})
+	_, err := client.UpdateAccessPolicy(context.Background(), testAccountRC, UpdateAccessPolicyParams{ApplicationID: accessApplicationID})
 	assert.EqualError(t, err, "access policy ID cannot be empty")
 
-	_, err = client.UpdateAccessPolicy(context.Background(), testZoneRC, accessApplicationID, AccessPolicy{})
+	_, err = client.UpdateAccessPolicy(context.Background(), testZoneRC, UpdateAccessPolicyParams{ApplicationID: accessApplicationID})
 	assert.EqualError(t, err, "access policy ID cannot be empty")
 }
 
diff --git a/logpush_example_test.go b/logpush_example_test.go
index cfeb0e868..f45b3281a 100644
--- a/logpush_example_test.go
+++ b/logpush_example_test.go
@@ -9,21 +9,7 @@ import (
 	cloudflare "github.com/cloudflare/cloudflare-go"
 )
 
-var exampleNewLogpushJob = cloudflare.LogpushJob{
-	Enabled:         false,
-	Name:            "example.com",
-	LogpullOptions:  "fields=RayID,ClientIP,EdgeStartTimestamp&timestamps=rfc3339",
-	DestinationConf: "s3://mybucket/logs?region=us-west-2",
-}
-
-var exampleUpdatedLogpushJob = cloudflare.LogpushJob{
-	Enabled:         true,
-	Name:            "updated.com",
-	LogpullOptions:  "fields=RayID,ClientIP,EdgeStartTimestamp",
-	DestinationConf: "gs://mybucket/logs",
-}
-
-func ExampleAPI_CreateZoneLogpushJob() {
+func ExampleAPI_CreateLogpushJob() {
 	api, err := cloudflare.New(apiKey, user)
 	if err != nil {
 		log.Fatal(err)
@@ -34,7 +20,12 @@ func ExampleAPI_CreateZoneLogpushJob() {
 		log.Fatal(err)
 	}
 
-	job, err := api.CreateZoneLogpushJob(context.Background(), zoneID, exampleNewLogpushJob)
+	job, err := api.CreateLogpushJob(context.Background(), cloudflare.ZoneIdentifier(zoneID), cloudflare.CreateLogpushJobParams{
+		Enabled:         false,
+		Name:            "example.com",
+		LogpullOptions:  "fields=RayID,ClientIP,EdgeStartTimestamp&timestamps=rfc3339",
+		DestinationConf: "s3://mybucket/logs?region=us-west-2",
+	})
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -42,7 +33,7 @@ func ExampleAPI_CreateZoneLogpushJob() {
 	fmt.Printf("%+v\n", job)
 }
 
-func ExampleAPI_UpdateZoneLogpushJob() {
+func ExampleAPI_UpdateLogpushJob() {
 	api, err := cloudflare.New(apiKey, user)
 	if err != nil {
 		log.Fatal(err)
@@ -53,13 +44,19 @@ func ExampleAPI_UpdateZoneLogpushJob() {
 		log.Fatal(err)
 	}
 
-	err = api.UpdateZoneLogpushJob(context.Background(), zoneID, 1, exampleUpdatedLogpushJob)
+	err = api.UpdateLogpushJob(context.Background(), cloudflare.ZoneIdentifier(zoneID), cloudflare.UpdateLogpushJobParams{
+		ID:              1,
+		Enabled:         true,
+		Name:            "updated.com",
+		LogpullOptions:  "fields=RayID,ClientIP,EdgeStartTimestamp",
+		DestinationConf: "gs://mybucket/logs",
+	})
 	if err != nil {
 		log.Fatal(err)
 	}
 }
 
-func ExampleAPI_ListZoneLogpushJobs() {
+func ExampleAPI_ListLogpushJobs() {
 	api, err := cloudflare.New(apiKey, user)
 	if err != nil {
 		log.Fatal(err)
@@ -70,7 +67,7 @@ func ExampleAPI_ListZoneLogpushJobs() {
 		log.Fatal(err)
 	}
 
-	jobs, err := api.ListZoneLogpushJobs(context.Background(), zoneID)
+	jobs, err := api.ListLogpushJobs(context.Background(), cloudflare.ZoneIdentifier(zoneID), cloudflare.ListLogpushJobsParams{})
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -81,7 +78,7 @@ func ExampleAPI_ListZoneLogpushJobs() {
 	}
 }
 
-func ExampleAPI_GetZoneLogpushJob() {
+func ExampleAPI_GetLogpushJob() {
 	api, err := cloudflare.New(apiKey, user)
 	if err != nil {
 		log.Fatal(err)
@@ -92,7 +89,7 @@ func ExampleAPI_GetZoneLogpushJob() {
 		log.Fatal(err)
 	}
 
-	job, err := api.GetZoneLogpushJob(context.Background(), zoneID, 1)
+	job, err := api.GetLogpushJob(context.Background(), cloudflare.ZoneIdentifier(zoneID), 1)
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -100,7 +97,7 @@ func ExampleAPI_GetZoneLogpushJob() {
 	fmt.Printf("%+v\n", job)
 }
 
-func ExampleAPI_DeleteZoneLogpushJob() {
+func ExampleAPI_DeleteLogpushJob() {
 	api, err := cloudflare.New(apiKey, user)
 	if err != nil {
 		log.Fatal(err)
@@ -111,13 +108,13 @@ func ExampleAPI_DeleteZoneLogpushJob() {
 		log.Fatal(err)
 	}
 
-	err = api.DeleteZoneLogpushJob(context.Background(), zoneID, 1)
+	err = api.DeleteLogpushJob(context.Background(), cloudflare.ZoneIdentifier(zoneID), 1)
 	if err != nil {
 		log.Fatal(err)
 	}
 }
 
-func ExampleAPI_GetZoneLogpushOwnershipChallenge() {
+func ExampleAPI_GetLogpushOwnershipChallenge() {
 	api, err := cloudflare.New(apiKey, user)
 	if err != nil {
 		log.Fatal(err)
@@ -128,7 +125,7 @@ func ExampleAPI_GetZoneLogpushOwnershipChallenge() {
 		log.Fatal(err)
 	}
 
-	ownershipChallenge, err := api.GetZoneLogpushOwnershipChallenge(context.Background(), zoneID, "destination_conf")
+	ownershipChallenge, err := api.GetLogpushOwnershipChallenge(context.Background(), cloudflare.ZoneIdentifier(zoneID), cloudflare.GetLogpushOwnershipChallengeParams{DestinationConf: "destination_conf"})
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -136,7 +133,7 @@ func ExampleAPI_GetZoneLogpushOwnershipChallenge() {
 	fmt.Printf("%+v\n", ownershipChallenge)
 }
 
-func ExampleAPI_ValidateZoneLogpushOwnershipChallenge() {
+func ExampleAPI_ValidateLogpushOwnershipChallenge() {
 	api, err := cloudflare.New(apiKey, user)
 	if err != nil {
 		log.Fatal(err)
@@ -147,7 +144,10 @@ func ExampleAPI_ValidateZoneLogpushOwnershipChallenge() {
 		log.Fatal(err)
 	}
 
-	isValid, err := api.ValidateZoneLogpushOwnershipChallenge(context.Background(), zoneID, "destination_conf", "ownership_challenge")
+	isValid, err := api.ValidateLogpushOwnershipChallenge(context.Background(), cloudflare.ZoneIdentifier(zoneID), cloudflare.ValidateLogpushOwnershipChallengeParams{
+		DestinationConf:    "destination_conf",
+		OwnershipChallenge: "ownership_challenge",
+	})
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -155,7 +155,7 @@ func ExampleAPI_ValidateZoneLogpushOwnershipChallenge() {
 	fmt.Printf("%+v\n", isValid)
 }
 
-func ExampleAPI_CheckZoneLogpushDestinationExists() {
+func ExampleAPI_CheckLogpushDestinationExists() {
 	api, err := cloudflare.New(apiKey, user)
 	if err != nil {
 		log.Fatal(err)
@@ -166,7 +166,7 @@ func ExampleAPI_CheckZoneLogpushDestinationExists() {
 		log.Fatal(err)
 	}
 
-	exists, err := api.CheckZoneLogpushDestinationExists(context.Background(), zoneID, "destination_conf")
+	exists, err := api.CheckLogpushDestinationExists(context.Background(), cloudflare.ZoneIdentifier(zoneID), "destination_conf")
 	if err != nil {
 		log.Fatal(err)
 	}
diff --git a/logpush_test.go b/logpush_test.go
index c68e3b18b..4585b9a40 100644
--- a/logpush_test.go
+++ b/logpush_test.go
@@ -122,7 +122,7 @@ func TestLogpushJobs(t *testing.T) {
 	mux.HandleFunc("/zones/"+testZoneID+"/logpush/jobs", handler)
 	want := []LogpushJob{expectedLogpushJobStruct}
 
-	actual, err := client.ListZoneLogpushJobs(context.Background(), testZoneID)
+	actual, err := client.ListLogpushJobs(context.Background(), ZoneIdentifier(testZoneID), ListLogpushJobsParams{})
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
 	}
@@ -162,7 +162,7 @@ func TestGetLogpushJob(t *testing.T) {
 
 			mux.HandleFunc("/zones/"+testZoneID+"/logpush/jobs/"+strconv.Itoa(jobID), handler)
 
-			actual, err := client.GetZoneLogpushJob(context.Background(), testZoneID, jobID)
+			actual, err := client.GetLogpushJob(context.Background(), ZoneIdentifier(testZoneID), jobID)
 			if assert.NoError(t, err) {
 				assert.Equal(t, tc.want, actual)
 			}
@@ -172,13 +172,13 @@ func TestGetLogpushJob(t *testing.T) {
 
 func TestCreateLogpushJob(t *testing.T) {
 	testCases := map[string]struct {
-		newJob  LogpushJob
+		newJob  CreateLogpushJobParams
 		payload string
 		result  string
 		want    LogpushJob
 	}{
 		"core logpush job": {
-			newJob: LogpushJob{
+			newJob: CreateLogpushJobParams{
 				Dataset:          "http_requests",
 				Enabled:          false,
 				Name:             "example.com",
@@ -198,7 +198,7 @@ func TestCreateLogpushJob(t *testing.T) {
 			want:   expectedLogpushJobStruct,
 		},
 		"edge logpush job": {
-			newJob: LogpushJob{
+			newJob: CreateLogpushJobParams{
 				Dataset:         "http_requests",
 				Enabled:         true,
 				Name:            "example.com",
@@ -218,7 +218,7 @@ func TestCreateLogpushJob(t *testing.T) {
 			want:   expectedEdgeLogpushJobStruct,
 		},
 		"filtered edge logpush job": {
-			newJob: LogpushJob{
+			newJob: CreateLogpushJobParams{
 				Dataset:         "http_requests",
 				Enabled:         true,
 				Name:            "example.com",
@@ -269,7 +269,7 @@ func TestCreateLogpushJob(t *testing.T) {
 
 			mux.HandleFunc("/zones/"+testZoneID+"/logpush/jobs", handler)
 
-			actual, err := client.CreateZoneLogpushJob(context.Background(), testZoneID, tc.newJob)
+			actual, err := client.CreateLogpushJob(context.Background(), ZoneIdentifier(testZoneID), tc.newJob)
 			if assert.NoError(t, err) {
 				assert.Equal(t, tc.want, *actual)
 			}
@@ -280,7 +280,8 @@ func TestCreateLogpushJob(t *testing.T) {
 func TestUpdateLogpushJob(t *testing.T) {
 	setup()
 	defer teardown()
-	updatedJob := LogpushJob{
+	updatedJob := UpdateLogpushJobParams{
+		ID:              jobID,
 		Enabled:         true,
 		Name:            "updated.com",
 		LogpullOptions:  "fields=RayID,ClientIP,EdgeStartTimestamp",
@@ -301,7 +302,7 @@ func TestUpdateLogpushJob(t *testing.T) {
 
 	mux.HandleFunc("/zones/"+testZoneID+"/logpush/jobs/"+strconv.Itoa(jobID), handler)
 
-	err := client.UpdateLogpushJob(context.Background(), testZoneID, jobID, updatedJob)
+	err := client.UpdateLogpushJob(context.Background(), ZoneIdentifier(testZoneID), updatedJob)
 	assert.NoError(t, err)
 }
 
@@ -323,7 +324,7 @@ func TestDeleteLogpushJob(t *testing.T) {
 
 	mux.HandleFunc("/zones/"+testZoneID+"/logpush/jobs/"+strconv.Itoa(jobID), handler)
 
-	err := client.DeleteZoneLogpushJob(context.Background(), testZoneID, jobID)
+	err := client.DeleteLogpushJob(context.Background(), ZoneIdentifier(testZoneID), jobID)
 	assert.NoError(t, err)
 }
 
@@ -347,7 +348,7 @@ func TestGetLogpushOwnershipChallenge(t *testing.T) {
 
 	want := &expectedLogpushGetOwnershipChallengeStruct
 
-	actual, err := client.GetZoneLogpushOwnershipChallenge(context.Background(), testZoneID, "destination_conf")
+	actual, err := client.GetLogpushOwnershipChallenge(context.Background(), ZoneIdentifier(testZoneID), GetLogpushOwnershipChallengeParams{DestinationConf: "destination_conf"})
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
 	}
@@ -370,7 +371,7 @@ func TestGetLogpushOwnershipChallengeWithInvalidResponse(t *testing.T) {
 	}
 
 	mux.HandleFunc("/zones/"+testZoneID+"/logpush/ownership", handler)
-	_, err := client.GetZoneLogpushOwnershipChallenge(context.Background(), testZoneID, "destination_conf")
+	_, err := client.GetLogpushOwnershipChallenge(context.Background(), ZoneIdentifier(testZoneID), GetLogpushOwnershipChallengeParams{DestinationConf: "destination_conf"})
 
 	assert.Error(t, err)
 }
@@ -408,7 +409,10 @@ func TestValidateLogpushOwnershipChallenge(t *testing.T) {
 
 			mux.HandleFunc("/zones/"+testZoneID+"/logpush/ownership/validate", handler)
 
-			actual, err := client.ValidateZoneLogpushOwnershipChallenge(context.Background(), testZoneID, "destination_conf", "ownership_challenge")
+			actual, err := client.ValidateLogpushOwnershipChallenge(context.Background(), ZoneIdentifier(testZoneID), ValidateLogpushOwnershipChallengeParams{
+				DestinationConf:    "destination_conf",
+				OwnershipChallenge: "ownership_challenge",
+			})
 			if assert.NoError(t, err) {
 				assert.Equal(t, tc.isValid, actual)
 			}
@@ -449,7 +453,7 @@ func TestCheckLogpushDestinationExists(t *testing.T) {
 
 			mux.HandleFunc("/zones/"+testZoneID+"/logpush/validate/destination/exists", handler)
 
-			actual, err := client.CheckZoneLogpushDestinationExists(context.Background(), testZoneID, "destination_conf")
+			actual, err := client.CheckLogpushDestinationExists(context.Background(), ZoneIdentifier(testZoneID), "destination_conf")
 			if assert.NoError(t, err) {
 				assert.Equal(t, tc.exists, actual)
 			}