Repository: cloudflare/cloudflare-go
Pull request #985 (2022-07-11 04:18:54)

experimental: swap method signature conventions
The original purpose of exposing everything using structs was to be (overly)
explicit about what level of resource we were operating on and allow consistent
customisation between resources. To reduce the verbosity of some of these
structs, we've opted to introduce a `ResourceContainer` concept which accepts
an ID and sets up the method with the same level of information we were
previously using in a more friendly way. Updated recently touched resources to
match this potentially changing the external interface slightly.



Patch:
diff --git a/docs/experimental.md b/docs/experimental.md
index 92073cbce..e7b22ed4d 100644
--- a/docs/experimental.md
+++ b/docs/experimental.md
@@ -5,19 +5,6 @@ and consistent experience.
 
 ## Improvements
 
-### Consistent CRUD method signatures
-
-Majority of entities follow a standard method signature (where `$entity` is the
-resource such as `Zone`, `DNSRecord`, ...).
-
-| Signature                                             | Purpose                                                                                                                              | Return value                                                                                                                   |
-| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
-| `Get(ctx, *Resource) ($entity, error)`                | Fetches a single entity by a `Resource`. Should use `ZoneIdentifier` and `AccountIdentifier` respectively (not \*Resource directly). | Returns the entity and `error` based on the listing parameters.                                                                |
-| `List(ctx, ...params) ([]$entity, ResultInfo, error)` | Fetches all entities.                                                                                                                | Returns the list of matching entities, the result information (pagination, fail/success and additional metadata), and `error`. |
-| `New(ctx, ...params) ($entity, error)`                | Creates a new entity with the provided parameters.                                                                                   | Returns the newly created entity and `error`.                                                                                  |
-| `Update(ctx, ...params) ($entity, error)`             | Updates an existing entity.                                                                                                          | Returns the updated entity and `error`.                                                                                        |
-| `Delete(ctx, *Resource) (error)`                      | Deletes a single entity by a `Resource`. Should use `ZoneIdentifier` and `AccountIdentifier` respectively (not \*Resource directly). | Returns `error`.                                                                                                               |
-
 ### Why no iterator for `List` operations?
 
 Initially, there was proposal to either: 1) automatically paginate all results
@@ -48,12 +35,35 @@ client.Access.ServiceTokens(...)
 This avoids polluting the global namespace and having more specific methods
 for services.
 
-## Examples
+### Consistent CRUD method signatures
 
-A zone is used below for the examples however, all entites will implement the
-same methods and interfaces.
+Majority of methods on an entity will follow a standard method signature.
+
+| Signature                                                                 | Purpose                                            | Return value                                                                                                                   |
+| ------------------------------------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
+| `Get(ctx, *ResourceContainer, $entityID) ($entity, error)`                | Fetches a single entity by a `$entityID`.          | Returns the entity and `error` based on the listing parameters.                                                                |
+| `List(ctx, *ResourceContainer, ...params) ([]$entity, ResultInfo, error)` | Fetches all entities.                              | Returns the list of matching entities, the result information (pagination, fail/success and additional metadata), and `error`. |
+| `New(ctx, *ResourceContainer, ...params) ($entity, error)`                | Creates a new entity with the provided parameters. | Returns the newly created entity and `error`.                                                                                  |
+| `Update(ctx, *ResourceContainer, ...params) ($entity, error)`             | Updates an existing entity.                        | Returns the updated entity and `error`.                                                                                        |
+| `Delete(ctx, *ResourceContainer, $entityID) (error)`                      | Deletes a single entity by a `$entityID`.          | Returns `error`.                                                                                                               |
+
+- `*ResourceContainer` determines the "level" of the resource and where it will
+  operate at. Operated using `UserIdentifier`, `ZoneIdentifier`, and
+  `AccountIdentifier` respectively
+- `$entityID` is the resource identifier
+- `...params` is a complex structure that allows filtering/finding resources
+  matching the struct fields
+- `$entity` the resource being operated on
+
+Exceptions to this convention will be:
+
+- Methods outside of CRUD operations
+- Top level level concepts such as `Accounts` and `Zones`
+
+#### Examples
 
-### Initialising a new client with options like your own `http.Client`
+`DNSRecord` is used below for the examples however, all entites will implement the
+same methods and interfaces.
 
 ```go
 params := cloudflare.ClientParams{
@@ -65,76 +75,46 @@ params := cloudflare.ClientParams{
 c, err := cloudflare.NewExperimental(params)
 ```
 
-### Create a new zone
+**Create a new DNS record**
 
 ```go
-params := cloudflare.ClientParams{
-  Key: "3bc3be114fb6323adc5b0ad7422d193a",
-  Email: "someone@example.com",
+dParams := &cloudflare.DNSRecordParams{
+  Name: "@",
+  Content: "foo.example.com",
+  TTL: 300,
 }
-c, err := cloudflare.NewExperimental(params)
-
-zParams := &cloudflare.ZoneParams{
-  Name: "example.com",
-  AccountID: "d8e8fca2dc0f896fd7cb4cb0031ba249"
-}
-z, _ := c.Zones.New(ctx, zParams)
+r, _ := c.DNSRecord.New(context.TODO(), cloudflare.ZoneIdentifier("b026324c6904b2a9cb4b88d6d61c81d1"), dParams)
 ```
 
-### Fetching a known zone ID
+**Fetching a known DNS record by ID**
 
 ```go
-params := cloudflare.ClientParams{
-  Key: "3bc3be114fb6323adc5b0ad7422d193a",
-  Email: "someone@example.com",
-}
-c, err := cloudflare.NewExperimental(params)
-
-z, _ := c.Zones.Get(ctx, cloudflare.ZoneIdentifier("3e7705498e8be60520841409ebc69bc1"))
+r, _ := c.DNSRecord.Get(context.TODO(), cloudflare.ZoneIdentifier("b026324c6904b2a9cb4b88d6d61c81d1"), "3e7705498e8be60520841409ebc69bc1")
 ```
 
-### Fetching all zones matching a single account ID
+**Listing all records matching a single account ID (filter option)**
 
 ```go
-params := cloudflare.ClientParams{
-  Key: "3bc3be114fb6323adc5b0ad7422d193a",
-  Email: "someone@example.com",
-}
-c, err := cloudflare.NewExperimental(params)
-
-zParams := &cloudflare.ZoneParams{
+dParams := &cloudflare.DNSRecordListParams{
   AccountID: "d8e8fca2dc0f896fd7cb4cb0031ba249"
 }
-z, _, _ := c.Zones.List(ctx, zParams)
+r, _, _ := c.DNSRecord.List(context.TODO(), dParams)
 ```
 
-### Update a zone
+**Update an existing DNS record**
 
 ```go
-params := cloudflare.ClientParams{
-  Key: "3bc3be114fb6323adc5b0ad7422d193a",
-  Email: "someone@example.com",
+dParams := &cloudflare.DNSRecordParams{
+  ID: "b5163cf270a3fbac34827c4a2713eef4",
+  Name: "@",
+  Content: "bar.example.com",
+  TTL: 300,
 }
-c, err := cloudflare.NewExperimental(params)
-
-zParams := &cloudflare.ZoneParams{
-  ID: "3e7705498e8be60520841409ebc69bc1",
-  Nameservers: cloudflare.StringSlice([]string{
-    "ns1.example.com",
-    "ns2.example.com"
-  })
-}
-z, _ := c.Zones.Update(ctx, zParams)
+r, _ := c.DNSRecord.Update(context.TODO(), cloudflare.ZoneIdentifier("b026324c6904b2a9cb4b88d6d61c81d1"), dParams)
 ```
 
-### Delete a zone
+**Delete a DNS Record**
 
 ```go
-params := cloudflare.ClientParams{
-  Key: "3bc3be114fb6323adc5b0ad7422d193a",
-  Email: "someone@example.com",
-}
-c, err := cloudflare.NewExperimental(params)
-
-z, _ := c.Zones.Delete(ctx, cloudflare.ZoneIdentifier("b5163cf270a3fbac34827c4a2713eef4"))
+r, _ := c.DNSRecord.Delete(context.TODO(), cloudflare.ZoneIdentifier("b026324c6904b2a9cb4b88d6d61c81d1"), "b5163cf270a3fbac34827c4a2713eef4")
 ```
diff --git a/list.go b/list.go
index 4b12486d3..323e6e8b9 100644
--- a/list.go
+++ b/list.go
@@ -143,81 +143,69 @@ type ListItemsGetResponse struct {
 }
 
 type ListListsParams struct {
-	AccountID string
 }
 
 type ListCreateParams struct {
-	AccountID   string
 	Name        string
 	Description string
 	Kind        string
 }
 
 type ListGetParams struct {
-	AccountID string
-	ID        string
+	ID string
 }
 
 type ListUpdateParams struct {
-	AccountID   string
 	ID          string
 	Description string
 }
 
 type ListDeleteParams struct {
-	AccountID string
-	ID        string
+	ID string
 }
 
 type ListListItemsParams struct {
-	AccountID string
-	ID        string
+	ID string
 }
 
 type ListCreateItemsParams struct {
-	AccountID string
-	ID        string
-	Items     []ListItemCreateRequest
+	ID    string
+	Items []ListItemCreateRequest
 }
 
 type ListCreateItemParams struct {
-	AccountID string
-	ID        string
-	Item      ListItemCreateRequest
+	ID   string
+	Item ListItemCreateRequest
 }
 
 type ListReplaceItemsParams struct {
-	AccountID string
-	ID        string
-	Items     []ListItemCreateRequest
+	ID    string
+	Items []ListItemCreateRequest
 }
 
 type ListDeleteItemsParams struct {
-	AccountID string
-	ID        string
-	Items     ListItemDeleteRequest
+	ID    string
+	Items ListItemDeleteRequest
 }
 
 type ListGetItemParams struct {
-	AccountID string
-	ListID    string
-	ID        string
+	ListID string
+	ID     string
 }
 
 type ListGetBulkOperationParams struct {
-	AccountID string
-	ID        string
+	ID string
 }
 
 // ListLists lists all Lists.
 //
 // API reference: https://api.cloudflare.com/#rules-lists-list-lists
-func (api *API) ListLists(ctx context.Context, params ListListsParams) ([]List, error) {
-	if params.AccountID == "" {
+func (api *API) ListLists(ctx context.Context, rc *ResourceContainer, params ListListsParams) ([]List, error) {
+	if rc.Identifier == "" {
 		return []List{}, ErrMissingAccountID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/rules/lists", params.AccountID)
+	uri := fmt.Sprintf("/accounts/%s/rules/lists", rc.Identifier)
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
 		return []List{}, err
@@ -234,14 +222,13 @@ func (api *API) ListLists(ctx context.Context, params ListListsParams) ([]List,
 // CreateList creates a new List.
 //
 // API reference: https://api.cloudflare.com/#rules-lists-create-list
-func (api *API) CreateList(ctx context.Context, params ListCreateParams) (List, error) {
-	if params.AccountID == "" {
+func (api *API) CreateList(ctx context.Context, rc *ResourceContainer, params ListCreateParams) (List, error) {
+	if rc.Identifier == "" {
 		return List{}, ErrMissingAccountID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/rules/lists", params.AccountID)
-	res, err := api.makeRequestContext(ctx, http.MethodPost, uri,
-		ListCreateRequest{Name: params.Name, Description: params.Description, Kind: params.Kind})
+	uri := fmt.Sprintf("/accounts/%s/rules/lists", rc.Identifier)
+	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, ListCreateRequest{Name: params.Name, Description: params.Description, Kind: params.Kind})
 	if err != nil {
 		return List{}, err
 	}
@@ -257,16 +244,16 @@ func (api *API) CreateList(ctx context.Context, params ListCreateParams) (List,
 // GetList returns a single List.
 //
 // API reference: https://api.cloudflare.com/#rules-lists-get-list
-func (api *API) GetList(ctx context.Context, params ListGetParams) (List, error) {
-	if params.AccountID == "" {
+func (api *API) GetList(ctx context.Context, rc *ResourceContainer, listID string) (List, error) {
+	if rc.Identifier == "" {
 		return List{}, ErrMissingAccountID
 	}
 
-	if params.ID == "" {
+	if listID == "" {
 		return List{}, ErrMissingListID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s", params.AccountID, params.ID)
+	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s", rc.Identifier, listID)
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
 		return List{}, err
@@ -283,8 +270,8 @@ func (api *API) GetList(ctx context.Context, params ListGetParams) (List, error)
 // UpdateList updates the description of an existing List.
 //
 // API reference: https://api.cloudflare.com/#rules-lists-update-list
-func (api *API) UpdateList(ctx context.Context, params ListUpdateParams) (List, error) {
-	if params.AccountID == "" {
+func (api *API) UpdateList(ctx context.Context, rc *ResourceContainer, params ListUpdateParams) (List, error) {
+	if rc.Identifier == "" {
 		return List{}, ErrMissingAccountID
 	}
 
@@ -292,7 +279,7 @@ func (api *API) UpdateList(ctx context.Context, params ListUpdateParams) (List,
 		return List{}, ErrMissingListID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s", params.AccountID, params.ID)
+	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s", rc.Identifier, params.ID)
 	res, err := api.makeRequestContext(ctx, http.MethodPut, uri, ListUpdateRequest{Description: params.Description})
 	if err != nil {
 		return List{}, err
@@ -309,16 +296,16 @@ func (api *API) UpdateList(ctx context.Context, params ListUpdateParams) (List,
 // DeleteList deletes a List.
 //
 // API reference: https://api.cloudflare.com/#rules-lists-delete-list
-func (api *API) DeleteList(ctx context.Context, params ListDeleteParams) (ListDeleteResponse, error) {
-	if params.AccountID == "" {
+func (api *API) DeleteList(ctx context.Context, rc *ResourceContainer, listID string) (ListDeleteResponse, error) {
+	if rc.Identifier == "" {
 		return ListDeleteResponse{}, ErrMissingAccountID
 	}
 
-	if params.ID == "" {
+	if listID == "" {
 		return ListDeleteResponse{}, ErrMissingListID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s", params.AccountID, params.ID)
+	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s", rc.Identifier, listID)
 	res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
 	if err != nil {
 		return ListDeleteResponse{}, err
@@ -335,7 +322,7 @@ func (api *API) DeleteList(ctx context.Context, params ListDeleteParams) (ListDe
 // ListListItems returns a list with all items in a List.
 //
 // API reference: https://api.cloudflare.com/#rules-lists-list-list-items
-func (api *API) ListListItems(ctx context.Context, params ListListItemsParams) ([]ListItem, error) {
+func (api *API) ListListItems(ctx context.Context, rc *ResourceContainer, params ListListItemsParams) ([]ListItem, error) {
 	var list []ListItem
 	var cursor string
 	var cursorQuery string
@@ -344,7 +331,7 @@ func (api *API) ListListItems(ctx context.Context, params ListListItemsParams) (
 		if len(cursor) > 0 {
 			cursorQuery = fmt.Sprintf("?cursor=%s", cursor)
 		}
-		uri := fmt.Sprintf("/accounts/%s/rules/lists/%s/items%s", params.AccountID, params.ID, cursorQuery)
+		uri := fmt.Sprintf("/accounts/%s/rules/lists/%s/items%s", rc.Identifier, params.ID, cursorQuery)
 		res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 		if err != nil {
 			return []ListItem{}, err
@@ -368,8 +355,8 @@ func (api *API) ListListItems(ctx context.Context, params ListListItemsParams) (
 // using the operation_id returned by this function.
 //
 // API reference: https://api.cloudflare.com/#rules-lists-create-list-items
-func (api *API) CreateListItemAsync(ctx context.Context, params ListCreateItemParams) (ListItemCreateResponse, error) {
-	if params.AccountID == "" {
+func (api *API) CreateListItemAsync(ctx context.Context, rc *ResourceContainer, params ListCreateItemParams) (ListItemCreateResponse, error) {
+	if rc.Identifier == "" {
 		return ListItemCreateResponse{}, ErrMissingAccountID
 	}
 
@@ -377,7 +364,7 @@ func (api *API) CreateListItemAsync(ctx context.Context, params ListCreateItemPa
 		return ListItemCreateResponse{}, ErrMissingListID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s/items", params.AccountID, params.ID)
+	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s/items", rc.Identifier, params.ID)
 	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, []ListItemCreateRequest{params.Item})
 	if err != nil {
 		return ListItemCreateResponse{}, err
@@ -392,19 +379,19 @@ func (api *API) CreateListItemAsync(ctx context.Context, params ListCreateItemPa
 }
 
 // CreateListItem creates a new List Item synchronously and returns the current set of List Items.
-func (api *API) CreateListItem(ctx context.Context, params ListCreateItemParams) ([]ListItem, error) {
-	result, err := api.CreateListItemAsync(ctx, params)
+func (api *API) CreateListItem(ctx context.Context, rc *ResourceContainer, params ListCreateItemParams) ([]ListItem, error) {
+	result, err := api.CreateListItemAsync(ctx, rc, params)
 
 	if err != nil {
 		return []ListItem{}, err
 	}
 
-	err = api.pollListBulkOperation(ctx, params.AccountID, result.Result.OperationID)
+	err = api.pollListBulkOperation(ctx, rc, result.Result.OperationID)
 	if err != nil {
 		return []ListItem{}, err
 	}
 
-	return api.ListListItems(ctx, ListListItemsParams{AccountID: params.AccountID, ID: params.ID})
+	return api.ListListItems(ctx, rc, ListListItemsParams{ID: params.ID})
 }
 
 // CreateListItemsAsync bulk creates multiple List Items asynchronously. Users
@@ -412,8 +399,8 @@ func (api *API) CreateListItem(ctx context.Context, params ListCreateItemParams)
 // function.
 //
 // API reference: https://api.cloudflare.com/#rules-lists-create-list-items
-func (api *API) CreateListItemsAsync(ctx context.Context, params ListCreateItemsParams) (ListItemCreateResponse, error) {
-	if params.AccountID == "" {
+func (api *API) CreateListItemsAsync(ctx context.Context, rc *ResourceContainer, params ListCreateItemsParams) (ListItemCreateResponse, error) {
+	if rc.Identifier == "" {
 		return ListItemCreateResponse{}, ErrMissingAccountID
 	}
 
@@ -421,7 +408,7 @@ func (api *API) CreateListItemsAsync(ctx context.Context, params ListCreateItems
 		return ListItemCreateResponse{}, ErrMissingListID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s/items", params.AccountID, params.ID)
+	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s/items", rc.Identifier, params.ID)
 	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params.Items)
 	if err != nil {
 		return ListItemCreateResponse{}, err
@@ -437,18 +424,18 @@ func (api *API) CreateListItemsAsync(ctx context.Context, params ListCreateItems
 
 // CreateListItems bulk creates multiple List Items synchronously and returns
 // the current set of List Items.
-func (api *API) CreateListItems(ctx context.Context, params ListCreateItemsParams) ([]ListItem, error) {
-	result, err := api.CreateListItemsAsync(ctx, params)
+func (api *API) CreateListItems(ctx context.Context, rc *ResourceContainer, params ListCreateItemsParams) ([]ListItem, error) {
+	result, err := api.CreateListItemsAsync(ctx, rc, params)
 	if err != nil {
 		return []ListItem{}, err
 	}
 
-	err = api.pollListBulkOperation(ctx, params.AccountID, result.Result.OperationID)
+	err = api.pollListBulkOperation(ctx, rc, result.Result.OperationID)
 	if err != nil {
 		return []ListItem{}, err
 	}
 
-	return api.ListListItems(ctx, ListListItemsParams{AccountID: params.AccountID, ID: params.ID})
+	return api.ListListItems(ctx, rc, ListListItemsParams{ID: params.ID})
 }
 
 // ReplaceListItemsAsync replaces all List Items asynchronously. Users have to
@@ -456,8 +443,8 @@ func (api *API) CreateListItems(ctx context.Context, params ListCreateItemsParam
 // function.
 //
 // API reference: https://api.cloudflare.com/#rules-lists-replace-list-items
-func (api *API) ReplaceListItemsAsync(ctx context.Context, params ListReplaceItemsParams) (ListItemCreateResponse, error) {
-	if params.AccountID == "" {
+func (api *API) ReplaceListItemsAsync(ctx context.Context, rc *ResourceContainer, params ListReplaceItemsParams) (ListItemCreateResponse, error) {
+	if rc.Identifier == "" {
 		return ListItemCreateResponse{}, ErrMissingAccountID
 	}
 
@@ -465,7 +452,7 @@ func (api *API) ReplaceListItemsAsync(ctx context.Context, params ListReplaceIte
 		return ListItemCreateResponse{}, ErrMissingListID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s/items", params.AccountID, params.ID)
+	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s/items", rc.Identifier, params.ID)
 	res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params.Items)
 	if err != nil {
 		return ListItemCreateResponse{}, err
@@ -481,19 +468,19 @@ func (api *API) ReplaceListItemsAsync(ctx context.Context, params ListReplaceIte
 
 // ReplaceListItems replaces all List Items synchronously and returns the
 // current set of List Items.
-func (api *API) ReplaceListItems(ctx context.Context, params ListReplaceItemsParams) (
+func (api *API) ReplaceListItems(ctx context.Context, rc *ResourceContainer, params ListReplaceItemsParams) (
 	[]ListItem, error) {
-	result, err := api.ReplaceListItemsAsync(ctx, params)
+	result, err := api.ReplaceListItemsAsync(ctx, rc, params)
 	if err != nil {
 		return []ListItem{}, err
 	}
 
-	err = api.pollListBulkOperation(ctx, params.AccountID, result.Result.OperationID)
+	err = api.pollListBulkOperation(ctx, rc, result.Result.OperationID)
 	if err != nil {
 		return []ListItem{}, err
 	}
 
-	return api.ListListItems(ctx, ListListItemsParams{AccountID: params.AccountID, ID: params.ID})
+	return api.ListListItems(ctx, rc, ListListItemsParams{ID: params.ID})
 }
 
 // DeleteListItemsAsync removes specific Items of a List by their ID
@@ -501,8 +488,8 @@ func (api *API) ReplaceListItems(ctx context.Context, params ListReplaceItemsPar
 // operation_id returned by this function.
 //
 // API reference: https://api.cloudflare.com/#rules-lists-delete-list-items
-func (api *API) DeleteListItemsAsync(ctx context.Context, params ListDeleteItemsParams) (ListItemDeleteResponse, error) {
-	if params.AccountID == "" {
+func (api *API) DeleteListItemsAsync(ctx context.Context, rc *ResourceContainer, params ListDeleteItemsParams) (ListItemDeleteResponse, error) {
+	if rc.Identifier == "" {
 		return ListItemDeleteResponse{}, ErrMissingAccountID
 	}
 
@@ -510,7 +497,7 @@ func (api *API) DeleteListItemsAsync(ctx context.Context, params ListDeleteItems
 		return ListItemDeleteResponse{}, ErrMissingListID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s/items", params.AccountID, params.ID)
+	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s/items", rc.Identifier, params.ID)
 	res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, params.Items)
 	if err != nil {
 		return ListItemDeleteResponse{}, err
@@ -526,37 +513,37 @@ func (api *API) DeleteListItemsAsync(ctx context.Context, params ListDeleteItems
 
 // DeleteListItems removes specific Items of a List by their ID synchronously
 // and returns the current set of List Items.
-func (api *API) DeleteListItems(ctx context.Context, params ListDeleteItemsParams) ([]ListItem, error) {
-	result, err := api.DeleteListItemsAsync(ctx, params)
+func (api *API) DeleteListItems(ctx context.Context, rc *ResourceContainer, params ListDeleteItemsParams) ([]ListItem, error) {
+	result, err := api.DeleteListItemsAsync(ctx, rc, params)
 	if err != nil {
 		return []ListItem{}, err
 	}
 
-	err = api.pollListBulkOperation(ctx, params.AccountID, result.Result.OperationID)
+	err = api.pollListBulkOperation(ctx, rc, result.Result.OperationID)
 	if err != nil {
 		return []ListItem{}, err
 	}
 
-	return api.ListListItems(ctx, ListListItemsParams{AccountID: params.AccountID, ID: params.ID})
+	return api.ListListItems(ctx, AccountIdentifier(rc.Identifier), ListListItemsParams{ID: params.ID})
 }
 
 // GetListItem returns a single List Item.
 //
 // API reference: https://api.cloudflare.com/#rules-lists-get-list-item
-func (api *API) GetListItem(ctx context.Context, params ListGetItemParams) (ListItem, error) {
-	if params.AccountID == "" {
+func (api *API) GetListItem(ctx context.Context, rc *ResourceContainer, listID, itemID string) (ListItem, error) {
+	if rc.Identifier == "" {
 		return ListItem{}, ErrMissingAccountID
 	}
 
-	if params.ListID == "" {
+	if listID == "" {
 		return ListItem{}, ErrMissingListID
 	}
 
-	if params.ID == "" {
+	if itemID == "" {
 		return ListItem{}, ErrMissingResourceIdentifier
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s/items/%s", params.AccountID, params.ListID, params.ID)
+	uri := fmt.Sprintf("/accounts/%s/rules/lists/%s/items/%s", rc.Identifier, listID, itemID)
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
 		return ListItem{}, err
@@ -573,16 +560,16 @@ func (api *API) GetListItem(ctx context.Context, params ListGetItemParams) (List
 // GetListBulkOperation returns the status of a bulk operation.
 //
 // API reference: https://api.cloudflare.com/#rules-lists-get-bulk-operation
-func (api *API) GetListBulkOperation(ctx context.Context, params ListGetBulkOperationParams) (ListBulkOperation, error) {
-	if params.AccountID == "" {
+func (api *API) GetListBulkOperation(ctx context.Context, rc *ResourceContainer, ID string) (ListBulkOperation, error) {
+	if rc.Identifier == "" {
 		return ListBulkOperation{}, ErrMissingAccountID
 	}
 
-	if params.ID == "" {
+	if ID == "" {
 		return ListBulkOperation{}, ErrMissingResourceIdentifier
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/rules/lists/bulk_operations/%s", params.AccountID, params.ID)
+	uri := fmt.Sprintf("/accounts/%s/rules/lists/bulk_operations/%s", rc.Identifier, ID)
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
 		return ListBulkOperation{}, err
@@ -599,7 +586,7 @@ func (api *API) GetListBulkOperation(ctx context.Context, params ListGetBulkOper
 // pollListBulkOperation implements synchronous behaviour for some asynchronous
 // endpoints. bulk-operation status can be either pending, running, failed or
 // completed.
-func (api *API) pollListBulkOperation(ctx context.Context, accountID, ID string) error {
+func (api *API) pollListBulkOperation(ctx context.Context, rc *ResourceContainer, ID string) error {
 	for i := uint8(0); i < 16; i++ {
 		sleepDuration := 1 << (i / 2) * time.Second
 		select {
@@ -608,7 +595,7 @@ func (api *API) pollListBulkOperation(ctx context.Context, accountID, ID string)
 			return fmt.Errorf("operation aborted during backoff: %w", ctx.Err())
 		}
 
-		bulkResult, err := api.GetListBulkOperation(ctx, ListGetBulkOperationParams{AccountID: accountID, ID: ID})
+		bulkResult, err := api.GetListBulkOperation(ctx, rc, ID)
 		if err != nil {
 			return err
 		}
diff --git a/managed_headers.go b/managed_headers.go
index d696ea3b0..a1d6f3a67 100644
--- a/managed_headers.go
+++ b/managed_headers.go
@@ -13,7 +13,6 @@ type ListManagedHeadersResponse struct {
 }
 
 type UpdateManagedHeadersParams struct {
-	ZoneID string
 	ManagedHeaders
 }
 
@@ -29,16 +28,14 @@ type ManagedHeader struct {
 	ConflictsWith []string `json:"conflicts_with,omitempty"`
 }
 
-type ListManagedHeadersParams struct {
-	ZoneID string
-}
+type ListManagedHeadersParams struct{}
 
-func (api *API) ListZoneManagedHeaders(ctx context.Context, params ListManagedHeadersParams) (ManagedHeaders, error) {
-	if params.ZoneID == "" {
+func (api *API) ListZoneManagedHeaders(ctx context.Context, rc *ResourceContainer, params ListManagedHeadersParams) (ManagedHeaders, error) {
+	if rc.Identifier == "" {
 		return ManagedHeaders{}, ErrMissingZoneID
 	}
 
-	uri := fmt.Sprintf("/zones/%s/managed_headers", params.ZoneID)
+	uri := fmt.Sprintf("/zones/%s/managed_headers", rc.Identifier)
 
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
@@ -53,12 +50,12 @@ func (api *API) ListZoneManagedHeaders(ctx context.Context, params ListManagedHe
 	return result.Result, nil
 }
 
-func (api *API) UpdateZoneManagedHeaders(ctx context.Context, params UpdateManagedHeadersParams) (ManagedHeaders, error) {
-	if params.ZoneID == "" {
+func (api *API) UpdateZoneManagedHeaders(ctx context.Context, rc *ResourceContainer, params UpdateManagedHeadersParams) (ManagedHeaders, error) {
+	if rc.Identifier == "" {
 		return ManagedHeaders{}, ErrMissingZoneID
 	}
 
-	uri := fmt.Sprintf("/zones/%s/managed_headers", params.ZoneID)
+	uri := fmt.Sprintf("/zones/%s/managed_headers", rc.Identifier)
 
 	payload, err := json.Marshal(params.ManagedHeaders)
 	if err != nil {
diff --git a/pages_deployment.go b/pages_deployment.go
index 1d5838b67..c4f41e644 100644
--- a/pages_deployment.go
+++ b/pages_deployment.go
@@ -76,20 +76,17 @@ type pagesDeploymentLogsResponse struct {
 }
 
 type ListPagesDeploymentsParams struct {
-	AccountID   string
 	ProjectName string
 
 	PaginationOptions
 }
 
 type GetPagesDeploymentInfoParams struct {
-	AccountID    string
 	ProjectName  string
 	DeploymentID string
 }
 
 type GetPagesDeploymentStageLogsParams struct {
-	AccountID    string
 	ProjectName  string
 	DeploymentID string
 	StageName    string
@@ -98,7 +95,6 @@ type GetPagesDeploymentStageLogsParams struct {
 }
 
 type GetPagesDeploymentLogsParams struct {
-	AccountID    string
 	ProjectName  string
 	DeploymentID string
 
@@ -106,24 +102,20 @@ type GetPagesDeploymentLogsParams struct {
 }
 
 type DeletePagesDeploymentParams struct {
-	AccountID    string
 	ProjectName  string
 	DeploymentID string
 }
 
 type CreatePagesDeploymentParams struct {
-	AccountID   string
 	ProjectName string
 }
 
 type RetryPagesDeploymentParams struct {
-	AccountID    string
 	ProjectName  string
 	DeploymentID string
 }
 
 type RollbackPagesDeploymentParams struct {
-	AccountID    string
 	ProjectName  string
 	DeploymentID string
 }
@@ -137,8 +129,8 @@ var (
 // ListPagesDeployments returns all deployments for a Pages project.
 //
 // API reference: https://api.cloudflare.com/#pages-deployment-get-deployments
-func (api *API) ListPagesDeployments(ctx context.Context, params ListPagesDeploymentsParams) ([]PagesProjectDeployment, ResultInfo, error) {
-	if params.AccountID == "" {
+func (api *API) ListPagesDeployments(ctx context.Context, rc *ResourceContainer, params ListPagesDeploymentsParams) ([]PagesProjectDeployment, ResultInfo, error) {
+	if rc.Identifier == "" {
 		return []PagesProjectDeployment{}, ResultInfo{}, ErrMissingAccountID
 	}
 
@@ -146,7 +138,7 @@ func (api *API) ListPagesDeployments(ctx context.Context, params ListPagesDeploy
 		return []PagesProjectDeployment{}, ResultInfo{}, ErrMissingProjectName
 	}
 
-	uri := buildURI(fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments", params.AccountID, params.ProjectName), params.PaginationOptions)
+	uri := buildURI(fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments", rc.Identifier, params.ProjectName), params.PaginationOptions)
 
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
@@ -163,20 +155,20 @@ func (api *API) ListPagesDeployments(ctx context.Context, params ListPagesDeploy
 // GetPagesDeploymentInfo returns a deployment for a Pages project.
 //
 // API reference: https://api.cloudflare.com/#pages-deployment-get-deployment-info
-func (api *API) GetPagesDeploymentInfo(ctx context.Context, params GetPagesDeploymentInfoParams) (PagesProjectDeployment, error) {
-	if params.AccountID == "" {
+func (api *API) GetPagesDeploymentInfo(ctx context.Context, rc *ResourceContainer, projectName, deploymentID string) (PagesProjectDeployment, error) {
+	if rc.Identifier == "" {
 		return PagesProjectDeployment{}, ErrMissingAccountID
 	}
 
-	if params.ProjectName == "" {
+	if projectName == "" {
 		return PagesProjectDeployment{}, ErrMissingProjectName
 	}
 
-	if params.DeploymentID == "" {
+	if deploymentID == "" {
 		return PagesProjectDeployment{}, ErrMissingDeploymentID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s", params.AccountID, params.ProjectName, params.DeploymentID)
+	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s", rc.Identifier, projectName, deploymentID)
 
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
@@ -195,8 +187,8 @@ func (api *API) GetPagesDeploymentInfo(ctx context.Context, params GetPagesDeplo
 // API reference: https://api.cloudflare.com/#pages-deployment-get-deployment-stage-logs
 //
 // Deprecated: Use GetPagesDeploymentLogs instead.
-func (api *API) GetPagesDeploymentStageLogs(ctx context.Context, params GetPagesDeploymentStageLogsParams) (PagesDeploymentStageLogs, error) {
-	if params.AccountID == "" {
+func (api *API) GetPagesDeploymentStageLogs(ctx context.Context, rc *ResourceContainer, params GetPagesDeploymentStageLogsParams) (PagesDeploymentStageLogs, error) {
+	if rc.Identifier == "" {
 		return PagesDeploymentStageLogs{}, ErrMissingAccountID
 	}
 
@@ -213,7 +205,7 @@ func (api *API) GetPagesDeploymentStageLogs(ctx context.Context, params GetPages
 	}
 
 	uri := buildURI(
-		fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s/history/%s/logs", params.AccountID, params.ProjectName, params.DeploymentID, params.StageName),
+		fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s/history/%s/logs", rc.Identifier, params.ProjectName, params.DeploymentID, params.StageName),
 		params.SizeOptions,
 	)
 
@@ -232,8 +224,8 @@ func (api *API) GetPagesDeploymentStageLogs(ctx context.Context, params GetPages
 // GetPagesDeploymentStageLogs returns the logs for a Pages deployment stage.
 //
 // API reference: https://api.cloudflare.com/#pages-deployment-get-deployment-logs
-func (api *API) GetPagesDeploymentLogs(ctx context.Context, params GetPagesDeploymentLogsParams) (PagesDeploymentLogs, error) {
-	if params.AccountID == "" {
+func (api *API) GetPagesDeploymentLogs(ctx context.Context, rc *ResourceContainer, params GetPagesDeploymentLogsParams) (PagesDeploymentLogs, error) {
+	if rc.Identifier == "" {
 		return PagesDeploymentLogs{}, ErrMissingAccountID
 	}
 
@@ -246,7 +238,7 @@ func (api *API) GetPagesDeploymentLogs(ctx context.Context, params GetPagesDeplo
 	}
 
 	uri := buildURI(
-		fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s/history/logs", params.AccountID, params.ProjectName, params.DeploymentID),
+		fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s/history/logs", rc.Identifier, params.ProjectName, params.DeploymentID),
 		params.SizeOptions,
 	)
 
@@ -265,20 +257,20 @@ func (api *API) GetPagesDeploymentLogs(ctx context.Context, params GetPagesDeplo
 // DeletePagesDeployment deletes a Pages deployment.
 //
 // API reference: https://api.cloudflare.com/#pages-deployment-delete-deployment
-func (api *API) DeletePagesDeployment(ctx context.Context, params DeletePagesDeploymentParams) error {
-	if params.AccountID == "" {
+func (api *API) DeletePagesDeployment(ctx context.Context, rc *ResourceContainer, projectName, deploymentID string) error {
+	if rc.Identifier == "" {
 		return ErrMissingAccountID
 	}
 
-	if params.ProjectName == "" {
+	if projectName == "" {
 		return ErrMissingProjectName
 	}
 
-	if params.DeploymentID == "" {
+	if deploymentID == "" {
 		return ErrMissingDeploymentID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s", params.AccountID, params.ProjectName, params.DeploymentID)
+	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s", rc.Identifier, projectName, deploymentID)
 
 	_, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
 	if err != nil {
@@ -290,8 +282,8 @@ func (api *API) DeletePagesDeployment(ctx context.Context, params DeletePagesDep
 // CreatePagesDeployment creates a Pages production deployment.
 //
 // API reference: https://api.cloudflare.com/#pages-deployment-create-deployment
-func (api *API) CreatePagesDeployment(ctx context.Context, params CreatePagesDeploymentParams) (PagesProjectDeployment, error) {
-	if params.AccountID == "" {
+func (api *API) CreatePagesDeployment(ctx context.Context, rc *ResourceContainer, params CreatePagesDeploymentParams) (PagesProjectDeployment, error) {
+	if rc.Identifier == "" {
 		return PagesProjectDeployment{}, ErrMissingAccountID
 	}
 
@@ -299,7 +291,7 @@ func (api *API) CreatePagesDeployment(ctx context.Context, params CreatePagesDep
 		return PagesProjectDeployment{}, ErrMissingProjectName
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments", params.AccountID, params.ProjectName)
+	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments", rc.Identifier, params.ProjectName)
 
 	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, nil)
 	if err != nil {
@@ -316,20 +308,20 @@ func (api *API) CreatePagesDeployment(ctx context.Context, params CreatePagesDep
 // RetryPagesDeployment retries a specific Pages deployment.
 //
 // API reference: https://api.cloudflare.com/#pages-deployment-retry-deployment
-func (api *API) RetryPagesDeployment(ctx context.Context, params RetryPagesDeploymentParams) (PagesProjectDeployment, error) {
-	if params.AccountID == "" {
+func (api *API) RetryPagesDeployment(ctx context.Context, rc *ResourceContainer, projectName, deploymentID string) (PagesProjectDeployment, error) {
+	if rc.Identifier == "" {
 		return PagesProjectDeployment{}, ErrMissingAccountID
 	}
 
-	if params.ProjectName == "" {
+	if projectName == "" {
 		return PagesProjectDeployment{}, ErrMissingProjectName
 	}
 
-	if params.DeploymentID == "" {
+	if deploymentID == "" {
 		return PagesProjectDeployment{}, ErrMissingDeploymentID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s/retry", params.AccountID, params.ProjectName, params.DeploymentID)
+	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s/retry", rc.Identifier, projectName, deploymentID)
 
 	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, nil)
 	if err != nil {
@@ -346,20 +338,20 @@ func (api *API) RetryPagesDeployment(ctx context.Context, params RetryPagesDeplo
 // RollbackPagesDeployment rollbacks the Pages production deployment to a previous production deployment.
 //
 // API reference: https://api.cloudflare.com/#pages-deployment-rollback-deployment
-func (api *API) RollbackPagesDeployment(ctx context.Context, params RollbackPagesDeploymentParams) (PagesProjectDeployment, error) {
-	if params.AccountID == "" {
+func (api *API) RollbackPagesDeployment(ctx context.Context, rc *ResourceContainer, projectName, deploymentID string) (PagesProjectDeployment, error) {
+	if rc.Identifier == "" {
 		return PagesProjectDeployment{}, ErrMissingAccountID
 	}
 
-	if params.ProjectName == "" {
+	if projectName == "" {
 		return PagesProjectDeployment{}, ErrMissingProjectName
 	}
 
-	if params.DeploymentID == "" {
+	if deploymentID == "" {
 		return PagesProjectDeployment{}, ErrMissingDeploymentID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s/rollback", params.AccountID, params.ProjectName, params.DeploymentID)
+	uri := fmt.Sprintf("/accounts/%s/pages/projects/%s/deployments/%s/rollback", rc.Identifier, projectName, deploymentID)
 
 	res, err := api.makeRequestContext(ctx, http.MethodPost, uri, nil)
 	if err != nil {
diff --git a/resource.go b/resource.go
index 824cfd70a..cf0a9cfb6 100644
--- a/resource.go
+++ b/resource.go
@@ -9,33 +9,40 @@ const (
 	UserRouteLevel    RouteLevel = "user"
 )
 
-// Resource defines an API resource you wish to target. Should not be used
-// directly, use `UserIdentifer`, `ZoneIdentifier` and `AccountIdentifier`
+// ResourceContainer defines an API resource you wish to target. Should not be
+// used directly, use `UserIdentifier`, `ZoneIdentifier` and `AccountIdentifier`
 // instead.
-type Resource struct {
+type ResourceContainer struct {
 	Level      RouteLevel
 	Identifier string
 }
 
-// UserIdentifer returns a user level *Resource.
-func UserIdentifer(id string) *Resource {
-	return &Resource{
+// ResourceIdentifier returns a generic *ResourceContainer.
+func ResourceIdentifier(id string) *ResourceContainer {
+	return &ResourceContainer{
+		Identifier: id,
+	}
+}
+
+// UserIdentifier returns a user level *ResourceContainer.
+func UserIdentifier(id string) *ResourceContainer {
+	return &ResourceContainer{
 		Level:      UserRouteLevel,
 		Identifier: id,
 	}
 }
 
-// ZoneIdentifer returns a zone level *Resource.
-func ZoneIdentifer(id string) *Resource {
-	return &Resource{
+// ZoneIdentifier returns a zone level *ResourceContainer.
+func ZoneIdentifier(id string) *ResourceContainer {
+	return &ResourceContainer{
 		Level:      ZoneRouteLevel,
 		Identifier: id,
 	}
 }
 
-// AccountIdentifer returns an account level *Resource.
-func AccountIdentifer(id string) *Resource {
-	return &Resource{
+// AccountIdentifier returns an account level *ResourceContainer.
+func AccountIdentifier(id string) *ResourceContainer {
+	return &ResourceContainer{
 		Level:      AccountRouteLevel,
 		Identifier: id,
 	}
diff --git a/tunnel.go b/tunnel.go
index 5aa304364..c9f7a7cab 100644
--- a/tunnel.go
+++ b/tunnel.go
@@ -85,21 +85,14 @@ type TunnelTokenResponse struct {
 	Response
 }
 
-type TunnelParams struct {
-	AccountID string
-	ID        string
-}
-
 type TunnelCreateParams struct {
-	AccountID string `json:"-"`
-	Name      string `json:"name,omitempty"`
-	Secret    string `json:"tunnel_secret,omitempty"`
+	Name   string `json:"name,omitempty"`
+	Secret string `json:"tunnel_secret,omitempty"`
 }
 
 type TunnelUpdateParams struct {
-	AccountID string `json:"-"`
-	Name      string `json:"name,omitempty"`
-	Secret    string `json:"tunnel_secret,omitempty"`
+	Name   string `json:"name,omitempty"`
+	Secret string `json:"tunnel_secret,omitempty"`
 }
 
 type UnvalidatedIngressRule struct {
@@ -168,29 +161,8 @@ type WarpRoutingConfig struct {
 }
 
 type TunnelConfigurationParams struct {
-	AccountID string              `json:"-"`
-	TunnelID  string              `json:"-"`
-	Config    TunnelConfiguration `json:"config,omitempty"`
-}
-
-type GetTunnelConfigurationParams struct {
-	AccountID string `json:"-"`
-	TunnelID  string `json:"-"`
-}
-
-type TunnelDeleteParams struct {
-	AccountID string
-	ID        string
-}
-
-type TunnelCleanupParams struct {
-	AccountID string
-	ID        string
-}
-
-type TunnelTokenParams struct {
-	AccountID string
-	ID        string
+	TunnelID string              `json:"-"`
+	Config   TunnelConfiguration `json:"config,omitempty"`
 }
 
 type TunnelListParams struct {
@@ -204,12 +176,12 @@ type TunnelListParams struct {
 // Tunnels lists all tunnels.
 //
 // API reference: https://api.cloudflare.com/#cloudflare-tunnel-list-cloudflare-tunnels
-func (api *API) Tunnels(ctx context.Context, params TunnelListParams) ([]Tunnel, error) {
-	if params.AccountID == "" {
+func (api *API) Tunnels(ctx context.Context, rc *ResourceContainer, params TunnelListParams) ([]Tunnel, error) {
+	if rc.Identifier == "" {
 		return []Tunnel{}, ErrMissingAccountID
 	}
 
-	uri := buildURI(fmt.Sprintf("/accounts/%s/cfd_tunnel", params.AccountID), params)
+	uri := buildURI(fmt.Sprintf("/accounts/%s/cfd_tunnel", rc.Identifier), params)
 
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
@@ -227,16 +199,16 @@ func (api *API) Tunnels(ctx context.Context, params TunnelListParams) ([]Tunnel,
 // Tunnel returns a single Argo tunnel.
 //
 // API reference: https://api.cloudflare.com/#cloudflare-tunnel-get-cloudflare-tunnel
-func (api *API) Tunnel(ctx context.Context, params TunnelParams) (Tunnel, error) {
-	if params.AccountID == "" {
+func (api *API) Tunnel(ctx context.Context, rc *ResourceContainer, tunnelID string) (Tunnel, error) {
+	if rc.Identifier == "" {
 		return Tunnel{}, ErrMissingAccountID
 	}
 
-	if params.ID == "" {
+	if tunnelID == "" {
 		return Tunnel{}, errors.New("missing tunnel ID")
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel/%s", params.AccountID, params.ID)
+	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel/%s", rc.Identifier, tunnelID)
 
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
@@ -254,8 +226,8 @@ func (api *API) Tunnel(ctx context.Context, params TunnelParams) (Tunnel, error)
 // CreateTunnel creates a new tunnel for the account.
 //
 // API reference: https://api.cloudflare.com/#cloudflare-tunnel-create-cloudflare-tunnel
-func (api *API) CreateTunnel(ctx context.Context, params TunnelCreateParams) (Tunnel, error) {
-	if params.AccountID == "" {
+func (api *API) CreateTunnel(ctx context.Context, rc *ResourceContainer, params TunnelCreateParams) (Tunnel, error) {
+	if rc.Identifier == "" {
 		return Tunnel{}, ErrMissingAccountID
 	}
 
@@ -267,7 +239,7 @@ func (api *API) CreateTunnel(ctx context.Context, params TunnelCreateParams) (Tu
 		return Tunnel{}, errors.New("missing tunnel secret")
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel", params.AccountID)
+	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel", rc.Identifier)
 
 	tunnel := Tunnel{Name: params.Name, Secret: params.Secret}
 
@@ -288,12 +260,12 @@ func (api *API) CreateTunnel(ctx context.Context, params TunnelCreateParams) (Tu
 // UpdateTunnel updates an existing tunnel for the account.
 //
 // API reference: https://api.cloudflare.com/#cloudflare-tunnel-update-cloudflare-tunnel
-func (api *API) UpdateTunnel(ctx context.Context, params TunnelUpdateParams) (Tunnel, error) {
-	if params.AccountID == "" {
+func (api *API) UpdateTunnel(ctx context.Context, rc *ResourceContainer, params TunnelUpdateParams) (Tunnel, error) {
+	if rc.Identifier == "" {
 		return Tunnel{}, ErrMissingAccountID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel", params.AccountID)
+	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel", rc.Identifier)
 
 	var tunnel Tunnel
 
@@ -322,16 +294,16 @@ func (api *API) UpdateTunnel(ctx context.Context, params TunnelUpdateParams) (Tu
 // UpdateTunnelConfiguration updates an existing tunnel for the account.
 //
 // API reference: https://api.cloudflare.com/#cloudflare-tunnel-configuration-properties
-func (api *API) UpdateTunnelConfiguration(ctx context.Context, params TunnelConfigurationParams) (TunnelConfigurationResult, error) {
-	if len(params.AccountID) == 0 {
+func (api *API) UpdateTunnelConfiguration(ctx context.Context, rc *ResourceContainer, params TunnelConfigurationParams) (TunnelConfigurationResult, error) {
+	if rc.Identifier == "" {
 		return TunnelConfigurationResult{}, ErrMissingAccountID
 	}
 
-	if len(params.TunnelID) == 0 {
+	if params.TunnelID == "" {
 		return TunnelConfigurationResult{}, ErrMissingTunnelID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel/%s/configurations", params.AccountID, params.TunnelID)
+	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel/%s/configurations", rc.Identifier, params.TunnelID)
 	res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params.Config)
 	if err != nil {
 		return TunnelConfigurationResult{}, err
@@ -366,16 +338,16 @@ func (api *API) UpdateTunnelConfiguration(ctx context.Context, params TunnelConf
 // GetTunnelConfiguration updates an existing tunnel for the account.
 //
 // API reference: https://api.cloudflare.com/#cloudflare-tunnel-configuration-properties
-func (api *API) GetTunnelConfiguration(ctx context.Context, params GetTunnelConfigurationParams) (TunnelConfigurationResult, error) {
-	if len(params.AccountID) == 0 {
+func (api *API) GetTunnelConfiguration(ctx context.Context, rc *ResourceContainer, tunnelID string) (TunnelConfigurationResult, error) {
+	if rc.Identifier == "" {
 		return TunnelConfigurationResult{}, ErrMissingAccountID
 	}
 
-	if len(params.TunnelID) == 0 {
+	if tunnelID == "" {
 		return TunnelConfigurationResult{}, ErrMissingTunnelID
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel/%s/configurations", params.AccountID, params.TunnelID)
+	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel/%s/configurations", rc.Identifier, tunnelID)
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
 		return TunnelConfigurationResult{}, err
@@ -410,8 +382,8 @@ func (api *API) GetTunnelConfiguration(ctx context.Context, params GetTunnelConf
 // DeleteTunnel removes a single Argo tunnel.
 //
 // API reference: https://api.cloudflare.com/#cloudflare-tunnel-delete-cloudflare-tunnel
-func (api *API) DeleteTunnel(ctx context.Context, params TunnelDeleteParams) error {
-	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel/%s", params.AccountID, params.ID)
+func (api *API) DeleteTunnel(ctx context.Context, rc *ResourceContainer, tunnelID string) error {
+	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel/%s", rc.Identifier, tunnelID)
 
 	res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
 	if err != nil {
@@ -430,16 +402,16 @@ func (api *API) DeleteTunnel(ctx context.Context, params TunnelDeleteParams) err
 // CleanupTunnelConnections deletes any inactive connections on a tunnel.
 //
 // API reference: https://api.cloudflare.com/#cloudflare-tunnel-clean-up-cloudflare-tunnel-connections
-func (api *API) CleanupTunnelConnections(ctx context.Context, params TunnelCleanupParams) error {
-	if params.AccountID == "" {
+func (api *API) CleanupTunnelConnections(ctx context.Context, rc *ResourceContainer, tunnelID string) error {
+	if rc.Identifier == "" {
 		return ErrMissingAccountID
 	}
 
-	if params.ID == "" {
+	if tunnelID == "" {
 		return errors.New("missing tunnel ID")
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel/%s/connections", params.AccountID, params.ID)
+	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel/%s/connections", rc.Identifier, tunnelID)
 
 	res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
 	if err != nil {
@@ -458,16 +430,16 @@ func (api *API) CleanupTunnelConnections(ctx context.Context, params TunnelClean
 // TunnelToken that allows to run a tunnel.
 //
 // API reference: https://api.cloudflare.com/#cloudflare-tunnel-get-cloudflare-tunnel-token
-func (api *API) TunnelToken(ctx context.Context, params TunnelTokenParams) (string, error) {
-	if params.AccountID == "" {
+func (api *API) TunnelToken(ctx context.Context, rc *ResourceContainer, tunnelID string) (string, error) {
+	if rc.Identifier == "" {
 		return "", ErrMissingAccountID
 	}
 
-	if params.ID == "" {
+	if tunnelID == "" {
 		return "", errors.New("missing tunnel ID")
 	}
 
-	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel/%s/token", params.AccountID, params.ID)
+	uri := fmt.Sprintf("/accounts/%s/cfd_tunnel/%s/token", rc.Identifier, tunnelID)
 
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
diff --git a/tunnel_routes.go b/tunnel_routes.go
index 0a8eb72e7..966c5a71d 100644
--- a/tunnel_routes.go
+++ b/tunnel_routes.go
@@ -29,7 +29,6 @@ type TunnelRoute struct {
 }
 
 type TunnelRoutesListParams struct {
-	AccountID        string     `url:"-"`
 	TunnelID         string     `url:"tunnel_id,omitempty"`
 	Comment          string     `url:"comment,omitempty"`
 	IsDeleted        *bool      `url:"is_deleted,omitempty"`
@@ -41,7 +40,6 @@ type TunnelRoutesListParams struct {
 }
 
 type TunnelRoutesCreateParams struct {
-	AccountID        string `json:"-"`
 	Network          string `json:"-"`
 	TunnelID         string `json:"tunnel_id"`
 	Comment          string `json:"comment,omitempty"`
@@ -49,7 +47,6 @@ type TunnelRoutesCreateParams struct {
 }
 
 type TunnelRoutesUpdateParams struct {
-	AccountID        string `json:"-"`
 	Network          string `json:"network"`
 	TunnelID         string `json:"tunnel_id"`
 	Comment          string `json:"comment,omitempty"`
@@ -57,13 +54,11 @@ type TunnelRoutesUpdateParams struct {
 }
 
 type TunnelRoutesForIPParams struct {
-	AccountID        string `url:"-"`
 	Network          string `url:"-"`
 	VirtualNetworkID string `url:"virtual_network_id,omitempty"`
 }
 
 type TunnelRoutesDeleteParams struct {
-	AccountID        string `json:"-"`
 	Network          string `json:"-"`
 	VirtualNetworkID string `url:"virtual_network_id,omitempty"`
 }
@@ -82,12 +77,12 @@ type tunnelRouteResponse struct {
 // ListTunnelRoutes lists all defined routes for tunnels in the account.
 //
 // See: https://api.cloudflare.com/#tunnel-route-list-tunnel-routes
-func (api *API) ListTunnelRoutes(ctx context.Context, params TunnelRoutesListParams) ([]TunnelRoute, error) {
-	if params.AccountID == "" {
+func (api *API) ListTunnelRoutes(ctx context.Context, rc *ResourceContainer, params TunnelRoutesListParams) ([]TunnelRoute, error) {
+	if rc.Identifier == "" {
 		return []TunnelRoute{}, ErrMissingAccountID
 	}
 
-	uri := buildURI(fmt.Sprintf("/%s/%s/teamnet/routes", AccountRouteRoot, params.AccountID), params)
+	uri := buildURI(fmt.Sprintf("/%s/%s/teamnet/routes", AccountRouteRoot, rc.Identifier), params)
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
 		return []TunnelRoute{}, err
@@ -105,8 +100,8 @@ func (api *API) ListTunnelRoutes(ctx context.Context, params TunnelRoutesListPar
 // GetTunnelRouteForIP finds the Tunnel Route that encompasses the given IP.
 //
 // See: https://api.cloudflare.com/#tunnel-route-get-tunnel-route-by-ip
-func (api *API) GetTunnelRouteForIP(ctx context.Context, params TunnelRoutesForIPParams) (TunnelRoute, error) {
-	if params.AccountID == "" {
+func (api *API) GetTunnelRouteForIP(ctx context.Context, rc *ResourceContainer, params TunnelRoutesForIPParams) (TunnelRoute, error) {
+	if rc.Identifier == "" {
 		return TunnelRoute{}, ErrMissingAccountID
 	}
 
@@ -118,7 +113,7 @@ func (api *API) GetTunnelRouteForIP(ctx context.Context, params TunnelRoutesForI
 		return TunnelRoute{}, ErrInvalidNetworkValue
 	}
 
-	uri := buildURI(fmt.Sprintf("/%s/%s/teamnet/routes/ip/%s", AccountRouteRoot, params.AccountID, params.Network), params)
+	uri := buildURI(fmt.Sprintf("/%s/%s/teamnet/routes/ip/%s", AccountRouteRoot, rc.Identifier, params.Network), params)
 
 	responseBody, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
 	if err != nil {
@@ -138,8 +133,8 @@ func (api *API) GetTunnelRouteForIP(ctx context.Context, params TunnelRoutesForI
 // tunnel.
 //
 // See: https://api.cloudflare.com/#tunnel-route-create-route
-func (api *API) CreateTunnelRoute(ctx context.Context, params TunnelRoutesCreateParams) (TunnelRoute, error) {
-	if params.AccountID == "" {
+func (api *API) CreateTunnelRoute(ctx context.Context, rc *ResourceContainer, params TunnelRoutesCreateParams) (TunnelRoute, error) {
+	if rc.Identifier == "" {
 		return TunnelRoute{}, ErrMissingAccountID
 	}
 
@@ -147,7 +142,7 @@ func (api *API) CreateTunnelRoute(ctx context.Context, params TunnelRoutesCreate
 		return TunnelRoute{}, ErrMissingNetwork
 	}
 
-	uri := fmt.Sprintf("/%s/%s/teamnet/routes/network/%s", AccountRouteRoot, params.AccountID, url.PathEscape(params.Network))
+	uri := fmt.Sprintf("/%s/%s/teamnet/routes/network/%s", AccountRouteRoot, rc.Identifier, url.PathEscape(params.Network))
 
 	responseBody, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
 	if err != nil {
@@ -166,8 +161,8 @@ func (api *API) CreateTunnelRoute(ctx context.Context, params TunnelRoutesCreate
 // DeleteTunnelRoute delete an existing route from the account routing table.
 //
 // See: https://api.cloudflare.com/#tunnel-route-delete-route
-func (api *API) DeleteTunnelRoute(ctx context.Context, params TunnelRoutesDeleteParams) error {
-	if params.AccountID == "" {
+func (api *API) DeleteTunnelRoute(ctx context.Context, rc *ResourceContainer, params TunnelRoutesDeleteParams) error {
+	if rc.Identifier == "" {
 		return ErrMissingAccountID
 	}
 
@@ -175,7 +170,7 @@ func (api *API) DeleteTunnelRoute(ctx context.Context, params TunnelRoutesDelete
 		return ErrMissingNetwork
 	}
 
-	uri := fmt.Sprintf("/%s/%s/teamnet/routes/network/%s", AccountRouteRoot, params.AccountID, url.PathEscape(params.Network))
+	uri := fmt.Sprintf("/%s/%s/teamnet/routes/network/%s", AccountRouteRoot, rc.Identifier, url.PathEscape(params.Network))
 
 	responseBody, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
 	if err != nil {
@@ -195,12 +190,12 @@ func (api *API) DeleteTunnelRoute(ctx context.Context, params TunnelRoutesDelete
 // the given tunnel.
 //
 // See: https://api.cloudflare.com/#tunnel-route-update-route
-func (api *API) UpdateTunnelRoute(ctx context.Context, params TunnelRoutesUpdateParams) (TunnelRoute, error) {
-	if params.AccountID == "" {
+func (api *API) UpdateTunnelRoute(ctx context.Context, rc *ResourceContainer, params TunnelRoutesUpdateParams) (TunnelRoute, error) {
+	if rc.Identifier == "" {
 		return TunnelRoute{}, ErrMissingAccountID
 	}
 
-	uri := fmt.Sprintf("/%s/%s/teamnet/routes/network/%s", AccountRouteRoot, params.AccountID, url.PathEscape(params.Network))
+	uri := fmt.Sprintf("/%s/%s/teamnet/routes/network/%s", AccountRouteRoot, rc.Identifier, url.PathEscape(params.Network))
 
 	responseBody, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
 	if err != nil {
diff --git a/tunnel_virtual_networks.go b/tunnel_virtual_networks.go
index eb80c67af..2a22c2e67 100644
--- a/tunnel_virtual_networks.go
+++ b/tunnel_virtual_networks.go
@@ -24,7 +24,6 @@ type TunnelVirtualNetwork struct {
 }
 
 type TunnelVirtualNetworksListParams struct {
-	AccountID string `url:"-"`
 	ID        string `url:"id,omitempty"`
 	Name      string `url:"name,omitempty"`
 	IsDefault *bool  `url:"is_default,omitempty"`
@@ -34,25 +33,18 @@ type TunnelVirtualNetworksListParams struct {
 }
 
 type TunnelVirtualNetworkCreateParams struct {
-	AccountID string `json:"-"`
 	Name      string `json:"name"`
 	Comment   string `json:"comment"`
 	IsDefault bool   `json:"is_default"`
 }
 
 type TunnelVirtualNetworkUpdateParams struct {
-	AccountID        string `json:"-"`
 	VnetID           string `json:"-"`
 	Name             string `json:"name,omitempty"`
 	Comment          string `json:"comment,omitempty"`
 	IsDefaultNetwork *bool  `json:"is_default_network,omitempty"`
 }
 
-type TunnelVirtualNetworkDeleteParams struct {
-	AccountID string `json:"-"`
-	VnetID    string `json:"-"`
-}
-
 // tunnelRouteListResponse is the API response for listing tunnel virtual
 // networks.
 type tunnelVirtualNetworkListResponse struct {
@@ -69,12 +61,12 @@ type tunnelVirtualNetworkResponse struct {
 // the account.
 //
 // API reference: https://api.cloudflare.com/#tunnel-virtual-network-list-virtual-networks
-func (api *API) ListTunnelVirtualNetworks(ctx context.Context, params TunnelVirtualNetworksListParams) ([]TunnelVirtualNetwork, error) {
-	if params.AccountID == "" {
+func (api *API) ListTunnelVirtualNetworks(ctx context.Context, rc *ResourceContainer, params TunnelVirtualNetworksListParams) ([]TunnelVirtualNetwork, error) {
+	if rc.Identifier == "" {
 		return []TunnelVirtualNetwork{}, ErrMissingAccountID
 	}
 
-	uri := buildURI(fmt.Sprintf("/%s/%s/teamnet/virtual_networks", AccountRouteRoot, params.AccountID), params)
+	uri := buildURI(fmt.Sprintf("/%s/%s/teamnet/virtual_networks", AccountRouteRoot, rc.Identifier), params)
 	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, params)
 	if err != nil {
 		return []TunnelVirtualNetwork{}, err
@@ -92,8 +84,8 @@ func (api *API) ListTunnelVirtualNetworks(ctx context.Context, params TunnelVirt
 // CreateTunnelVirtualNetwork adds a new virtual network to the account.
 //
 // API reference: https://api.cloudflare.com/#tunnel-virtual-network-create-virtual-network
-func (api *API) CreateTunnelVirtualNetwork(ctx context.Context, params TunnelVirtualNetworkCreateParams) (TunnelVirtualNetwork, error) {
-	if params.AccountID == "" {
+func (api *API) CreateTunnelVirtualNetwork(ctx context.Context, rc *ResourceContainer, params TunnelVirtualNetworkCreateParams) (TunnelVirtualNetwork, error) {
+	if rc.Identifier == "" {
 		return TunnelVirtualNetwork{}, ErrMissingAccountID
 	}
 
@@ -101,7 +93,7 @@ func (api *API) CreateTunnelVirtualNetwork(ctx context.Context, params TunnelVir
 		return TunnelVirtualNetwork{}, ErrMissingVnetName
 	}
 
-	uri := fmt.Sprintf("/%s/%s/teamnet/virtual_networks", AccountRouteRoot, params.AccountID)
+	uri := fmt.Sprintf("/%s/%s/teamnet/virtual_networks", AccountRouteRoot, rc.Identifier)
 
 	responseBody, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
 	if err != nil {
@@ -121,12 +113,12 @@ func (api *API) CreateTunnelVirtualNetwork(ctx context.Context, params TunnelVir
 // account.
 //
 // API reference: https://api.cloudflare.com/#tunnel-virtual-network-delete-virtual-network
-func (api *API) DeleteTunnelVirtualNetwork(ctx context.Context, params TunnelVirtualNetworkDeleteParams) error {
-	if params.AccountID == "" {
+func (api *API) DeleteTunnelVirtualNetwork(ctx context.Context, rc *ResourceContainer, vnetID string) error {
+	if rc.Identifier == "" {
 		return ErrMissingAccountID
 	}
 
-	uri := fmt.Sprintf("/%s/%s/teamnet/virtual_networks/%s", AccountRouteRoot, params.AccountID, params.VnetID)
+	uri := fmt.Sprintf("/%s/%s/teamnet/virtual_networks/%s", AccountRouteRoot, rc.Identifier, vnetID)
 
 	responseBody, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil)
 	if err != nil {
@@ -145,12 +137,12 @@ func (api *API) DeleteTunnelVirtualNetwork(ctx context.Context, params TunnelVir
 // UpdateTunnelRoute updates an existing virtual network in the account.
 //
 // API reference: https://api.cloudflare.com/#tunnel-virtual-network-update-virtual-network
-func (api *API) UpdateTunnelVirtualNetwork(ctx context.Context, params TunnelVirtualNetworkUpdateParams) (TunnelVirtualNetwork, error) {
-	if params.AccountID == "" {
+func (api *API) UpdateTunnelVirtualNetwork(ctx context.Context, rc *ResourceContainer, params TunnelVirtualNetworkUpdateParams) (TunnelVirtualNetwork, error) {
+	if rc.Identifier == "" {
 		return TunnelVirtualNetwork{}, ErrMissingAccountID
 	}
 
-	uri := fmt.Sprintf("/%s/%s/teamnet/virtual_networks/%s", AccountRouteRoot, params.AccountID, params.VnetID)
+	uri := fmt.Sprintf("/%s/%s/teamnet/virtual_networks/%s", AccountRouteRoot, rc.Identifier, params.VnetID)
 
 	responseBody, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
 	if err != nil {
diff --git a/zones.go b/zones.go
index 1ba42dce0..c924fe037 100644
--- a/zones.go
+++ b/zones.go
@@ -55,8 +55,8 @@ func (s *ZonesService) New(ctx context.Context, zone *ZoneCreateParams) (Zone, e
 // Get fetches a single zone.
 //
 // API reference: https://api.cloudflare.com/#zone-zone-details
-func (s *ZonesService) Get(ctx context.Context, resource *Resource) (Zone, error) {
-	uri := fmt.Sprintf("/%s/%s", resource.Level, resource.Identifier)
+func (s *ZonesService) Get(ctx context.Context, rc *ResourceContainer) (Zone, error) {
+	uri := fmt.Sprintf("/zones/%s", rc.Identifier)
 	res, err := s.client.get(ctx, uri, nil)
 	if err != nil {
 		return Zone{}, fmt.Errorf("failed to fetch zones: %w", err)
@@ -105,8 +105,8 @@ func (s *ZonesService) Update(ctx context.Context, params *ZoneUpdateParams) ([]
 // Delete deletes a zone based on ID.
 //
 // API reference: https://api.cloudflare.com/#zone-delete-zone
-func (s *ZonesService) Delete(ctx context.Context, resource *Resource) error {
-	uri := fmt.Sprintf("/%s/%s", resource.Level, resource.Identifier)
+func (s *ZonesService) Delete(ctx context.Context, rc *ResourceContainer) error {
+	uri := fmt.Sprintf("/zones/%s", rc.Identifier)
 	res, _ := s.client.delete(ctx, uri, nil)
 
 	var r ZoneResponse


Test patch:
diff --git a/list_test.go b/list_test.go
index 6d806ce80..9a73a0a8f 100644
--- a/list_test.go
+++ b/list_test.go
@@ -54,9 +54,7 @@ func TestListLists(t *testing.T) {
 		},
 	}
 
-	actual, err := client.ListLists(context.Background(), ListListsParams{
-		AccountID: testAccountID,
-	})
+	actual, err := client.ListLists(context.Background(), AccountIdentifier(testAccountID), ListListsParams{})
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
 	}
@@ -102,8 +100,8 @@ func TestCreateList(t *testing.T) {
 		ModifiedOn:            &modifiedOn,
 	}
 
-	actual, err := client.CreateList(context.Background(), ListCreateParams{
-		AccountID: testAccountID, Name: "list1", Description: "This is a note.", Kind: "ip",
+	actual, err := client.CreateList(context.Background(), AccountIdentifier(testAccountID), ListCreateParams{
+		Name: "list1", Description: "This is a note.", Kind: "ip",
 	})
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
@@ -150,9 +148,7 @@ func TestGetList(t *testing.T) {
 		ModifiedOn:            &modifiedOn,
 	}
 
-	actual, err := client.GetList(context.Background(), ListGetParams{
-		AccountID: testAccountID, ID: "2c0fc9fa937b11eaa1b71c4d701ab86e",
-	})
+	actual, err := client.GetList(context.Background(), AccountIdentifier(testAccountID), "2c0fc9fa937b11eaa1b71c4d701ab86e")
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
 	}
@@ -198,9 +194,9 @@ func TestUpdateList(t *testing.T) {
 		ModifiedOn:            &modifiedOn,
 	}
 
-	actual, err := client.UpdateList(context.Background(),
+	actual, err := client.UpdateList(context.Background(), AccountIdentifier(testAccountID),
 		ListUpdateParams{
-			AccountID: testAccountID, ID: "2c0fc9fa937b11eaa1b71c4d701ab86e", Description: "This note was updated.",
+			ID: "2c0fc9fa937b11eaa1b71c4d701ab86e", Description: "This note was updated.",
 		},
 	)
 	if assert.NoError(t, err) {
@@ -233,9 +229,7 @@ func TestDeleteList(t *testing.T) {
 	want.Messages = []ResponseInfo{}
 	want.Result.ID = "34b12448945f11eaa1b71c4d701ab86e"
 
-	actual, err := client.DeleteList(context.Background(), ListDeleteParams{
-		AccountID: testAccountID, ID: "2c0fc9fa937b11eaa1b71c4d701ab86e",
-	})
+	actual, err := client.DeleteList(context.Background(), AccountIdentifier(testAccountID), "2c0fc9fa937b11eaa1b71c4d701ab86e")
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
 	}
@@ -315,8 +309,8 @@ func TestListsItemsIP(t *testing.T) {
 		},
 	}
 
-	actual, err := client.ListListItems(context.Background(), ListListItemsParams{
-		AccountID: testAccountID, ID: "2c0fc9fa937b11eaa1b71c4d701ab86e",
+	actual, err := client.ListListItems(context.Background(), AccountIdentifier(testAccountID), ListListItemsParams{
+		ID: "2c0fc9fa937b11eaa1b71c4d701ab86e",
 	})
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
@@ -421,7 +415,8 @@ func TestListsItemsRedirect(t *testing.T) {
 
 	actual, err := client.ListListItems(
 		context.Background(),
-		ListListItemsParams{AccountID: testAccountID, ID: "0c0fc9fa937b11eaa1b71c4d701ab86e"},
+		AccountIdentifier(testAccountID),
+		ListListItemsParams{ID: "0c0fc9fa937b11eaa1b71c4d701ab86e"},
 	)
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
@@ -453,9 +448,8 @@ func TestCreateListItemsIP(t *testing.T) {
 	want.Messages = []ResponseInfo{}
 	want.Result.OperationID = "4da8780eeb215e6cb7f48dd981c4ea02"
 
-	actual, err := client.CreateListItemsAsync(context.Background(), ListCreateItemsParams{
-		AccountID: testAccountID,
-		ID:        "2c0fc9fa937b11eaa1b71c4d701ab86e",
+	actual, err := client.CreateListItemsAsync(context.Background(), AccountIdentifier(testAccountID), ListCreateItemsParams{
+		ID: "2c0fc9fa937b11eaa1b71c4d701ab86e",
 		Items: []ListItemCreateRequest{{
 			IP:      StringPtr("192.0.2.1"),
 			Comment: "Private IP",
@@ -493,9 +487,8 @@ func TestCreateListItemsRedirect(t *testing.T) {
 	want.Messages = []ResponseInfo{}
 	want.Result.OperationID = "4da8780eeb215e6cb7f48dd981c4ea02"
 
-	actual, err := client.CreateListItemsAsync(context.Background(), ListCreateItemsParams{
-		AccountID: testAccountID,
-		ID:        "0c0fc9fa937b11eaa1b71c4d701ab86e",
+	actual, err := client.CreateListItemsAsync(context.Background(), AccountIdentifier(testAccountID), ListCreateItemsParams{
+		ID: "0c0fc9fa937b11eaa1b71c4d701ab86e",
 		Items: []ListItemCreateRequest{{
 			Redirect: &Redirect{
 				SourceUrl: "www.3fonteinen.be",
@@ -539,9 +532,8 @@ func TestReplaceListItemsIP(t *testing.T) {
 	want.Messages = []ResponseInfo{}
 	want.Result.OperationID = "4da8780eeb215e6cb7f48dd981c4ea02"
 
-	actual, err := client.ReplaceListItemsAsync(context.Background(), ListReplaceItemsParams{
-		AccountID: testAccountID,
-		ID:        "2c0fc9fa937b11eaa1b71c4d701ab86e",
+	actual, err := client.ReplaceListItemsAsync(context.Background(), AccountIdentifier(testAccountID), ListReplaceItemsParams{
+		ID: "2c0fc9fa937b11eaa1b71c4d701ab86e",
 		Items: []ListItemCreateRequest{{
 			IP:      StringPtr("192.0.2.1"),
 			Comment: "Private IP",
@@ -579,9 +571,8 @@ func TestReplaceListItemsRedirect(t *testing.T) {
 	want.Messages = []ResponseInfo{}
 	want.Result.OperationID = "4da8780eeb215e6cb7f48dd981c4ea02"
 
-	actual, err := client.ReplaceListItemsAsync(context.Background(), ListReplaceItemsParams{
-		AccountID: testAccountID,
-		ID:        "2c0fc9fa937b11eaa1b71c4d701ab86e",
+	actual, err := client.ReplaceListItemsAsync(context.Background(), AccountIdentifier(testAccountID), ListReplaceItemsParams{
+		ID: "2c0fc9fa937b11eaa1b71c4d701ab86e",
 		Items: []ListItemCreateRequest{{
 			Redirect: &Redirect{
 				SourceUrl: "www.3fonteinen.be",
@@ -625,9 +616,8 @@ func TestDeleteListItems(t *testing.T) {
 	want.Messages = []ResponseInfo{}
 	want.Result.OperationID = "4da8780eeb215e6cb7f48dd981c4ea02"
 
-	actual, err := client.DeleteListItemsAsync(context.Background(), ListDeleteItemsParams{
-		AccountID: testAccountID,
-		ID:        "2c0fc9fa937b11eaa1b71c4d701ab86e",
+	actual, err := client.DeleteListItemsAsync(context.Background(), AccountIdentifier(testAccountID), ListDeleteItemsParams{
+		ID: "2c0fc9fa937b11eaa1b71c4d701ab86e",
 		Items: ListItemDeleteRequest{[]ListItemDeleteItemRequest{{
 			ID: "34b12448945f11eaa1b71c4d701ab86e",
 		}}}})
@@ -671,11 +661,7 @@ func TestGetListItemIP(t *testing.T) {
 		ModifiedOn: &modifiedOn,
 	}
 
-	actual, err := client.GetListItem(context.Background(), ListGetItemParams{
-		AccountID: testAccountID,
-		ListID:    "2c0fc9fa937b11eaa1b71c4d701ab86e",
-		ID:        "34b12448945f11eaa1b71c4d701ab86e",
-	})
+	actual, err := client.GetListItem(context.Background(), AccountIdentifier(testAccountID), "2c0fc9fa937b11eaa1b71c4d701ab86e", "34b12448945f11eaa1b71c4d701ab86e")
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
 	}
@@ -686,7 +672,7 @@ func TestPollListTimeout(t *testing.T) {
 	defer cancel()
 
 	start := time.Now()
-	err := client.pollListBulkOperation(ctx, testAccountID, "list1")
+	err := client.pollListBulkOperation(ctx, AccountIdentifier(testAccountID), "list1")
 	assert.ErrorIs(t, err, context.DeadlineExceeded)
 	assert.WithinDuration(t, start, time.Now(), time.Second,
 		"pollListBulkOperation took too much time with an expiring context")
diff --git a/managed_headers_test.go b/managed_headers_test.go
index d8b660450..833dd2622 100644
--- a/managed_headers_test.go
+++ b/managed_headers_test.go
@@ -79,9 +79,7 @@ func TestListManagedHeaders(t *testing.T) {
 		},
 	}
 
-	zoneActual, err := client.ListZoneManagedHeaders(context.Background(), ListManagedHeadersParams{
-		ZoneID: testZoneID,
-	})
+	zoneActual, err := client.ListZoneManagedHeaders(context.Background(), ZoneIdentifier(testZoneID), ListManagedHeadersParams{})
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, zoneActual)
 	}
@@ -170,8 +168,7 @@ func TestUpdateManagedHeaders(t *testing.T) {
 			},
 		},
 	}
-	zoneActual, err := client.UpdateZoneManagedHeaders(context.Background(), UpdateManagedHeadersParams{
-		ZoneID:         testZoneID,
+	zoneActual, err := client.UpdateZoneManagedHeaders(context.Background(), ZoneIdentifier(testZoneID), UpdateManagedHeadersParams{
 		ManagedHeaders: managedHeadersForUpdate,
 	})
 	if assert.NoError(t, err) {
diff --git a/pages_deployment_test.go b/pages_deployment_test.go
index ea809528e..f0d1693e3 100644
--- a/pages_deployment_test.go
+++ b/pages_deployment_test.go
@@ -377,8 +377,7 @@ func TestListPagesDeployments(t *testing.T) {
 		Count:   1,
 		Total:   1,
 	}
-	actual, resultInfo, err := client.ListPagesDeployments(context.Background(), ListPagesDeploymentsParams{
-		AccountID:         testAccountID,
+	actual, resultInfo, err := client.ListPagesDeployments(context.Background(), AccountIdentifier(testAccountID), ListPagesDeploymentsParams{
 		ProjectName:       "test",
 		PaginationOptions: PaginationOptions{},
 	})
@@ -406,11 +405,7 @@ func TestGetPagesDeploymentInfo(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe", handler)
 
-	actual, err := client.GetPagesDeploymentInfo(context.Background(), GetPagesDeploymentInfoParams{
-		AccountID:    testAccountID,
-		ProjectName:  "test",
-		DeploymentID: "0012e50b-fa5d-44db-8cb5-1f372785dcbe",
-	})
+	actual, err := client.GetPagesDeploymentInfo(context.Background(), AccountIdentifier(testAccountID), "test", "0012e50b-fa5d-44db-8cb5-1f372785dcbe")
 	if assert.NoError(t, err) {
 		assert.Equal(t, *expectedPagesDeployment, actual)
 	}
@@ -434,8 +429,7 @@ func TestGetPagesDeploymentStageLogs(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe/history/build/logs", handler)
 
-	actual, err := client.GetPagesDeploymentStageLogs(context.Background(), GetPagesDeploymentStageLogsParams{
-		AccountID:    testAccountID,
+	actual, err := client.GetPagesDeploymentStageLogs(context.Background(), AccountIdentifier(testAccountID), GetPagesDeploymentStageLogsParams{
 		ProjectName:  "test",
 		DeploymentID: "0012e50b-fa5d-44db-8cb5-1f372785dcbe",
 		StageName:    "build",
@@ -464,8 +458,7 @@ func TestGetPagesDeploymentLogs(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe/history/logs", handler)
 
-	actual, err := client.GetPagesDeploymentLogs(context.Background(), GetPagesDeploymentLogsParams{
-		AccountID:    testAccountID,
+	actual, err := client.GetPagesDeploymentLogs(context.Background(), AccountIdentifier(testAccountID), GetPagesDeploymentLogsParams{
 		ProjectName:  "test",
 		DeploymentID: "0012e50b-fa5d-44db-8cb5-1f372785dcbe",
 		SizeOptions:  SizeOptions{},
@@ -493,11 +486,7 @@ func TestDeletePagesDeployment(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe", handler)
 
-	err := client.DeletePagesDeployment(context.Background(), DeletePagesDeploymentParams{
-		AccountID:    testAccountID,
-		ProjectName:  "test",
-		DeploymentID: "0012e50b-fa5d-44db-8cb5-1f372785dcbe",
-	})
+	err := client.DeletePagesDeployment(context.Background(), AccountIdentifier(testAccountID), "test", "0012e50b-fa5d-44db-8cb5-1f372785dcbe")
 	assert.NoError(t, err)
 }
 
@@ -519,8 +508,7 @@ func TestCreatePagesDeployment(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments", handler)
 
-	actual, err := client.CreatePagesDeployment(context.Background(), CreatePagesDeploymentParams{
-		AccountID:   testAccountID,
+	actual, err := client.CreatePagesDeployment(context.Background(), AccountIdentifier(testAccountID), CreatePagesDeploymentParams{
 		ProjectName: "test",
 	})
 
@@ -547,11 +535,7 @@ func TestRetryPagesDeployment(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe/retry", handler)
 
-	actual, err := client.RetryPagesDeployment(context.Background(), RetryPagesDeploymentParams{
-		AccountID:    testAccountID,
-		ProjectName:  "test",
-		DeploymentID: "0012e50b-fa5d-44db-8cb5-1f372785dcbe",
-	})
+	actual, err := client.RetryPagesDeployment(context.Background(), AccountIdentifier(testAccountID), "test", "0012e50b-fa5d-44db-8cb5-1f372785dcbe")
 	if assert.NoError(t, err) {
 		assert.Equal(t, *expectedPagesDeployment, actual)
 	}
@@ -575,11 +559,7 @@ func TestRollbackPagesDeployment(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/pages/projects/test/deployments/0012e50b-fa5d-44db-8cb5-1f372785dcbe/rollback", handler)
 
-	actual, err := client.RollbackPagesDeployment(context.Background(), RollbackPagesDeploymentParams{
-		AccountID:    testAccountID,
-		ProjectName:  "test",
-		DeploymentID: "0012e50b-fa5d-44db-8cb5-1f372785dcbe",
-	})
+	actual, err := client.RollbackPagesDeployment(context.Background(), AccountIdentifier(testAccountID), "test", "0012e50b-fa5d-44db-8cb5-1f372785dcbe")
 	if assert.NoError(t, err) {
 		assert.Equal(t, *expectedPagesDeployment, actual)
 	}
diff --git a/tunnel_routes_test.go b/tunnel_routes_test.go
index df6174a42..81ab39e2d 100644
--- a/tunnel_routes_test.go
+++ b/tunnel_routes_test.go
@@ -51,8 +51,8 @@ func TestListTunnelRoutes(t *testing.T) {
 		},
 	}
 
-	params := TunnelRoutesListParams{AccountID: testAccountID}
-	got, err := client.ListTunnelRoutes(context.Background(), params)
+	params := TunnelRoutesListParams{}
+	got, err := client.ListTunnelRoutes(context.Background(), AccountIdentifier(testAccountID), params)
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, got)
@@ -95,7 +95,7 @@ func TestTunnelRouteForIP(t *testing.T) {
 		VirtualNetworkID: "9f322de4-5988-4945-b770-f1d6ac200f86",
 	}
 
-	got, err := client.GetTunnelRouteForIP(context.Background(), TunnelRoutesForIPParams{AccountID: testAccountID, Network: "10.1.0.137"})
+	got, err := client.GetTunnelRouteForIP(context.Background(), AccountIdentifier(testAccountID), TunnelRoutesForIPParams{Network: "10.1.0.137"})
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, got)
@@ -138,7 +138,7 @@ func TestCreateTunnelRoute(t *testing.T) {
 		VirtualNetworkID: "9f322de4-5988-4945-b770-f1d6ac200f86",
 	}
 
-	tunnel, err := client.CreateTunnelRoute(context.Background(), TunnelRoutesCreateParams{AccountID: testAccountID, TunnelID: testTunnelID, Network: "10.0.0.0/16", Comment: "foo", VirtualNetworkID: "9f322de4-5988-4945-b770-f1d6ac200f86"})
+	tunnel, err := client.CreateTunnelRoute(context.Background(), AccountIdentifier(testAccountID), TunnelRoutesCreateParams{TunnelID: testTunnelID, Network: "10.0.0.0/16", Comment: "foo", VirtualNetworkID: "9f322de4-5988-4945-b770-f1d6ac200f86"})
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, tunnel)
 	}
@@ -185,7 +185,7 @@ func TestUpdateTunnelRoute(t *testing.T) {
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/teamnet/routes/network/10.0.0.0/16", handler)
-	tunnel, err := client.UpdateTunnelRoute(context.Background(), TunnelRoutesUpdateParams{AccountID: testAccountID, TunnelID: testTunnelID, Network: "10.0.0.0/16", Comment: "foo", VirtualNetworkID: "9f322de4-5988-4945-b770-f1d6ac200f86"})
+	tunnel, err := client.UpdateTunnelRoute(context.Background(), AccountIdentifier(testAccountID), TunnelRoutesUpdateParams{TunnelID: testTunnelID, Network: "10.0.0.0/16", Comment: "foo", VirtualNetworkID: "9f322de4-5988-4945-b770-f1d6ac200f86"})
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, tunnel)
@@ -217,6 +217,6 @@ func TestDeleteTunnelRoute(t *testing.T) {
 	}
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/teamnet/routes/network/10.0.0.0/16", handler)
-	err := client.DeleteTunnelRoute(context.Background(), TunnelRoutesDeleteParams{AccountID: testAccountID, Network: "10.0.0.0/16", VirtualNetworkID: "9f322de4-5988-4945-b770-f1d6ac200f86"})
+	err := client.DeleteTunnelRoute(context.Background(), AccountIdentifier(testAccountID), TunnelRoutesDeleteParams{Network: "10.0.0.0/16", VirtualNetworkID: "9f322de4-5988-4945-b770-f1d6ac200f86"})
 	assert.NoError(t, err)
 }
diff --git a/tunnel_test.go b/tunnel_test.go
index 7db030165..9fa6089cc 100644
--- a/tunnel_test.go
+++ b/tunnel_test.go
@@ -64,7 +64,7 @@ func TestTunnels(t *testing.T) {
 		}},
 	}}
 
-	actual, err := client.Tunnels(context.Background(), TunnelListParams{AccountID: testAccountID, UUID: "f174e90a-fafe-4643-bbbc-4a0ed4fc8415"})
+	actual, err := client.Tunnels(context.Background(), AccountIdentifier(testAccountID), TunnelListParams{UUID: "f174e90a-fafe-4643-bbbc-4a0ed4fc8415"})
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
@@ -123,7 +123,7 @@ func TestTunnel(t *testing.T) {
 		}},
 	}
 
-	actual, err := client.Tunnel(context.Background(), TunnelParams{AccountID: testAccountID, ID: "f174e90a-fafe-4643-bbbc-4a0ed4fc8415"})
+	actual, err := client.Tunnel(context.Background(), AccountIdentifier(testAccountID), "f174e90a-fafe-4643-bbbc-4a0ed4fc8415")
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
@@ -182,7 +182,7 @@ func TestCreateTunnel(t *testing.T) {
 		}},
 	}
 
-	actual, err := client.CreateTunnel(context.Background(), TunnelCreateParams{AccountID: testAccountID, Name: "blog", Secret: "notarealsecret"})
+	actual, err := client.CreateTunnel(context.Background(), AccountIdentifier(testAccountID), TunnelCreateParams{Name: "blog", Secret: "notarealsecret"})
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
@@ -232,9 +232,8 @@ func TestUpdateTunnelConfiguration(t *testing.T) {
 			},
 		}}
 
-	actual, err := client.UpdateTunnelConfiguration(context.Background(), TunnelConfigurationParams{
-		AccountID: testAccountID,
-		TunnelID:  "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+	actual, err := client.UpdateTunnelConfiguration(context.Background(), AccountIdentifier(testAccountID), TunnelConfigurationParams{
+		TunnelID: "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
 		Config: TunnelConfiguration{
 			Ingress: []UnvalidatedIngressRule{
 				{
@@ -302,7 +301,7 @@ func TestGetTunnelConfiguration(t *testing.T) {
 			},
 		}}
 
-	actual, err := client.GetTunnelConfiguration(context.Background(), GetTunnelConfigurationParams{AccountID: testAccountID, TunnelID: "f174e90a-fafe-4643-bbbc-4a0ed4fc8415"})
+	actual, err := client.GetTunnelConfiguration(context.Background(), AccountIdentifier(testAccountID), "f174e90a-fafe-4643-bbbc-4a0ed4fc8415")
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, actual)
@@ -343,7 +342,7 @@ func TestDeleteTunnel(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/cfd_tunnel/f174e90a-fafe-4643-bbbc-4a0ed4fc8415", handler)
 
-	err := client.DeleteTunnel(context.Background(), TunnelDeleteParams{AccountID: testAccountID, ID: "f174e90a-fafe-4643-bbbc-4a0ed4fc8415"})
+	err := client.DeleteTunnel(context.Background(), AccountIdentifier(testAccountID), "f174e90a-fafe-4643-bbbc-4a0ed4fc8415")
 	assert.NoError(t, err)
 }
 
@@ -364,7 +363,7 @@ func TestCleanupTunnelConnections(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/cfd_tunnel/f174e90a-fafe-4643-bbbc-4a0ed4fc8415/connections", handler)
 
-	err := client.CleanupTunnelConnections(context.Background(), TunnelCleanupParams{AccountID: testAccountID, ID: "f174e90a-fafe-4643-bbbc-4a0ed4fc8415"})
+	err := client.CleanupTunnelConnections(context.Background(), AccountIdentifier(testAccountID), "f174e90a-fafe-4643-bbbc-4a0ed4fc8415")
 	assert.NoError(t, err)
 }
 
@@ -386,7 +385,7 @@ func TestTunnelToken(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/cfd_tunnel/f174e90a-fafe-4643-bbbc-4a0ed4fc8415/token", handler)
 
-	token, err := client.TunnelToken(context.Background(), TunnelTokenParams{AccountID: testAccountID, ID: "f174e90a-fafe-4643-bbbc-4a0ed4fc8415"})
+	token, err := client.TunnelToken(context.Background(), AccountIdentifier(testAccountID), "f174e90a-fafe-4643-bbbc-4a0ed4fc8415")
 	assert.NoError(t, err)
 	assert.Equal(t, "ZHNraGdhc2RraGFza2hqZGFza2poZGFza2poYXNrZGpoYWtzamRoa2FzZGpoa2FzamRoa2Rhc2po\na2FzamRoa2FqCg==", token)
 }
diff --git a/tunnel_virtual_networks_test.go b/tunnel_virtual_networks_test.go
index d1f700d92..91818aa4e 100644
--- a/tunnel_virtual_networks_test.go
+++ b/tunnel_virtual_networks_test.go
@@ -50,8 +50,7 @@ func TestTunnelVirtualNetworks(t *testing.T) {
 		},
 	}
 
-	params := TunnelVirtualNetworksListParams{AccountID: testAccountID}
-	got, err := client.ListTunnelVirtualNetworks(context.Background(), params)
+	got, err := client.ListTunnelVirtualNetworks(context.Background(), AccountIdentifier(testAccountID), TunnelVirtualNetworksListParams{})
 
 	if assert.NoError(t, err) {
 		assert.Equal(t, want, got)
@@ -92,8 +91,7 @@ func TestCreateTunnelVirtualNetwork(t *testing.T) {
 		DeletedAt:        &ts,
 	}
 
-	tunnel, err := client.CreateTunnelVirtualNetwork(context.Background(), TunnelVirtualNetworkCreateParams{
-		AccountID: testAccountID,
+	tunnel, err := client.CreateTunnelVirtualNetwork(context.Background(), AccountIdentifier(testAccountID), TunnelVirtualNetworkCreateParams{
 		Name:      "us-east-1-vpc",
 		IsDefault: true,
 		Comment:   "Staging VPC for data science",
@@ -144,8 +142,7 @@ func TestUpdateTunnelVirtualNetwork(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/teamnet/virtual_networks/f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", handler)
 
-	tunnel, err := client.UpdateTunnelVirtualNetwork(context.Background(), TunnelVirtualNetworkUpdateParams{
-		AccountID:        testAccountID,
+	tunnel, err := client.UpdateTunnelVirtualNetwork(context.Background(), AccountIdentifier(testAccountID), TunnelVirtualNetworkUpdateParams{
 		VnetID:           "f70ff985-a4ef-4643-bbbc-4a0ed4fc8415",
 		Name:             "us-east-1-vpc",
 		IsDefaultNetwork: BoolPtr(true),
@@ -182,10 +179,7 @@ func TestDeleteTunnelVirtualNetwork(t *testing.T) {
 
 	mux.HandleFunc("/accounts/"+testAccountID+"/teamnet/virtual_networks/f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", handler)
 
-	err := client.DeleteTunnelVirtualNetwork(context.Background(), TunnelVirtualNetworkDeleteParams{
-		AccountID: testAccountID,
-		VnetID:    "f70ff985-a4ef-4643-bbbc-4a0ed4fc8415",
-	})
+	err := client.DeleteTunnelVirtualNetwork(context.Background(), AccountIdentifier(testAccountID), "f70ff985-a4ef-4643-bbbc-4a0ed4fc8415")
 
 	assert.NoError(t, err)
 }