Repository: honeycombio/terraform-provider-honeycombio
Pull request #416 (2023-12-21 13:57:24)

refactor(client) - testsuite and constructor improvements
This moves the embedded client's test suite into the package `client_test` and enforces a fully external test of the client. A few functional changes needed to happen to make this possible, but it felt like a cleaner way to test the client given it's intended purpose.

A breaking change is included in this refactor: `client.NewClient` now takes no arguments and creates a client with the default configuration values, while `client.NewClientWithConfig` has been added to allow passing a custom configuration.

This felt a bit more standard (and less awkward), and will only affect other projects pulling in the client package.

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/honeycombio/terraform-provider-honeycombio/pull/416?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=honeycombio) Report
Attention: `2 lines` in your changes are missing coverage. Please review.
> Comparison is base [(`b08c6ec`)](https://app.codecov.io/gh/honeycombio/terraform-provider-honeycombio/commit/b08c6ec39b6819bd2bef10650483e011aa9fd3fc?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=honeycombio) 81.01% compared to head [(`5ee541a`)](https://app.codecov.io/gh/honeycombio/terraform-provider-honeycombio/pull/416?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=honeycombio) 80.98%.

| [Files](https://app.codecov.io/gh/honeycombio/terraform-provider-honeycombio/pull/416?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=honeycombio) | Patch % | Lines |
|---|---|---|
| [client/client.go](https://app.codecov.io/gh/honeycombio/terraform-provider-honeycombio/pull/416?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=honeycombio#diff-Y2xpZW50L2NsaWVudC5nbw==) | 66.66% | [2 Missing :warning: ](https://app.codecov.io/gh/honeycombio/terraform-provider-honeycombio/pull/416?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=honeycombio) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #416      +/-   ##
==========================================
- Coverage   81.01%   80.98%   -0.03%     
==========================================
  Files          62       62              
  Lines        4840     4844       +4     
==========================================
+ Hits         3921     3923       +2     
- Misses        763      765       +2     
  Partials      156      156              
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/honeycombio/terraform-provider-honeycombio/pull/416?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=honeycombio).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=honeycombio).


Patch:
diff --git a/client/auth.go b/client/auth.go
index e39455e..dc01507 100644
--- a/client/auth.go
+++ b/client/auth.go
@@ -48,6 +48,6 @@ type AuthMetadata struct {
 
 func (s *auth) List(ctx context.Context) (AuthMetadata, error) {
 	var r AuthMetadata
-	err := s.client.performRequest(ctx, "GET", "/1/auth", nil, &r)
+	err := s.client.Do(ctx, "GET", "/1/auth", nil, &r)
 	return r, err
 }
diff --git a/client/board.go b/client/board.go
index c638c5c..80d5c48 100644
--- a/client/board.go
+++ b/client/board.go
@@ -128,28 +128,28 @@ func BoardQueryStyles() []BoardQueryStyle {
 
 func (s *boards) List(ctx context.Context) ([]Board, error) {
 	var b []Board
-	err := s.client.performRequest(ctx, "GET", "/1/boards", nil, &b)
+	err := s.client.Do(ctx, "GET", "/1/boards", nil, &b)
 	return b, err
 }
 
 func (s *boards) Get(ctx context.Context, ID string) (*Board, error) {
 	var b Board
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/boards/%s", ID), nil, &b)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/boards/%s", ID), nil, &b)
 	return &b, err
 }
 
 func (s *boards) Create(ctx context.Context, data *Board) (*Board, error) {
 	var b Board
-	err := s.client.performRequest(ctx, "POST", "/1/boards", data, &b)
+	err := s.client.Do(ctx, "POST", "/1/boards", data, &b)
 	return &b, err
 }
 
 func (s *boards) Update(ctx context.Context, data *Board) (*Board, error) {
 	var b Board
-	err := s.client.performRequest(ctx, "PUT", fmt.Sprintf("/1/boards/%s", data.ID), data, &b)
+	err := s.client.Do(ctx, "PUT", fmt.Sprintf("/1/boards/%s", data.ID), data, &b)
 	return &b, err
 }
 
 func (s *boards) Delete(ctx context.Context, id string) error {
-	return s.client.performRequest(ctx, "DELETE", fmt.Sprintf("/1/boards/%s", id), nil, nil)
+	return s.client.Do(ctx, "DELETE", fmt.Sprintf("/1/boards/%s", id), nil, nil)
 }
diff --git a/client/burn_alert.go b/client/burn_alert.go
index c6b0ce7..80bb20f 100644
--- a/client/burn_alert.go
+++ b/client/burn_alert.go
@@ -42,7 +42,7 @@ type SLORef struct {
 
 type BurnAlert struct {
 	ID                                    string                  `json:"id,omitempty"`
-	AlertType                             string                  `json:"alert_type"`
+	AlertType                             BurnAlertAlertType      `json:"alert_type"`
 	ExhaustionMinutes                     *int                    `json:"exhaustion_minutes,omitempty"`
 	BudgetRateWindowMinutes               *int                    `json:"budget_rate_window_minutes,omitempty"`
 	BudgetRateDecreaseThresholdPerMillion *int                    `json:"budget_rate_decrease_threshold_per_million,omitempty"`
@@ -70,28 +70,28 @@ func BurnAlertAlertTypes() []BurnAlertAlertType {
 
 func (s *burnalerts) ListForSLO(ctx context.Context, dataset string, sloId string) ([]BurnAlert, error) {
 	var b []BurnAlert
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/burn_alerts/%s?slo_id=%s", urlEncodeDataset(dataset), url.QueryEscape(sloId)), nil, &b)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/burn_alerts/%s?slo_id=%s", urlEncodeDataset(dataset), url.QueryEscape(sloId)), nil, &b)
 	return b, err
 }
 
 func (s *burnalerts) Get(ctx context.Context, dataset string, id string) (*BurnAlert, error) {
 	var b BurnAlert
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/burn_alerts/%s/%s", urlEncodeDataset(dataset), id), nil, &b)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/burn_alerts/%s/%s", urlEncodeDataset(dataset), id), nil, &b)
 	return &b, err
 }
 
 func (s *burnalerts) Create(ctx context.Context, dataset string, data *BurnAlert) (*BurnAlert, error) {
 	var b BurnAlert
-	err := s.client.performRequest(ctx, "POST", fmt.Sprintf("/1/burn_alerts/%s", urlEncodeDataset(dataset)), data, &b)
+	err := s.client.Do(ctx, "POST", fmt.Sprintf("/1/burn_alerts/%s", urlEncodeDataset(dataset)), data, &b)
 	return &b, err
 }
 
 func (s *burnalerts) Update(ctx context.Context, dataset string, data *BurnAlert) (*BurnAlert, error) {
 	var b BurnAlert
-	err := s.client.performRequest(ctx, "PUT", fmt.Sprintf("/1/burn_alerts/%s/%s", urlEncodeDataset(dataset), data.ID), data, &b)
+	err := s.client.Do(ctx, "PUT", fmt.Sprintf("/1/burn_alerts/%s/%s", urlEncodeDataset(dataset), data.ID), data, &b)
 	return &b, err
 }
 
 func (s *burnalerts) Delete(ctx context.Context, dataset string, id string) error {
-	return s.client.performRequest(ctx, "DELETE", fmt.Sprintf("/1/burn_alerts/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
+	return s.client.Do(ctx, "DELETE", fmt.Sprintf("/1/burn_alerts/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
 }
diff --git a/client/client.go b/client/client.go
index 25e0806..4e6e92b 100644
--- a/client/client.go
+++ b/client/client.go
@@ -68,6 +68,7 @@ type Client struct {
 	Recipients         Recipients
 }
 
+// DefaultConfig returns a Config initilized with default values.
 func DefaultConfig() *Config {
 	c := &Config{
 		APIKey:     os.Getenv(DefaultAPIKeyEnv),
@@ -89,8 +90,14 @@ func DefaultConfig() *Config {
 	return c
 }
 
-// NewClient creates a new Honeycomb API client.
-func NewClient(config *Config) (*Client, error) {
+// NewClient creates a new Honeycomb API client with default settings.
+func NewClient() (*Client, error) {
+	return NewClientWithConfig(DefaultConfig())
+}
+
+// NewClientWithConfig creates a new Honeycomb API client using the provided
+// Config.
+func NewClientWithConfig(config *Config) (*Client, error) {
 	cfg := DefaultConfig()
 
 	if config.APIKey != "" {
@@ -161,6 +168,11 @@ func NewClient(config *Config) (*Client, error) {
 	return client, nil
 }
 
+// EndpointURL returns the Client's configured API endpoint URL
+func (c *Client) EndpointURL() *url.URL {
+	return c.apiURL
+}
+
 // IsClassic returns true if the client is configured with a Classic API Key
 //
 // If there is an error fetching the auth metadata, this will return false.
@@ -172,14 +184,14 @@ func (c *Client) IsClassic(ctx context.Context) bool {
 	return metadata.Environment.Slug == ""
 }
 
-// performRequest makes a request to the Honeycomb API and, if
-// requestBody is not nil, a JSON body.
+// Do makes a request to the configured Honeycomb API endpoint
+// and, if requestBody is not nil, sends along the JSON.
 //
 // The response is parsed in responseBody, if responseBody is not nil.
 //
 // Attemps to return a DetailedError if the response status code is not 2xx,
 // but can return a generic error.
-func (c *Client) performRequest(ctx context.Context, method, path string, requestBody, responseBody interface{}) error {
+func (c *Client) Do(ctx context.Context, method, path string, requestBody, responseBody interface{}) error {
 	var body io.Reader
 
 	if requestBody != nil {
diff --git a/client/column.go b/client/column.go
index 6b1b829..4d20b69 100644
--- a/client/column.go
+++ b/client/column.go
@@ -86,34 +86,34 @@ func ColumnTypes() []ColumnType {
 
 func (s *columns) List(ctx context.Context, dataset string) ([]Column, error) {
 	var c []Column
-	err := s.client.performRequest(ctx, "GET", "/1/columns/"+urlEncodeDataset(dataset), nil, &c)
+	err := s.client.Do(ctx, "GET", "/1/columns/"+urlEncodeDataset(dataset), nil, &c)
 	return c, err
 }
 
 func (s *columns) Get(ctx context.Context, dataset string, id string) (*Column, error) {
 	var c Column
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/columns/%s/%s", urlEncodeDataset(dataset), id), nil, &c)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/columns/%s/%s", urlEncodeDataset(dataset), id), nil, &c)
 	return &c, err
 }
 
 func (s *columns) GetByKeyName(ctx context.Context, dataset string, keyName string) (*Column, error) {
 	var c Column
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/columns/%s?key_name=%s", urlEncodeDataset(dataset), url.QueryEscape(keyName)), nil, &c)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/columns/%s?key_name=%s", urlEncodeDataset(dataset), url.QueryEscape(keyName)), nil, &c)
 	return &c, err
 }
 
 func (s *columns) Create(ctx context.Context, dataset string, data *Column) (*Column, error) {
 	var c Column
-	err := s.client.performRequest(ctx, "POST", "/1/columns/"+urlEncodeDataset(dataset), data, &c)
+	err := s.client.Do(ctx, "POST", "/1/columns/"+urlEncodeDataset(dataset), data, &c)
 	return &c, err
 }
 
 func (s *columns) Update(ctx context.Context, dataset string, data *Column) (*Column, error) {
 	var c Column
-	err := s.client.performRequest(ctx, "PUT", fmt.Sprintf("/1/columns/%s/%s", urlEncodeDataset(dataset), data.ID), data, &c)
+	err := s.client.Do(ctx, "PUT", fmt.Sprintf("/1/columns/%s/%s", urlEncodeDataset(dataset), data.ID), data, &c)
 	return &c, err
 }
 
 func (s *columns) Delete(ctx context.Context, dataset string, id string) error {
-	return s.client.performRequest(ctx, "DELETE", fmt.Sprintf("/1/columns/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
+	return s.client.Do(ctx, "DELETE", fmt.Sprintf("/1/columns/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
 }
diff --git a/client/dataset.go b/client/dataset.go
index c928885..eaf6242 100644
--- a/client/dataset.go
+++ b/client/dataset.go
@@ -49,24 +49,24 @@ type Dataset struct {
 
 func (s datasets) List(ctx context.Context) ([]Dataset, error) {
 	var datasets []Dataset
-	err := s.client.performRequest(ctx, "GET", "/1/datasets", nil, &datasets)
+	err := s.client.Do(ctx, "GET", "/1/datasets", nil, &datasets)
 	return datasets, err
 }
 
 func (s datasets) Get(ctx context.Context, slug string) (*Dataset, error) {
 	var dataset Dataset
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/datasets/%s", urlEncodeDataset(slug)), nil, &dataset)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/datasets/%s", urlEncodeDataset(slug)), nil, &dataset)
 	return &dataset, err
 }
 
 func (s datasets) Create(ctx context.Context, data *Dataset) (*Dataset, error) {
 	var dataset Dataset
-	err := s.client.performRequest(ctx, "POST", "/1/datasets", data, &dataset)
+	err := s.client.Do(ctx, "POST", "/1/datasets", data, &dataset)
 	return &dataset, err
 }
 
 func (s datasets) Update(ctx context.Context, data *Dataset) (*Dataset, error) {
 	var dataset Dataset
-	err := s.client.performRequest(ctx, "PUT", fmt.Sprintf("/1/datasets/%s", urlEncodeDataset(data.Name)), data, &dataset)
+	err := s.client.Do(ctx, "PUT", fmt.Sprintf("/1/datasets/%s", urlEncodeDataset(data.Name)), data, &dataset)
 	return &dataset, err
 }
diff --git a/client/dataset_definitions.go b/client/dataset_definitions.go
index 81385fe..6c415bd 100644
--- a/client/dataset_definitions.go
+++ b/client/dataset_definitions.go
@@ -100,7 +100,7 @@ func DatasetDefinitionDefaults() map[string][]string {
 
 func (s *datasetDefinitions) Get(ctx context.Context, dataset string) (*DatasetDefinition, error) {
 	var result DatasetDefinition
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/dataset_definitions/%s", urlEncodeDataset(dataset)), nil, &result)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/dataset_definitions/%s", urlEncodeDataset(dataset)), nil, &result)
 	return &result, err
 }
 
@@ -122,11 +122,11 @@ func (s *datasetDefinitions) ResetAll(ctx context.Context, dataset string) error
 		User:           EmptyDatasetDefinition(),
 	}
 
-	return s.client.performRequest(ctx, "PATCH", fmt.Sprintf("/1/dataset_definitions/%s", urlEncodeDataset(dataset)), emptyDefinitions, nil)
+	return s.client.Do(ctx, "PATCH", fmt.Sprintf("/1/dataset_definitions/%s", urlEncodeDataset(dataset)), emptyDefinitions, nil)
 }
 
 func (s *datasetDefinitions) Update(ctx context.Context, dataset string, d *DatasetDefinition) (*DatasetDefinition, error) {
 	var result DatasetDefinition
-	err := s.client.performRequest(ctx, "PATCH", fmt.Sprintf("/1/dataset_definitions/%s", urlEncodeDataset(dataset)), d, &result)
+	err := s.client.Do(ctx, "PATCH", fmt.Sprintf("/1/dataset_definitions/%s", urlEncodeDataset(dataset)), d, &result)
 	return &result, err
 }
diff --git a/client/derived_column.go b/client/derived_column.go
index b6539cd..5c34db4 100644
--- a/client/derived_column.go
+++ b/client/derived_column.go
@@ -57,34 +57,34 @@ type DerivedColumn struct {
 
 func (s *derivedColumns) List(ctx context.Context, dataset string) ([]DerivedColumn, error) {
 	var c []DerivedColumn
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/derived_columns/%s", urlEncodeDataset(dataset)), nil, &c)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/derived_columns/%s", urlEncodeDataset(dataset)), nil, &c)
 	return c, err
 }
 
 func (s *derivedColumns) Get(ctx context.Context, dataset string, id string) (*DerivedColumn, error) {
 	var c DerivedColumn
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/derived_columns/%s/%s", urlEncodeDataset(dataset), id), nil, &c)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/derived_columns/%s/%s", urlEncodeDataset(dataset), id), nil, &c)
 	return &c, err
 }
 
 func (s *derivedColumns) GetByAlias(ctx context.Context, dataset string, alias string) (*DerivedColumn, error) {
 	var c DerivedColumn
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/derived_columns/%s?alias=%s", urlEncodeDataset(dataset), url.QueryEscape(alias)), nil, &c)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/derived_columns/%s?alias=%s", urlEncodeDataset(dataset), url.QueryEscape(alias)), nil, &c)
 	return &c, err
 }
 
 func (s *derivedColumns) Create(ctx context.Context, dataset string, data *DerivedColumn) (*DerivedColumn, error) {
 	var d DerivedColumn
-	err := s.client.performRequest(ctx, "POST", fmt.Sprintf("/1/derived_columns/%s", urlEncodeDataset(dataset)), data, &d)
+	err := s.client.Do(ctx, "POST", fmt.Sprintf("/1/derived_columns/%s", urlEncodeDataset(dataset)), data, &d)
 	return &d, err
 }
 
 func (s *derivedColumns) Update(ctx context.Context, dataset string, data *DerivedColumn) (*DerivedColumn, error) {
 	var d DerivedColumn
-	err := s.client.performRequest(ctx, "PUT", fmt.Sprintf("/1/derived_columns/%s/%s", urlEncodeDataset(dataset), data.ID), data, &d)
+	err := s.client.Do(ctx, "PUT", fmt.Sprintf("/1/derived_columns/%s/%s", urlEncodeDataset(dataset), data.ID), data, &d)
 	return &d, err
 }
 
 func (s *derivedColumns) Delete(ctx context.Context, dataset string, id string) error {
-	return s.client.performRequest(ctx, "DELETE", fmt.Sprintf("/1/derived_columns/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
+	return s.client.Do(ctx, "DELETE", fmt.Sprintf("/1/derived_columns/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
 }
diff --git a/client/marker.go b/client/marker.go
index 88fcf8c..7016d38 100644
--- a/client/marker.go
+++ b/client/marker.go
@@ -73,7 +73,7 @@ type Marker struct {
 
 func (s *markers) List(ctx context.Context, dataset string) ([]Marker, error) {
 	var m []Marker
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/markers/%s", urlEncodeDataset(dataset)), nil, &m)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/markers/%s", urlEncodeDataset(dataset)), nil, &m)
 	return m, err
 }
 
@@ -96,16 +96,16 @@ func (s *markers) Get(ctx context.Context, dataset string, id string) (*Marker,
 
 func (s *markers) Create(ctx context.Context, dataset string, data *Marker) (*Marker, error) {
 	var m Marker
-	err := s.client.performRequest(ctx, "POST", fmt.Sprintf("/1/markers/%s", urlEncodeDataset(dataset)), data, &m)
+	err := s.client.Do(ctx, "POST", fmt.Sprintf("/1/markers/%s", urlEncodeDataset(dataset)), data, &m)
 	return &m, err
 }
 
 func (s *markers) Update(ctx context.Context, dataset string, data *Marker) (*Marker, error) {
 	var m Marker
-	err := s.client.performRequest(ctx, "PUT", fmt.Sprintf("/1/markers/%s/%s", urlEncodeDataset(dataset), data.ID), data, &m)
+	err := s.client.Do(ctx, "PUT", fmt.Sprintf("/1/markers/%s/%s", urlEncodeDataset(dataset), data.ID), data, &m)
 	return &m, err
 }
 
 func (s *markers) Delete(ctx context.Context, dataset string, id string) error {
-	return s.client.performRequest(ctx, "DELETE", fmt.Sprintf("/1/markers/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
+	return s.client.Do(ctx, "DELETE", fmt.Sprintf("/1/markers/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
 }
diff --git a/client/marker_settings.go b/client/marker_settings.go
index b148a09..df7781b 100644
--- a/client/marker_settings.go
+++ b/client/marker_settings.go
@@ -60,7 +60,7 @@ type MarkerSetting struct {
 
 func (s *markerSettings) List(ctx context.Context, dataset string) ([]MarkerSetting, error) {
 	var m []MarkerSetting
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/marker_settings/%s", urlEncodeDataset(dataset)), nil, &m)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/marker_settings/%s", urlEncodeDataset(dataset)), nil, &m)
 	return m, err
 }
 
@@ -83,16 +83,16 @@ func (s *markerSettings) Get(ctx context.Context, dataset string, id string) (*M
 
 func (s *markerSettings) Create(ctx context.Context, dataset string, data *MarkerSetting) (*MarkerSetting, error) {
 	var m MarkerSetting
-	err := s.client.performRequest(ctx, "POST", fmt.Sprintf("/1/marker_settings/%s", urlEncodeDataset(dataset)), data, &m)
+	err := s.client.Do(ctx, "POST", fmt.Sprintf("/1/marker_settings/%s", urlEncodeDataset(dataset)), data, &m)
 	return &m, err
 }
 
 func (s *markerSettings) Update(ctx context.Context, dataset string, data *MarkerSetting) (*MarkerSetting, error) {
 	var m MarkerSetting
-	err := s.client.performRequest(ctx, "PUT", fmt.Sprintf("/1/marker_settings/%s/%s", urlEncodeDataset(dataset), data.ID), data, &m)
+	err := s.client.Do(ctx, "PUT", fmt.Sprintf("/1/marker_settings/%s/%s", urlEncodeDataset(dataset), data.ID), data, &m)
 	return &m, err
 }
 
 func (s *markerSettings) Delete(ctx context.Context, dataset string, id string) error {
-	return s.client.performRequest(ctx, "DELETE", fmt.Sprintf("/1/marker_settings/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
+	return s.client.Do(ctx, "DELETE", fmt.Sprintf("/1/marker_settings/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
 }
diff --git a/client/query.go b/client/query.go
index 513feb5..5312064 100644
--- a/client/query.go
+++ b/client/query.go
@@ -28,12 +28,12 @@ var _ Queries = (*queries)(nil)
 
 func (s *queries) Get(ctx context.Context, dataset string, id string) (*QuerySpec, error) {
 	var q QuerySpec
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/queries/%s/%s", urlEncodeDataset(dataset), id), nil, &q)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/queries/%s/%s", urlEncodeDataset(dataset), id), nil, &q)
 	return &q, err
 }
 
 func (s *queries) Create(ctx context.Context, dataset string, data *QuerySpec) (*QuerySpec, error) {
 	var q QuerySpec
-	err := s.client.performRequest(ctx, "POST", "/1/queries/"+urlEncodeDataset(dataset), data, &q)
+	err := s.client.Do(ctx, "POST", "/1/queries/"+urlEncodeDataset(dataset), data, &q)
 	return &q, err
 }
diff --git a/client/query_annotation.go b/client/query_annotation.go
index 11bffc3..1c8ea46 100644
--- a/client/query_annotation.go
+++ b/client/query_annotation.go
@@ -52,28 +52,28 @@ type QueryAnnotation struct {
 
 func (s *queryAnnotations) List(ctx context.Context, dataset string) ([]QueryAnnotation, error) {
 	var q []QueryAnnotation
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/query_annotations/%s", urlEncodeDataset(dataset)), nil, &q)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/query_annotations/%s", urlEncodeDataset(dataset)), nil, &q)
 	return q, err
 }
 
 func (s *queryAnnotations) Get(ctx context.Context, dataset string, ID string) (*QueryAnnotation, error) {
 	var q QueryAnnotation
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/query_annotations/%s/%s", urlEncodeDataset(dataset), ID), nil, &q)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/query_annotations/%s/%s", urlEncodeDataset(dataset), ID), nil, &q)
 	return &q, err
 }
 
 func (s *queryAnnotations) Create(ctx context.Context, dataset string, data *QueryAnnotation) (*QueryAnnotation, error) {
 	var q QueryAnnotation
-	err := s.client.performRequest(ctx, "POST", fmt.Sprintf("/1/query_annotations/%s", urlEncodeDataset(dataset)), data, &q)
+	err := s.client.Do(ctx, "POST", fmt.Sprintf("/1/query_annotations/%s", urlEncodeDataset(dataset)), data, &q)
 	return &q, err
 }
 
 func (s *queryAnnotations) Update(ctx context.Context, dataset string, data *QueryAnnotation) (*QueryAnnotation, error) {
 	var q QueryAnnotation
-	err := s.client.performRequest(ctx, "PUT", fmt.Sprintf("/1/query_annotations/%s/%s", urlEncodeDataset(dataset), data.ID), data, &q)
+	err := s.client.Do(ctx, "PUT", fmt.Sprintf("/1/query_annotations/%s/%s", urlEncodeDataset(dataset), data.ID), data, &q)
 	return &q, err
 }
 
 func (s *queryAnnotations) Delete(ctx context.Context, dataset string, id string) error {
-	return s.client.performRequest(ctx, "DELETE", fmt.Sprintf("/1/query_annotations/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
+	return s.client.Do(ctx, "DELETE", fmt.Sprintf("/1/query_annotations/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
 }
diff --git a/client/query_result.go b/client/query_result.go
index ff46617..771ba0d 100644
--- a/client/query_result.go
+++ b/client/query_result.go
@@ -74,7 +74,7 @@ func (s *queryResults) Get(ctx context.Context, dataset string, q *QueryResult)
 		select {
 		case <-ticker.C:
 			// poll until complete or errored
-			if err = s.client.performRequest(ctx, "GET", resultUri, nil, &q); err != nil {
+			if err = s.client.Do(ctx, "GET", resultUri, nil, &q); err != nil {
 				return err
 			}
 			if q.Complete {
@@ -88,6 +88,6 @@ func (s *queryResults) Get(ctx context.Context, dataset string, q *QueryResult)
 
 func (s *queryResults) Create(ctx context.Context, dataset string, data *QueryResultRequest) (*QueryResult, error) {
 	var q QueryResult
-	err := s.client.performRequest(ctx, "POST", fmt.Sprintf("/1/query_results/%s", urlEncodeDataset(dataset)), data, &q)
+	err := s.client.Do(ctx, "POST", fmt.Sprintf("/1/query_results/%s", urlEncodeDataset(dataset)), data, &q)
 	return &q, err
 }
diff --git a/client/query_spec.go b/client/query_spec.go
index a785098..865425c 100644
--- a/client/query_spec.go
+++ b/client/query_spec.go
@@ -138,7 +138,6 @@ type CalculationSpec struct {
 // CalculationOp represents the operator of a calculation.
 type CalculationOp string
 
-// Declaration of calculation operators.
 const (
 	CalculationOpCount         CalculationOp = "COUNT"
 	CalculationOpConcurrency   CalculationOp = "CONCURRENCY"
diff --git a/client/recipient.go b/client/recipient.go
index 0e4e04b..66e27b2 100644
--- a/client/recipient.go
+++ b/client/recipient.go
@@ -116,28 +116,28 @@ func RecipientTypes() []RecipientType {
 
 func (s *recipients) List(ctx context.Context) ([]Recipient, error) {
 	var r []Recipient
-	err := s.client.performRequest(ctx, "GET", "/1/recipients", nil, &r)
+	err := s.client.Do(ctx, "GET", "/1/recipients", nil, &r)
 	return r, err
 }
 
 func (s *recipients) Get(ctx context.Context, ID string) (*Recipient, error) {
 	var r Recipient
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/recipients/%s", ID), nil, &r)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/recipients/%s", ID), nil, &r)
 	return &r, err
 }
 
 func (s *recipients) Create(ctx context.Context, data *Recipient) (*Recipient, error) {
 	var r Recipient
-	err := s.client.performRequest(ctx, "POST", "/1/recipients", data, &r)
+	err := s.client.Do(ctx, "POST", "/1/recipients", data, &r)
 	return &r, err
 }
 
 func (s *recipients) Update(ctx context.Context, data *Recipient) (*Recipient, error) {
 	var r Recipient
-	err := s.client.performRequest(ctx, "PUT", fmt.Sprintf("/1/recipients/%s", data.ID), data, &r)
+	err := s.client.Do(ctx, "PUT", fmt.Sprintf("/1/recipients/%s", data.ID), data, &r)
 	return &r, err
 }
 
 func (s *recipients) Delete(ctx context.Context, id string) error {
-	return s.client.performRequest(ctx, "DELETE", fmt.Sprintf("/1/recipients/%s", id), nil, nil)
+	return s.client.Do(ctx, "DELETE", fmt.Sprintf("/1/recipients/%s", id), nil, nil)
 }
diff --git a/client/slo.go b/client/slo.go
index f23b16a..cd57e4c 100644
--- a/client/slo.go
+++ b/client/slo.go
@@ -52,28 +52,28 @@ type SLO struct {
 
 func (s *slos) List(ctx context.Context, dataset string) ([]SLO, error) {
 	var r []SLO
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/slos/%s", urlEncodeDataset(dataset)), nil, &r)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/slos/%s", urlEncodeDataset(dataset)), nil, &r)
 	return r, err
 }
 
 func (s *slos) Get(ctx context.Context, dataset string, id string) (*SLO, error) {
 	var r SLO
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/slos/%s/%s", urlEncodeDataset(dataset), id), nil, &r)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/slos/%s/%s", urlEncodeDataset(dataset), id), nil, &r)
 	return &r, err
 }
 
 func (s *slos) Create(ctx context.Context, dataset string, data *SLO) (*SLO, error) {
 	var r SLO
-	err := s.client.performRequest(ctx, "POST", fmt.Sprintf("/1/slos/%s", urlEncodeDataset(dataset)), data, &r)
+	err := s.client.Do(ctx, "POST", fmt.Sprintf("/1/slos/%s", urlEncodeDataset(dataset)), data, &r)
 	return &r, err
 }
 
 func (s *slos) Update(ctx context.Context, dataset string, data *SLO) (*SLO, error) {
 	var r SLO
-	err := s.client.performRequest(ctx, "PUT", fmt.Sprintf("/1/slos/%s/%s", urlEncodeDataset(dataset), data.ID), data, &r)
+	err := s.client.Do(ctx, "PUT", fmt.Sprintf("/1/slos/%s/%s", urlEncodeDataset(dataset), data.ID), data, &r)
 	return &r, err
 }
 
 func (s *slos) Delete(ctx context.Context, dataset string, id string) error {
-	return s.client.performRequest(ctx, "DELETE", fmt.Sprintf("/1/slos/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
+	return s.client.Do(ctx, "DELETE", fmt.Sprintf("/1/slos/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
 }
diff --git a/client/trigger.go b/client/trigger.go
index f61dea9..d3af233 100644
--- a/client/trigger.go
+++ b/client/trigger.go
@@ -158,30 +158,30 @@ func (t *Trigger) MarshalJSON() ([]byte, error) {
 
 func (s *triggers) List(ctx context.Context, dataset string) ([]Trigger, error) {
 	var t []Trigger
-	err := s.client.performRequest(ctx, "GET", "/1/triggers/"+urlEncodeDataset(dataset), nil, &t)
+	err := s.client.Do(ctx, "GET", "/1/triggers/"+urlEncodeDataset(dataset), nil, &t)
 	return t, err
 }
 
 func (s *triggers) Get(ctx context.Context, dataset string, id string) (*Trigger, error) {
 	var t Trigger
-	err := s.client.performRequest(ctx, "GET", fmt.Sprintf("/1/triggers/%s/%s", urlEncodeDataset(dataset), id), nil, &t)
+	err := s.client.Do(ctx, "GET", fmt.Sprintf("/1/triggers/%s/%s", urlEncodeDataset(dataset), id), nil, &t)
 	return &t, err
 }
 
 func (s *triggers) Create(ctx context.Context, dataset string, data *Trigger) (*Trigger, error) {
 	var t Trigger
-	err := s.client.performRequest(ctx, "POST", fmt.Sprintf("/1/triggers/%s", urlEncodeDataset(dataset)), data, &t)
+	err := s.client.Do(ctx, "POST", fmt.Sprintf("/1/triggers/%s", urlEncodeDataset(dataset)), data, &t)
 	return &t, err
 }
 
 func (s *triggers) Update(ctx context.Context, dataset string, data *Trigger) (*Trigger, error) {
 	var t Trigger
-	err := s.client.performRequest(ctx, "PUT", fmt.Sprintf("/1/triggers/%s/%s", urlEncodeDataset(dataset), data.ID), data, &t)
+	err := s.client.Do(ctx, "PUT", fmt.Sprintf("/1/triggers/%s/%s", urlEncodeDataset(dataset), data.ID), data, &t)
 	return &t, err
 }
 
 func (s *triggers) Delete(ctx context.Context, dataset string, id string) error {
-	return s.client.performRequest(ctx, "DELETE", fmt.Sprintf("/1/triggers/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
+	return s.client.Do(ctx, "DELETE", fmt.Sprintf("/1/triggers/%s/%s", urlEncodeDataset(dataset), id), nil, nil)
 }
 
 // MatchesTriggerSubset checks that the given QuerySpec matches the strict
diff --git a/honeycombio/provider.go b/honeycombio/provider.go
index 42f480e..776205e 100644
--- a/honeycombio/provider.go
+++ b/honeycombio/provider.go
@@ -94,7 +94,7 @@ func Provider(version string) *schema.Provider {
 			UserAgent: provider.UserAgent("terraform-provider-honeycombio", version),
 			Debug:     debug,
 		}
-		c, err := honeycombio.NewClient(config)
+		c, err := honeycombio.NewClientWithConfig(config)
 		if err != nil {
 			return nil, diag.FromErr(err)
 		}
diff --git a/internal/provider/burn_alert_resource.go b/internal/provider/burn_alert_resource.go
index 9c62811..cd5d4af 100644
--- a/internal/provider/burn_alert_resource.go
+++ b/internal/provider/burn_alert_resource.go
@@ -229,7 +229,7 @@ func (r *burnAlertResource) Create(ctx context.Context, req resource.CreateReque
 
 	// Get attributes from config and construct the create request
 	createRequest := &client.BurnAlert{
-		AlertType:  plan.AlertType.ValueString(),
+		AlertType:  client.BurnAlertAlertType(plan.AlertType.ValueString()),
 		Recipients: expandNotificationRecipients(plan.Recipients),
 		SLO:        client.SLORef{ID: plan.SLOID.ValueString()},
 	}
@@ -256,7 +256,7 @@ func (r *burnAlertResource) Create(ctx context.Context, req resource.CreateReque
 	// Get attributes from the new burn alert and construct the state values
 	var state models.BurnAlertResourceModel
 	state.ID = types.StringValue(burnAlert.ID)
-	state.AlertType = types.StringValue(burnAlert.AlertType)
+	state.AlertType = types.StringValue(string(burnAlert.AlertType))
 	state.Dataset = plan.Dataset
 	// we created them as authored so to avoid matching type-target or ID we can just use the same value
 	state.Recipients = config.Recipients
@@ -313,7 +313,7 @@ func (r *burnAlertResource) Read(ctx context.Context, req resource.ReadRequest,
 
 	// Get attributes from the burn alert and construct the state values
 	state.ID = types.StringValue(burnAlert.ID)
-	state.AlertType = types.StringValue(burnAlert.AlertType)
+	state.AlertType = types.StringValue(string(burnAlert.AlertType))
 	state.SLOID = types.StringValue(burnAlert.SLO.ID)
 
 	// Process any attributes that could be nil and add them to the state values
@@ -370,7 +370,7 @@ func (r *burnAlertResource) Update(ctx context.Context, req resource.UpdateReque
 	// Get attributes from config and construct the update request
 	updateRequest := &client.BurnAlert{
 		ID:         plan.ID.ValueString(),
-		AlertType:  plan.AlertType.ValueString(),
+		AlertType:  client.BurnAlertAlertType(plan.AlertType.ValueString()),
 		Recipients: expandNotificationRecipients(plan.Recipients),
 		SLO:        client.SLORef{ID: plan.SLOID.ValueString()},
 	}
@@ -403,7 +403,7 @@ func (r *burnAlertResource) Update(ctx context.Context, req resource.UpdateReque
 	// Get attributes from the updated burn alert and construct the state values
 	var state models.BurnAlertResourceModel
 	state.ID = types.StringValue(burnAlert.ID)
-	state.AlertType = types.StringValue(burnAlert.AlertType)
+	state.AlertType = types.StringValue(string(burnAlert.AlertType))
 	state.Dataset = plan.Dataset
 	// we created them as authored so to avoid matching type-target or ID we can just use the same value
 	state.Recipients = config.Recipients
diff --git a/internal/provider/provider.go b/internal/provider/provider.go
index 5cb89bb..38f7060 100644
--- a/internal/provider/provider.go
+++ b/internal/provider/provider.go
@@ -123,7 +123,7 @@ func (p *HoneycombioProvider) Configure(ctx context.Context, req provider.Config
 		debug = config.Debug.ValueBool()
 	}
 
-	client, err := client.NewClient(&client.Config{
+	client, err := client.NewClientWithConfig(&client.Config{
 		APIKey:    apiKey,
 		APIUrl:    config.APIUrl.ValueString(),
 		Debug:     debug,


Test patch:
diff --git a/client/auth_test.go b/client/auth_test.go
index 0eba6d7..7a72d37 100644
--- a/client/auth_test.go
+++ b/client/auth_test.go
@@ -1,4 +1,4 @@
-package client
+package client_test
 
 import (
 	"context"
@@ -13,14 +13,15 @@ func TestAuthMetadata(t *testing.T) {
 	c := newTestClient(t)
 
 	t.Run("List", func(t *testing.T) {
-		metadata, err := c.Auth.List(context.Background())
+		ctx := context.Background()
+		metadata, err := c.Auth.List(ctx)
 
 		assert.NoError(t, err)
 		assert.NotEmpty(t, metadata.APIKeyAccess)
 		assert.NotEmpty(t, metadata.Team.Name)
 		assert.NotEmpty(t, metadata.Team.Slug)
 		// classic environment's don't have environment name and slugs
-		if len(c.apiKey) == 32 {
+		if c.IsClassic(ctx) {
 			assert.Empty(t, metadata.Environment.Name)
 			assert.Empty(t, metadata.Environment.Slug)
 		} else {
diff --git a/client/board_test.go b/client/board_test.go
index f4c65cb..62579c2 100644
--- a/client/board_test.go
+++ b/client/board_test.go
@@ -1,12 +1,14 @@
-package client
+package client_test
 
 import (
 	"context"
 	"testing"
 
-	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
+	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 )
 
 func TestBoards(t *testing.T) {
@@ -14,13 +16,13 @@ func TestBoards(t *testing.T) {
 
 	ctx := context.Background()
 
-	var b *Board
+	var b *client.Board
 	var err error
 
 	c := newTestClient(t)
 	dataset := testDataset(t)
 
-	column, err := c.Columns.Create(ctx, dataset, &Column{
+	column, err := c.Columns.Create(ctx, dataset, &client.Column{
 		KeyName: test.RandomStringWithPrefix("test.", 8),
 	})
 	require.NoError(t, err)
@@ -29,30 +31,30 @@ func TestBoards(t *testing.T) {
 		c.Columns.Delete(ctx, dataset, column.ID)
 	})
 
-	query, err := c.Queries.Create(ctx, dataset, &QuerySpec{
-		Calculations: []CalculationSpec{
+	query, err := c.Queries.Create(ctx, dataset, &client.QuerySpec{
+		Calculations: []client.CalculationSpec{
 			{
-				Op:     CalculationOpAvg,
+				Op:     client.CalculationOpAvg,
 				Column: &column.KeyName,
 			},
 		},
-		TimeRange: ToPtr(3600), // 1 hour
+		TimeRange: client.ToPtr(3600), // 1 hour
 	})
 	require.NoError(t, err)
 
 	t.Run("Create", func(t *testing.T) {
-		data := &Board{
+		data := &client.Board{
 			Name:         test.RandomStringWithPrefix("test.", 8),
 			Description:  "A board with some queries",
-			Style:        BoardStyleVisual,
-			ColumnLayout: BoardColumnStyleSingle,
-			Queries: []BoardQuery{
+			Style:        client.BoardStyleVisual,
+			ColumnLayout: client.BoardColumnStyleSingle,
+			Queries: []client.BoardQuery{
 				{
 					Caption:       "A sample query",
-					QueryStyle:    BoardQueryStyleCombo,
+					QueryStyle:    client.BoardQueryStyleCombo,
 					Dataset:       dataset,
 					QueryID:       *query.ID,
-					GraphSettings: BoardGraphSettings{OmitMissingValues: true, UseUTCXAxis: true},
+					GraphSettings: client.BoardGraphSettings{OmitMissingValues: true, UseUTCXAxis: true},
 				},
 			},
 		}
@@ -87,21 +89,21 @@ func TestBoards(t *testing.T) {
 	})
 
 	t.Run("Update", func(t *testing.T) {
-		newQuery, err := c.Queries.Create(ctx, dataset, &QuerySpec{
-			Calculations: []CalculationSpec{
+		newQuery, err := c.Queries.Create(ctx, dataset, &client.QuerySpec{
+			Calculations: []client.CalculationSpec{
 				{
-					Op: CalculationOpCount,
+					Op: client.CalculationOpCount,
 				},
 			},
-			TimeRange: ToPtr(DefaultQueryTimeRange),
+			TimeRange: client.ToPtr(client.DefaultQueryTimeRange),
 		})
 		assert.NoError(t, err)
-		b.ColumnLayout = BoardColumnStyleMulti
-		b.Queries = append(b.Queries, BoardQuery{
+		b.ColumnLayout = client.BoardColumnStyleMulti
+		b.Queries = append(b.Queries, client.BoardQuery{
 			Caption:       "A second query",
-			QueryStyle:    BoardQueryStyleGraph,
+			QueryStyle:    client.BoardQueryStyleGraph,
 			QueryID:       *newQuery.ID,
-			GraphSettings: BoardGraphSettings{UseUTCXAxis: true},
+			GraphSettings: client.BoardGraphSettings{UseUTCXAxis: true},
 		})
 
 		result, err := c.Boards.Update(ctx, b)
@@ -118,7 +120,7 @@ func TestBoards(t *testing.T) {
 	t.Run("Fail to get deleted Board", func(t *testing.T) {
 		_, err := c.Boards.Get(ctx, b.ID)
 
-		var de DetailedError
+		var de client.DetailedError
 		assert.Error(t, err)
 		assert.ErrorAs(t, err, &de)
 		assert.True(t, de.IsNotFound())
diff --git a/client/burn_alert_test.go b/client/burn_alert_test.go
index 61614a5..d9d5778 100644
--- a/client/burn_alert_test.go
+++ b/client/burn_alert_test.go
@@ -1,13 +1,15 @@
-package client
+package client_test
 
 import (
 	"context"
 	"fmt"
 	"testing"
 
-	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
+	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 )
 
 func TestBurnAlerts(t *testing.T) {
@@ -21,16 +23,16 @@ func TestBurnAlerts(t *testing.T) {
 	dataset := testDataset(t)
 	testAlertEmail := test.RandomString(8) + "@example.com"
 
-	sli, err := c.DerivedColumns.Create(ctx, dataset, &DerivedColumn{
+	sli, err := c.DerivedColumns.Create(ctx, dataset, &client.DerivedColumn{
 		Alias:      test.RandomStringWithPrefix("test.", 8),
 		Expression: "BOOL(1)",
 	})
 	require.NoError(t, err)
-	slo, err := c.SLOs.Create(ctx, dataset, &SLO{
+	slo, err := c.SLOs.Create(ctx, dataset, &client.SLO{
 		Name:             test.RandomStringWithPrefix("test.", 8),
 		TimePeriodDays:   7,
 		TargetPerMillion: 999000,
-		SLI:              SLIRef{Alias: sli.Alias},
+		SLI:              client.SLIRef{Alias: sli.Alias},
 	})
 	require.NoError(t, err)
 
@@ -43,19 +45,19 @@ func TestBurnAlerts(t *testing.T) {
 		// remove test alert email from recipients
 		rcpts, _ := c.Recipients.List(ctx)
 		for _, r := range rcpts {
-			if r.Type == RecipientTypeEmail && r.Details.EmailAddress == testAlertEmail {
+			if r.Type == client.RecipientTypeEmail && r.Details.EmailAddress == testAlertEmail {
 				c.Recipients.Delete(ctx, r.ID)
 				break
 			}
 		}
 	})
 
-	var defaultBurnAlert *BurnAlert
+	var defaultBurnAlert *client.BurnAlert
 	exhaustionMinutes24Hours := 24 * 60
-	defaultBurnAlertCreateRequest := BurnAlert{
+	defaultBurnAlertCreateRequest := client.BurnAlert{
 		ExhaustionMinutes: &exhaustionMinutes24Hours,
-		SLO:               SLORef{ID: slo.ID},
-		Recipients: []NotificationRecipient{
+		SLO:               client.SLORef{ID: slo.ID},
+		Recipients: []client.NotificationRecipient{
 			{
 				Type:   "email",
 				Target: testAlertEmail,
@@ -63,10 +65,10 @@ func TestBurnAlerts(t *testing.T) {
 		},
 	}
 	exhaustionMinutes1Hour := 60
-	defaultBurnAlertUpdateRequest := BurnAlert{
+	defaultBurnAlertUpdateRequest := client.BurnAlert{
 		ExhaustionMinutes: &exhaustionMinutes1Hour,
-		SLO:               SLORef{ID: slo.ID},
-		Recipients: []NotificationRecipient{
+		SLO:               client.SLORef{ID: slo.ID},
+		Recipients: []client.NotificationRecipient{
 			{
 				Type:   "email",
 				Target: testAlertEmail,
@@ -74,13 +76,13 @@ func TestBurnAlerts(t *testing.T) {
 		},
 	}
 
-	var exhaustionTimeBurnAlert *BurnAlert
+	var exhaustionTimeBurnAlert *client.BurnAlert
 	exhaustionMinutes0Minutes := 0
-	exhaustionTimeBurnAlertCreateRequest := BurnAlert{
-		AlertType:         string(BurnAlertAlertTypeExhaustionTime),
+	exhaustionTimeBurnAlertCreateRequest := client.BurnAlert{
+		AlertType:         client.BurnAlertAlertTypeExhaustionTime,
 		ExhaustionMinutes: &exhaustionMinutes0Minutes,
-		SLO:               SLORef{ID: slo.ID},
-		Recipients: []NotificationRecipient{
+		SLO:               client.SLORef{ID: slo.ID},
+		Recipients: []client.NotificationRecipient{
 			{
 				Type:   "email",
 				Target: testAlertEmail,
@@ -88,11 +90,11 @@ func TestBurnAlerts(t *testing.T) {
 		},
 	}
 	exhaustionMinutes4Hours := 4 * 60
-	exhaustionTimeBurnAlertUpdateRequest := BurnAlert{
-		AlertType:         string(BurnAlertAlertTypeExhaustionTime),
+	exhaustionTimeBurnAlertUpdateRequest := client.BurnAlert{
+		AlertType:         client.BurnAlertAlertTypeExhaustionTime,
 		ExhaustionMinutes: &exhaustionMinutes4Hours,
-		SLO:               SLORef{ID: slo.ID},
-		Recipients: []NotificationRecipient{
+		SLO:               client.SLORef{ID: slo.ID},
+		Recipients: []client.NotificationRecipient{
 			{
 				Type:   "email",
 				Target: testAlertEmail,
@@ -100,15 +102,15 @@ func TestBurnAlerts(t *testing.T) {
 		},
 	}
 
-	var budgetRateBurnAlert *BurnAlert
+	var budgetRateBurnAlert *client.BurnAlert
 	budgetRateWindowMinutes1Hour := 60
 	budgetRateDecreaseThresholdPerMillion1Percent := 10000
-	budgetRateBurnAlertCreateRequest := BurnAlert{
-		AlertType:                             string(BurnAlertAlertTypeBudgetRate),
+	budgetRateBurnAlertCreateRequest := client.BurnAlert{
+		AlertType:                             client.BurnAlertAlertTypeBudgetRate,
 		BudgetRateWindowMinutes:               &budgetRateWindowMinutes1Hour,
 		BudgetRateDecreaseThresholdPerMillion: &budgetRateDecreaseThresholdPerMillion1Percent,
-		SLO:                                   SLORef{ID: slo.ID},
-		Recipients: []NotificationRecipient{
+		SLO:                                   client.SLORef{ID: slo.ID},
+		Recipients: []client.NotificationRecipient{
 			{
 				Type:   "email",
 				Target: testAlertEmail,
@@ -117,12 +119,12 @@ func TestBurnAlerts(t *testing.T) {
 	}
 	budgetRateWindowMinutes2Hours := 2 * 60
 	budgetRateDecreaseThresholdPerMillion5Percent := 10000
-	budgetRateBurnAlertUpdateRequest := BurnAlert{
-		AlertType:                             string(BurnAlertAlertTypeBudgetRate),
+	budgetRateBurnAlertUpdateRequest := client.BurnAlert{
+		AlertType:                             client.BurnAlertAlertTypeBudgetRate,
 		BudgetRateWindowMinutes:               &budgetRateWindowMinutes2Hours,
 		BudgetRateDecreaseThresholdPerMillion: &budgetRateDecreaseThresholdPerMillion5Percent,
-		SLO:                                   SLORef{ID: slo.ID},
-		Recipients: []NotificationRecipient{
+		SLO:                                   client.SLORef{ID: slo.ID},
+		Recipients: []client.NotificationRecipient{
 			{
 				Type:   "email",
 				Target: testAlertEmail,
@@ -131,25 +133,25 @@ func TestBurnAlerts(t *testing.T) {
 	}
 
 	testCases := map[string]struct {
-		alertType     string
-		createRequest BurnAlert
-		updateRequest BurnAlert
-		burnAlert     *BurnAlert
+		alertType     client.BurnAlertAlertType
+		createRequest client.BurnAlert
+		updateRequest client.BurnAlert
+		burnAlert     *client.BurnAlert
 	}{
 		"default - exhaustion_time": {
-			alertType:     string(BurnAlertAlertTypeExhaustionTime),
+			alertType:     client.BurnAlertAlertTypeExhaustionTime,
 			createRequest: defaultBurnAlertCreateRequest,
 			updateRequest: defaultBurnAlertUpdateRequest,
 			burnAlert:     defaultBurnAlert,
 		},
 		"exhaustion_time": {
-			alertType:     string(BurnAlertAlertTypeExhaustionTime),
+			alertType:     client.BurnAlertAlertTypeExhaustionTime,
 			createRequest: exhaustionTimeBurnAlertCreateRequest,
 			updateRequest: exhaustionTimeBurnAlertUpdateRequest,
 			burnAlert:     exhaustionTimeBurnAlert,
 		},
 		"budget_rate": {
-			alertType:     string(BurnAlertAlertTypeBudgetRate),
+			alertType:     client.BurnAlertAlertTypeBudgetRate,
 			createRequest: budgetRateBurnAlertCreateRequest,
 			updateRequest: budgetRateBurnAlertUpdateRequest,
 			burnAlert:     budgetRateBurnAlert,
@@ -157,7 +159,7 @@ func TestBurnAlerts(t *testing.T) {
 	}
 
 	for testName, testCase := range testCases {
-		var burnAlert *BurnAlert
+		var burnAlert *client.BurnAlert
 		var err error
 
 		t.Run(fmt.Sprintf("Create: %s", testName), func(t *testing.T) {
@@ -219,7 +221,7 @@ func TestBurnAlerts(t *testing.T) {
 		t.Run(fmt.Sprintf("Fail to GET a deleted burn alert: %s", testName), func(t *testing.T) {
 			_, err := c.BurnAlerts.Get(ctx, dataset, burnAlert.ID)
 
-			var de DetailedError
+			var de client.DetailedError
 			assert.Error(t, err)
 			assert.ErrorAs(t, err, &de)
 			assert.True(t, de.IsNotFound())
@@ -228,13 +230,13 @@ func TestBurnAlerts(t *testing.T) {
 }
 
 func TestBurnAlerts_BurnAlertAlertTypes(t *testing.T) {
-	expectedAlertTypes := []BurnAlertAlertType{
-		BurnAlertAlertTypeExhaustionTime,
-		BurnAlertAlertTypeBudgetRate,
+	expectedAlertTypes := []client.BurnAlertAlertType{
+		client.BurnAlertAlertTypeExhaustionTime,
+		client.BurnAlertAlertTypeBudgetRate,
 	}
 
 	t.Run("returns expected burn alert alert types", func(t *testing.T) {
-		actualAlertTypes := BurnAlertAlertTypes()
+		actualAlertTypes := client.BurnAlertAlertTypes()
 
 		assert.NotEmpty(t, actualAlertTypes)
 		assert.Equal(t, len(expectedAlertTypes), len(actualAlertTypes))
diff --git a/client/client_test.go b/client/client_test.go
index 07bda1a..d51fe23 100644
--- a/client/client_test.go
+++ b/client/client_test.go
@@ -1,4 +1,4 @@
-package client
+package client_test
 
 import (
 	"context"
@@ -8,26 +8,29 @@ import (
 	"github.com/joho/godotenv"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
 )
 
-func newTestClient(t *testing.T) *Client {
+const testUserAgent = "go-honeycombio/test"
+
+func newTestClient(t *testing.T) *client.Client {
 	t.Helper()
 
 	// load environment values from a .env, if available
 	_ = godotenv.Load("../.env")
 
-	apiKey, ok := os.LookupEnv(DefaultAPIKeyEnv)
+	apiKey, ok := os.LookupEnv(client.DefaultAPIKeyEnv)
 	if !ok {
-		t.Fatal("expected environment variable " + DefaultAPIKeyEnv)
+		t.Fatal("expected environment variable " + client.DefaultAPIKeyEnv)
 	}
 	_, debug := os.LookupEnv("HONEYCOMBIO_DEBUG")
 
-	cfg := &Config{
+	c, err := client.NewClientWithConfig(&client.Config{
 		APIKey:    apiKey,
 		Debug:     debug,
-		UserAgent: "go-honeycombio/test",
-	}
-	c, err := NewClient(cfg)
+		UserAgent: testUserAgent,
+	})
 	require.NoError(t, err, "failed to create client")
 
 	return c
@@ -47,7 +50,7 @@ func testDataset(t *testing.T) string {
 func TestClient_InvalidConfig(t *testing.T) {
 	t.Parallel()
 
-	_, err := NewClient(&Config{
+	_, err := client.NewClientWithConfig(&client.Config{
 		APIKey: "123",
 		APIUrl: "cache_object:foo/bar",
 	})
@@ -59,7 +62,28 @@ func TestClient_IsClassic(t *testing.T) {
 	t.Parallel()
 
 	ctx := context.Background()
-	c := newTestClient(t)
+	apiKey, ok := os.LookupEnv(client.DefaultAPIKeyEnv)
+	if !ok {
+		t.Fatal("expected environment variable " + client.DefaultAPIKeyEnv)
+	}
+	c, err := client.NewClientWithConfig(&client.Config{
+		APIKey:    apiKey,
+		UserAgent: testUserAgent,
+	})
+	require.NoError(t, err, "failed to create client")
+
+	assert.Equal(t, len(apiKey) == 32, c.IsClassic(ctx))
+}
+
+func TestClient_EndpointURL(t *testing.T) {
+	t.Parallel()
+
+	endpointUrl := "https://api.example.com"
+	c, err := client.NewClientWithConfig(&client.Config{
+		APIUrl: endpointUrl,
+		APIKey: "abcd123",
+	})
+	require.NoError(t, err, "failed to create client")
 
-	assert.Equal(t, len(c.apiKey) == 32, c.IsClassic(ctx))
+	assert.Equal(t, endpointUrl, c.EndpointURL().String())
 }
diff --git a/client/column_test.go b/client/column_test.go
index 4d3ae29..89833dd 100644
--- a/client/column_test.go
+++ b/client/column_test.go
@@ -1,12 +1,14 @@
-package client
+package client_test
 
 import (
 	"context"
 	"testing"
 
-	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
+	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 )
 
 func TestColumns(t *testing.T) {
@@ -17,15 +19,15 @@ func TestColumns(t *testing.T) {
 	c := newTestClient(t)
 	dataset := testDataset(t)
 
-	var column *Column
+	var column *client.Column
 	var err error
 
 	t.Run("Create", func(t *testing.T) {
-		data := &Column{
+		data := &client.Column{
 			KeyName:     test.RandomStringWithPrefix("test.", 10),
-			Hidden:      ToPtr(false),
+			Hidden:      client.ToPtr(false),
 			Description: "This column is created by a test",
-			Type:        ToPtr(ColumnTypeFloat),
+			Type:        client.ToPtr(client.ColumnTypeFloat),
 		}
 		column, err = c.Columns.Create(ctx, dataset, data)
 
@@ -65,12 +67,12 @@ func TestColumns(t *testing.T) {
 
 	t.Run("Update", func(t *testing.T) {
 		// change all the fields to test
-		data := &Column{
+		data := &client.Column{
 			ID:          column.ID,
 			KeyName:     column.KeyName,
-			Hidden:      ToPtr(true),
+			Hidden:      client.ToPtr(true),
 			Description: "This is a new description",
-			Type:        ToPtr(ColumnTypeBoolean),
+			Type:        client.ToPtr(client.ColumnTypeBoolean),
 		}
 		column, err = c.Columns.Update(ctx, dataset, data)
 
@@ -98,7 +100,7 @@ func TestColumns(t *testing.T) {
 	t.Run("Fail to get deleted Column", func(t *testing.T) {
 		_, err := c.Columns.Get(ctx, dataset, column.ID)
 
-		var de DetailedError
+		var de client.DetailedError
 		assert.Error(t, err)
 		assert.ErrorAs(t, err, &de)
 		assert.True(t, de.IsNotFound())
@@ -109,24 +111,28 @@ func TestColumns(t *testing.T) {
 // One column is of type Float, and two are of type String.
 //
 // The columns are automatically cleaned up after the test run.
-func createRandomTestColumns(t *testing.T, c *Client, dataset string) (*Column, *Column, *Column) {
+func createRandomTestColumns(
+	t *testing.T,
+	c *client.Client,
+	dataset string,
+) (*client.Column, *client.Column, *client.Column) {
 	t.Helper()
 
 	ctx := context.Background()
 
-	floatCol, err := c.Columns.Create(ctx, dataset, &Column{
+	floatCol, err := c.Columns.Create(ctx, dataset, &client.Column{
 		KeyName: test.RandomStringWithPrefix("test.", 8),
-		Type:    ToPtr(ColumnTypeFloat),
+		Type:    client.ToPtr(client.ColumnTypeFloat),
 	})
 	require.NoError(t, err)
-	col1, err := c.Columns.Create(ctx, dataset, &Column{
+	col1, err := c.Columns.Create(ctx, dataset, &client.Column{
 		KeyName: test.RandomStringWithPrefix("test.", 8),
-		Type:    ToPtr(ColumnTypeString),
+		Type:    client.ToPtr(client.ColumnTypeString),
 	})
 	require.NoError(t, err)
-	col2, err := c.Columns.Create(ctx, dataset, &Column{
+	col2, err := c.Columns.Create(ctx, dataset, &client.Column{
 		KeyName: test.RandomStringWithPrefix("test.", 8),
-		Type:    ToPtr(ColumnTypeString),
+		Type:    client.ToPtr(client.ColumnTypeString),
 	})
 	require.NoError(t, err)
 
diff --git a/client/dataset_definitions_test.go b/client/dataset_definitions_test.go
index 9d2c5d4..b0087b9 100644
--- a/client/dataset_definitions_test.go
+++ b/client/dataset_definitions_test.go
@@ -1,12 +1,14 @@
-package client
+package client_test
 
 import (
 	"context"
 	"testing"
 
-	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
+	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 )
 
 func TestDatasetDefinitions(t *testing.T) {
@@ -16,27 +18,27 @@ func TestDatasetDefinitions(t *testing.T) {
 
 	c := newTestClient(t)
 	dataset := testDataset(t)
-	definitionDefaults := DatasetDefinitionDefaults()
+	definitionDefaults := client.DatasetDefinitionDefaults()
 
 	// ensure default definition columns exist -- create any which may be missing.
 	// we leave these behind at the end of the test run
 	// as they can't be deleted while being used as a definition column
-	for _, col := range []Column{
-		{KeyName: "duration_ms", Type: ToPtr(ColumnTypeFloat)},
-		{KeyName: "error", Type: ToPtr(ColumnTypeBoolean)},
-		{KeyName: "name", Type: ToPtr(ColumnTypeString)},
-		{KeyName: "trace.parent_id", Type: ToPtr(ColumnTypeString)},
-		{KeyName: "http.route", Type: ToPtr(ColumnTypeString)},
-		{KeyName: "service.name", Type: ToPtr(ColumnTypeString)},
-		{KeyName: "trace.span_id", Type: ToPtr(ColumnTypeString)},
-		{KeyName: "meta.span_type", Type: ToPtr(ColumnTypeString)},
-		{KeyName: "meta.annotation_type", Type: ToPtr(ColumnTypeString)},
-		{KeyName: "http.status_code", Type: ToPtr(ColumnTypeInteger)},
-		{KeyName: "trace.trace_id", Type: ToPtr(ColumnTypeString)},
-		{KeyName: "request.user.id", Type: ToPtr(ColumnTypeString)},
-		{KeyName: "request.user.username", Type: ToPtr(ColumnTypeString)},
-		{KeyName: "trace.link.trace_id", Type: ToPtr(ColumnTypeString)},
-		{KeyName: "trace.link.span_id", Type: ToPtr(ColumnTypeString)},
+	for _, col := range []client.Column{
+		{KeyName: "duration_ms", Type: client.ToPtr(client.ColumnTypeFloat)},
+		{KeyName: "error", Type: client.ToPtr(client.ColumnTypeBoolean)},
+		{KeyName: "name", Type: client.ToPtr(client.ColumnTypeString)},
+		{KeyName: "trace.parent_id", Type: client.ToPtr(client.ColumnTypeString)},
+		{KeyName: "http.route", Type: client.ToPtr(client.ColumnTypeString)},
+		{KeyName: "service.name", Type: client.ToPtr(client.ColumnTypeString)},
+		{KeyName: "trace.span_id", Type: client.ToPtr(client.ColumnTypeString)},
+		{KeyName: "meta.span_type", Type: client.ToPtr(client.ColumnTypeString)},
+		{KeyName: "meta.annotation_type", Type: client.ToPtr(client.ColumnTypeString)},
+		{KeyName: "http.status_code", Type: client.ToPtr(client.ColumnTypeInteger)},
+		{KeyName: "trace.trace_id", Type: client.ToPtr(client.ColumnTypeString)},
+		{KeyName: "request.user.id", Type: client.ToPtr(client.ColumnTypeString)},
+		{KeyName: "request.user.username", Type: client.ToPtr(client.ColumnTypeString)},
+		{KeyName: "trace.link.trace_id", Type: client.ToPtr(client.ColumnTypeString)},
+		{KeyName: "trace.link.span_id", Type: client.ToPtr(client.ColumnTypeString)},
 	} {
 		//nolint:errcheck
 		// ignore errors, we don't care if the column already exists
@@ -44,9 +46,9 @@ func TestDatasetDefinitions(t *testing.T) {
 	}
 
 	// create some new columns to assign as definitions -- we will clean these up at the end of the test run
-	testCol, err := c.Columns.Create(ctx, dataset, &Column{KeyName: test.RandomStringWithPrefix("test.", 10)})
+	testCol, err := c.Columns.Create(ctx, dataset, &client.Column{KeyName: test.RandomStringWithPrefix("test.", 10)})
 	require.NoError(t, err)
-	testDC, err := c.DerivedColumns.Create(ctx, dataset, &DerivedColumn{
+	testDC, err := c.DerivedColumns.Create(ctx, dataset, &client.DerivedColumn{
 		Alias:      test.RandomStringWithPrefix("test.", 10),
 		Expression: "BOOL(1)",
 	})
@@ -83,9 +85,9 @@ func TestDatasetDefinitions(t *testing.T) {
 	})
 
 	t.Run("Update a pair of definitions", func(t *testing.T) {
-		_, err := c.DatasetDefinitions.Update(ctx, dataset, &DatasetDefinition{
-			Name:  &DefinitionColumn{Name: testCol.KeyName},
-			Error: &DefinitionColumn{Name: testDC.Alias},
+		_, err := c.DatasetDefinitions.Update(ctx, dataset, &client.DatasetDefinition{
+			Name:  &client.DefinitionColumn{Name: testCol.KeyName},
+			Error: &client.DefinitionColumn{Name: testDC.Alias},
 		})
 		assert.NoError(t, err)
 		// refetch to be extra sure that our update took effect
@@ -98,9 +100,9 @@ func TestDatasetDefinitions(t *testing.T) {
 	})
 
 	t.Run("Reset the fields: ensure reverted to default", func(t *testing.T) {
-		result, err := c.DatasetDefinitions.Update(ctx, dataset, &DatasetDefinition{
-			Name:  EmptyDatasetDefinition(),
-			Error: EmptyDatasetDefinition(),
+		result, err := c.DatasetDefinitions.Update(ctx, dataset, &client.DatasetDefinition{
+			Name:  client.EmptyDatasetDefinition(),
+			Error: client.EmptyDatasetDefinition(),
 		})
 		assert.NoError(t, err)
 		assert.Equal(t, result.Name.Name, "name")
diff --git a/client/dataset_test.go b/client/dataset_test.go
index 355f9cc..04e4472 100644
--- a/client/dataset_test.go
+++ b/client/dataset_test.go
@@ -1,9 +1,10 @@
-package client
+package client_test
 
 import (
 	"context"
 	"testing"
 
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -15,9 +16,8 @@ func TestDatasets(t *testing.T) {
 	c := newTestClient(t)
 	datasetName := testDataset(t)
 
-	currentDataset := &Dataset{
+	currentDataset := &client.Dataset{
 		Name: datasetName,
-		Slug: urlEncodeDataset(datasetName),
 	}
 
 	t.Run("List", func(t *testing.T) {
@@ -30,6 +30,7 @@ func TestDatasets(t *testing.T) {
 			assert.NotNil(t, dataset.CreatedAt, "created at is empty")
 			// copy dynamic fields before asserting - will be skipped if expected dataset not found
 			if dataset.Name == currentDataset.Name {
+				currentDataset.Slug = dataset.Slug
 				currentDataset.LastWrittenAt = dataset.LastWrittenAt
 				currentDataset.CreatedAt = dataset.CreatedAt
 			}
@@ -54,14 +55,14 @@ func TestDatasets(t *testing.T) {
 	t.Run("Fail to Get bogus Dataset", func(t *testing.T) {
 		_, err := c.Datasets.Get(ctx, "does-not-exist")
 
-		var de DetailedError
+		var de client.DetailedError
 		assert.Error(t, err)
 		assert.ErrorAs(t, err, &de)
 		assert.True(t, de.IsNotFound())
 	})
 
 	t.Run("Create", func(t *testing.T) {
-		createDataset := &Dataset{
+		createDataset := &client.Dataset{
 			Name: datasetName,
 		}
 		d, err := c.Datasets.Create(ctx, createDataset)
@@ -81,7 +82,7 @@ func TestDatasets(t *testing.T) {
 		updatedDescription := "buzzing with data"
 		updatedExpandJSONDepth := 3
 
-		updateDataset := &Dataset{
+		updateDataset := &client.Dataset{
 			Name:            datasetName,
 			Description:     updatedDescription,
 			ExpandJSONDepth: updatedExpandJSONDepth,
@@ -89,7 +90,7 @@ func TestDatasets(t *testing.T) {
 		t.Cleanup(func() {
 			// revert updated fields to defaults after the test run
 			//nolint:errcheck
-			c.Datasets.Update(ctx, &Dataset{Name: datasetName})
+			c.Datasets.Update(ctx, &client.Dataset{Name: datasetName})
 		})
 		d, err := c.Datasets.Update(ctx, updateDataset)
 		assert.NoError(t, err)
diff --git a/client/derived_column_test.go b/client/derived_column_test.go
index 0227535..445d114 100644
--- a/client/derived_column_test.go
+++ b/client/derived_column_test.go
@@ -1,13 +1,15 @@
-package client
+package client_test
 
 import (
 	"context"
 	"net/http"
 	"testing"
 
-	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
+	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 )
 
 func TestDerivedColumns(t *testing.T) {
@@ -18,11 +20,11 @@ func TestDerivedColumns(t *testing.T) {
 	c := newTestClient(t)
 	dataset := testDataset(t)
 
-	var derivedColumn *DerivedColumn
+	var derivedColumn *client.DerivedColumn
 	var err error
 
 	t.Run("Create", func(t *testing.T) {
-		data := &DerivedColumn{
+		data := &client.DerivedColumn{
 			Alias:       test.RandomStringWithPrefix("test.", 10),
 			Expression:  "BOOL(1)",
 			Description: "This derived column is created by a test",
@@ -36,14 +38,14 @@ func TestDerivedColumns(t *testing.T) {
 	})
 
 	t.Run("Create_DuplicateErr", func(t *testing.T) {
-		data := &DerivedColumn{
+		data := &client.DerivedColumn{
 			Alias:       derivedColumn.Alias,
 			Expression:  "BOOL(0)",
 			Description: "This is a derived column with the same name as an existing one",
 		}
 		_, err = c.DerivedColumns.Create(ctx, dataset, data)
 
-		var de DetailedError
+		var de client.DetailedError
 		assert.Error(t, err)
 		assert.ErrorAs(t, err, &de)
 		assert.Equal(t, de.Status, http.StatusConflict)
@@ -72,7 +74,7 @@ func TestDerivedColumns(t *testing.T) {
 
 	t.Run("Update", func(t *testing.T) {
 		// change all the fields to test
-		data := &DerivedColumn{
+		data := &client.DerivedColumn{
 			ID:          derivedColumn.ID,
 			Alias:       test.RandomStringWithPrefix("test.", 10),
 			Expression:  "BOOL(0)",
@@ -95,7 +97,7 @@ func TestDerivedColumns(t *testing.T) {
 	t.Run("Fail to Get Deleted DC", func(t *testing.T) {
 		_, err := c.DerivedColumns.Get(ctx, dataset, derivedColumn.ID)
 
-		var de DetailedError
+		var de client.DetailedError
 		assert.Error(t, err)
 		assert.ErrorAs(t, err, &de)
 		assert.True(t, de.IsNotFound())
diff --git a/client/errors_test.go b/client/errors_test.go
index b1d16d3..021e466 100644
--- a/client/errors_test.go
+++ b/client/errors_test.go
@@ -1,4 +1,4 @@
-package client
+package client_test
 
 import (
 	"context"
@@ -8,21 +8,23 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
 )
 
 func TestClient_ParseDetailedError(t *testing.T) {
 	t.Parallel()
 
-	var de DetailedError
+	var de client.DetailedError
 	ctx := context.Background()
 	c := newTestClient(t)
 
 	t.Run("Post with no body should fail with 400 unparseable", func(t *testing.T) {
-		err := c.performRequest(ctx, "POST", "/1/boards/", nil, nil)
+		err := c.Do(ctx, "POST", "/1/boards/", nil, nil)
 		require.Error(t, err)
 		assert.ErrorAs(t, err, &de)
 		assert.Equal(t, de.Status, http.StatusBadRequest)
-		assert.Equal(t, de.Type, fmt.Sprintf("%s/problems/unparseable", c.apiURL))
+		assert.Equal(t, de.Type, fmt.Sprintf("%s/problems/unparseable", c.EndpointURL()))
 		assert.Equal(t, de.Title, "The request body could not be parsed.")
 		assert.Equal(t, de.Message, "could not parse request body")
 	})
@@ -32,18 +34,18 @@ func TestClient_ParseDetailedError(t *testing.T) {
 		require.Error(t, err)
 		assert.ErrorAs(t, err, &de)
 		assert.Equal(t, de.Status, http.StatusNotFound)
-		assert.Equal(t, de.Type, fmt.Sprintf("%s/problems/not-found", c.apiURL))
+		assert.Equal(t, de.Type, fmt.Sprintf("%s/problems/not-found", c.EndpointURL()))
 		assert.Equal(t, de.Title, "The requested resource cannot be found.")
 		assert.Equal(t, de.Message, "Dataset not found")
 	})
 
 	t.Run("Creating a dataset without a name should return a validation error", func(t *testing.T) {
-		createDatasetRequest := &Dataset{}
+		createDatasetRequest := &client.Dataset{}
 		_, err := c.Datasets.Create(ctx, createDatasetRequest)
 		require.Error(t, err)
 		assert.ErrorAs(t, err, &de)
 		assert.Equal(t, http.StatusUnprocessableEntity, de.Status)
-		assert.Equal(t, fmt.Sprintf("%s/problems/validation-failed", c.apiURL), de.Type)
+		assert.Equal(t, fmt.Sprintf("%s/problems/validation-failed", c.EndpointURL()), de.Type)
 		assert.Equal(t, "The provided input is invalid.", de.Title)
 		assert.Equal(t, "The provided input is invalid.", de.Message)
 		assert.Equal(t, 1, len(de.Details))
@@ -59,14 +61,14 @@ func TestErrors_DetailedError_Error(t *testing.T) {
 
 	testCases := []struct {
 		name           string
-		input          DetailedError
+		input          client.DetailedError
 		expectedOutput string
 	}{
 		{
 			name: "multiple details get separated by newline",
-			input: DetailedError{
+			input: client.DetailedError{
 				Message: "test message",
-				Details: []ErrorTypeDetail{
+				Details: []client.ErrorTypeDetail{
 					{
 						Code:        "test code1",
 						Field:       "test_field1",
@@ -83,17 +85,17 @@ func TestErrors_DetailedError_Error(t *testing.T) {
 		},
 		{
 			name: "empty details returns message",
-			input: DetailedError{
+			input: client.DetailedError{
 				Message: "test message",
-				Details: []ErrorTypeDetail{},
+				Details: []client.ErrorTypeDetail{},
 			},
 			expectedOutput: "test message",
 		},
 		{
 			name: "one item in details has no newlines",
-			input: DetailedError{
+			input: client.DetailedError{
 				Message: "test message",
-				Details: []ErrorTypeDetail{
+				Details: []client.ErrorTypeDetail{
 					{
 						Code:        "test code",
 						Field:       "test_field",
@@ -118,12 +120,12 @@ func TestErrors_ErrorTypeDetail_String(t *testing.T) {
 
 	testCases := []struct {
 		name           string
-		input          ErrorTypeDetail
+		input          client.ErrorTypeDetail
 		expectedOutput string
 	}{
 		{
 			name: "happy path: Code, Field, and Description present",
-			input: ErrorTypeDetail{
+			input: client.ErrorTypeDetail{
 				Code:        "test code",
 				Field:       "test_field",
 				Description: "test description",
@@ -132,12 +134,12 @@ func TestErrors_ErrorTypeDetail_String(t *testing.T) {
 		},
 		{
 			name:           "all fields blank returns empty string",
-			input:          ErrorTypeDetail{},
+			input:          client.ErrorTypeDetail{},
 			expectedOutput: "",
 		},
 		{
 			name: "empty Code",
-			input: ErrorTypeDetail{
+			input: client.ErrorTypeDetail{
 				Field:       "test_field",
 				Description: "test description",
 			},
@@ -145,21 +147,21 @@ func TestErrors_ErrorTypeDetail_String(t *testing.T) {
 		},
 		{
 			name: "empty Code and Field",
-			input: ErrorTypeDetail{
+			input: client.ErrorTypeDetail{
 				Description: "test description",
 			},
 			expectedOutput: "test description",
 		},
 		{
 			name: "empty Code and Description",
-			input: ErrorTypeDetail{
+			input: client.ErrorTypeDetail{
 				Field: "test_field",
 			},
 			expectedOutput: "test_field",
 		},
 		{
 			name: "empty Field",
-			input: ErrorTypeDetail{
+			input: client.ErrorTypeDetail{
 				Code:        "test code",
 				Description: "test description",
 			},
@@ -167,14 +169,14 @@ func TestErrors_ErrorTypeDetail_String(t *testing.T) {
 		},
 		{
 			name: "empty Field and Description",
-			input: ErrorTypeDetail{
+			input: client.ErrorTypeDetail{
 				Code: "test code",
 			},
 			expectedOutput: "test code",
 		},
 		{
 			name: "empty Description",
-			input: ErrorTypeDetail{
+			input: client.ErrorTypeDetail{
 				Code:  "test code",
 				Field: "test_field",
 			},
diff --git a/client/marker_settings_test.go b/client/marker_settings_test.go
index 0f63c6d..1f0e322 100644
--- a/client/marker_settings_test.go
+++ b/client/marker_settings_test.go
@@ -1,11 +1,13 @@
-package client
+package client_test
 
 import (
 	"context"
 	"testing"
 
-	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 	"github.com/stretchr/testify/assert"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
+	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 )
 
 func TestMarkerSettings(t *testing.T) {
@@ -13,13 +15,13 @@ func TestMarkerSettings(t *testing.T) {
 
 	ctx := context.Background()
 
-	var m *MarkerSetting
+	var m *client.MarkerSetting
 	var err error
 
 	c := newTestClient(t)
 	dataset := testDataset(t)
 
-	currentMarkerSetting := &MarkerSetting{
+	currentMarkerSetting := &client.MarkerSetting{
 		Type:  test.RandomStringWithPrefix("test.", 8),
 		Color: "#b71c1c",
 	}
@@ -78,6 +80,6 @@ func TestMarkerSettings(t *testing.T) {
 		_, err := c.MarkerSettings.Get(ctx, dataset, m.ID)
 
 		assert.Error(t, err)
-		assert.True(t, err.(*DetailedError).IsNotFound())
+		assert.True(t, err.(*client.DetailedError).IsNotFound())
 	})
 }
diff --git a/client/marker_test.go b/client/marker_test.go
index d2b34be..79a17a8 100644
--- a/client/marker_test.go
+++ b/client/marker_test.go
@@ -1,4 +1,4 @@
-package client
+package client_test
 
 import (
 	"context"
@@ -6,9 +6,11 @@ import (
 	"testing"
 	"time"
 
-	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
+	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 )
 
 func TestMarkers(t *testing.T) {
@@ -16,14 +18,14 @@ func TestMarkers(t *testing.T) {
 
 	ctx := context.Background()
 
-	var m *Marker
+	var m *client.Marker
 	var err error
 
 	c := newTestClient(t)
 	dataset := testDataset(t)
 
 	t.Run("Create", func(t *testing.T) {
-		data := &Marker{
+		data := &client.Marker{
 			Message:   fmt.Sprintf("Test run at %v", time.Now()),
 			Type:      test.RandomStringWithPrefix("test.", 8),
 			URL:       "http://example.com",
@@ -83,6 +85,6 @@ func TestMarkers(t *testing.T) {
 		_, err := c.Markers.Get(ctx, dataset, m.ID)
 
 		assert.Error(t, err)
-		assert.True(t, err.(*DetailedError).IsNotFound())
+		assert.True(t, err.(*client.DetailedError).IsNotFound())
 	})
 }
diff --git a/client/query_annotation_test.go b/client/query_annotation_test.go
index b7a0ef7..63fd3b5 100644
--- a/client/query_annotation_test.go
+++ b/client/query_annotation_test.go
@@ -1,9 +1,10 @@
-package client
+package client_test
 
 import (
 	"context"
 	"testing"
 
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
@@ -16,12 +17,12 @@ func TestQueryAnnotations(t *testing.T) {
 	c := newTestClient(t)
 	dataset := testDataset(t)
 
-	var queryAnnotation *QueryAnnotation
+	var queryAnnotation *client.QueryAnnotation
 	var err error
 
 	// no cleanup func needed as queries cannot be deleted
-	query, err := c.Queries.Create(ctx, dataset, &QuerySpec{
-		Calculations: []CalculationSpec{
+	query, err := c.Queries.Create(ctx, dataset, &client.QuerySpec{
+		Calculations: []client.CalculationSpec{
 			{
 				Op: "COUNT",
 			},
@@ -30,7 +31,7 @@ func TestQueryAnnotations(t *testing.T) {
 	require.NoError(t, err)
 
 	t.Run("Create", func(t *testing.T) {
-		data := &QueryAnnotation{
+		data := &client.QueryAnnotation{
 			Name:        "Query created by a test",
 			Description: "This derived column is created by a test",
 			QueryID:     *query.ID,
@@ -58,7 +59,7 @@ func TestQueryAnnotations(t *testing.T) {
 
 	t.Run("Update", func(t *testing.T) {
 		// change all the fields to test
-		data := &QueryAnnotation{
+		data := &client.QueryAnnotation{
 			ID:          queryAnnotation.ID,
 			Name:        "This is a new name for the query created by a test",
 			Description: "This is a new description",
@@ -79,7 +80,7 @@ func TestQueryAnnotations(t *testing.T) {
 	t.Run("Fail to Get deleted Query Annotation", func(t *testing.T) {
 		_, err := c.QueryAnnotations.Get(ctx, dataset, queryAnnotation.ID)
 
-		var de DetailedError
+		var de client.DetailedError
 		assert.Error(t, err)
 		assert.ErrorAs(t, err, &de)
 		assert.True(t, de.IsNotFound())
diff --git a/client/query_result_test.go b/client/query_result_test.go
index f234b49..bcc6edd 100644
--- a/client/query_result_test.go
+++ b/client/query_result_test.go
@@ -1,4 +1,4 @@
-package client
+package client_test
 
 import (
 	"context"
@@ -6,6 +6,8 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
 )
 
 func TestQueryResults(t *testing.T) {
@@ -13,24 +15,24 @@ func TestQueryResults(t *testing.T) {
 
 	ctx := context.Background()
 
-	var result *QueryResult
+	var result *client.QueryResult
 	var err error
 
 	c := newTestClient(t)
 	dataset := testDataset(t)
 
-	query, err := c.Queries.Create(ctx, dataset, &QuerySpec{
-		Calculations: []CalculationSpec{
+	query, err := c.Queries.Create(ctx, dataset, &client.QuerySpec{
+		Calculations: []client.CalculationSpec{
 			{
 				Op: "COUNT",
 			},
 		},
-		TimeRange: ToPtr(60 * 60 * 24),
+		TimeRange: client.ToPtr(60 * 60 * 24),
 	})
 	require.NoError(t, err)
 
 	t.Run("Create", func(t *testing.T) {
-		result, err = c.QueryResults.Create(ctx, dataset, &QueryResultRequest{
+		result, err = c.QueryResults.Create(ctx, dataset, &client.QueryResultRequest{
 			ID: *query.ID,
 		})
 
@@ -50,9 +52,9 @@ func TestQueryResults(t *testing.T) {
 	})
 
 	t.Run("Fail to Get bogus Query Result", func(t *testing.T) {
-		err := c.QueryResults.Get(ctx, dataset, &QueryResult{ID: "abcd1234"})
+		err := c.QueryResults.Get(ctx, dataset, &client.QueryResult{ID: "abcd1234"})
 
-		var de DetailedError
+		var de client.DetailedError
 		assert.Error(t, err)
 		assert.ErrorAs(t, err, &de)
 		assert.True(t, de.IsNotFound())
diff --git a/client/query_spec_test.go b/client/query_spec_test.go
index a90ab17..4367bd5 100644
--- a/client/query_spec_test.go
+++ b/client/query_spec_test.go
@@ -1,10 +1,12 @@
-package client
+package client_test
 
 import (
 	"context"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
 )
 
 // create a query with an elaborate QuerySpec as smoke test
@@ -16,58 +18,58 @@ func TestQuerySpec(t *testing.T) {
 	c := newTestClient(t)
 	dataset := testDataset(t)
 
-	query := QuerySpec{
-		Calculations: []CalculationSpec{
+	query := client.QuerySpec{
+		Calculations: []client.CalculationSpec{
 			{
-				Op: CalculationOpCount,
+				Op: client.CalculationOpCount,
 			},
 			{
-				Op:     CalculationOpHeatmap,
-				Column: ToPtr("duration_ms"),
+				Op:     client.CalculationOpHeatmap,
+				Column: client.ToPtr("duration_ms"),
 			},
 			{
-				Op:     CalculationOpP99,
-				Column: ToPtr("duration_ms"),
+				Op:     client.CalculationOpP99,
+				Column: client.ToPtr("duration_ms"),
 			},
 		},
-		Filters: []FilterSpec{
+		Filters: []client.FilterSpec{
 			{
 				Column: "column_1",
-				Op:     FilterOpExists,
+				Op:     client.FilterOpExists,
 			},
 			{
 				Column: "duration_ms",
-				Op:     FilterOpSmallerThan,
+				Op:     client.FilterOpSmallerThan,
 				Value:  10000.0,
 			},
 			{
 				Column: "column_1",
-				Op:     FilterOpNotEquals,
+				Op:     client.FilterOpNotEquals,
 				Value:  "",
 			},
 		},
-		FilterCombination: FilterCombinationOr,
+		FilterCombination: client.FilterCombinationOr,
 		Breakdowns:        []string{"column_1", "column_2"},
-		Orders: []OrderSpec{
+		Orders: []client.OrderSpec{
 			{
-				Column: ToPtr("column_1"),
+				Column: client.ToPtr("column_1"),
 			},
 			{
-				Op:    ToPtr(CalculationOpCount),
-				Order: ToPtr(SortOrderDesc),
+				Op:    client.ToPtr(client.CalculationOpCount),
+				Order: client.ToPtr(client.SortOrderDesc),
 			},
 		},
-		Havings: []HavingSpec{
+		Havings: []client.HavingSpec{
 			{
-				Column:      ToPtr("duration_ms"),
-				Op:          ToPtr(HavingOpGreaterThan),
-				CalculateOp: ToPtr(CalculationOpP99),
+				Column:      client.ToPtr("duration_ms"),
+				Op:          client.ToPtr(client.HavingOpGreaterThan),
+				CalculateOp: client.ToPtr(client.CalculationOpP99),
 				Value:       1000.0,
 			},
 		},
-		Limit:       ToPtr(100),
-		TimeRange:   ToPtr(3600), // 1 hour
-		Granularity: ToPtr(60),   // 1 minute
+		Limit:       client.ToPtr(100),
+		TimeRange:   client.ToPtr(3600), // 1 hour
+		Granularity: client.ToPtr(60),   // 1 minute
 	}
 
 	_, err := c.Queries.Create(ctx, dataset, &query)
@@ -79,39 +81,39 @@ func TestQuerySpec_EquivalentTo(t *testing.T) {
 
 	tests := []struct {
 		name string
-		a, b QuerySpec
+		a, b client.QuerySpec
 		want bool
 	}{
-		{"Empty", QuerySpec{}, QuerySpec{}, true},
+		{"Empty", client.QuerySpec{}, client.QuerySpec{}, true},
 		{
 			"Empty Defaults",
-			QuerySpec{
-				Calculations: []CalculationSpec{
+			client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
 						Op: "COUNT",
 					},
 				},
 				FilterCombination: "AND",
-				TimeRange:         ToPtr(DefaultQueryTimeRange),
+				TimeRange:         client.ToPtr(client.DefaultQueryTimeRange),
 				// Granularity may be exported out of the Query Builder as '0' when not provided
-				Granularity: ToPtr(0),
+				Granularity: client.ToPtr(0),
 			},
-			QuerySpec{},
+			client.QuerySpec{},
 			true,
 		},
 		{
 			"Equivalent but shuffled",
-			QuerySpec{
-				Calculations: []CalculationSpec{
+			client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
 						Op:     "HEATMAP",
-						Column: ToPtr("duration_ms"),
+						Column: client.ToPtr("duration_ms"),
 					},
 					{
 						Op: "COUNT",
 					},
 				},
-				Filters: []FilterSpec{
+				Filters: []client.FilterSpec{
 					{
 						Column: "colA",
 						Op:     "=",
@@ -129,19 +131,19 @@ func TestQuerySpec_EquivalentTo(t *testing.T) {
 					},
 				},
 				Breakdowns: []string{"colB", "colA"},
-				TimeRange:  ToPtr(DefaultQueryTimeRange),
+				TimeRange:  client.ToPtr(client.DefaultQueryTimeRange),
 			},
-			QuerySpec{
-				Calculations: []CalculationSpec{
+			client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
 						Op:     "HEATMAP",
-						Column: ToPtr("duration_ms"),
+						Column: client.ToPtr("duration_ms"),
 					},
 					{
 						Op: "COUNT",
 					},
 				},
-				Filters: []FilterSpec{
+				Filters: []client.FilterSpec{
 					{
 						Column: "colC",
 						Op:     "=",
@@ -165,25 +167,25 @@ func TestQuerySpec_EquivalentTo(t *testing.T) {
 		},
 		{
 			"Calculation order matters",
-			QuerySpec{
-				Calculations: []CalculationSpec{
+			client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
 						Op:     "HEATMAP",
-						Column: ToPtr("duration_ms"),
+						Column: client.ToPtr("duration_ms"),
 					},
 					{
 						Op: "COUNT",
 					},
 				},
 			},
-			QuerySpec{
-				Calculations: []CalculationSpec{
+			client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
 						Op: "COUNT",
 					},
 					{
 						Op:     "HEATMAP",
-						Column: ToPtr("duration_ms"),
+						Column: client.ToPtr("duration_ms"),
 					},
 				},
 			},
@@ -191,16 +193,16 @@ func TestQuerySpec_EquivalentTo(t *testing.T) {
 		},
 		{
 			"Different time ranges",
-			QuerySpec{
-				Calculations: []CalculationSpec{
+			client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
 						Op: "COUNT",
 					},
 				},
-				TimeRange: ToPtr(1800),
+				TimeRange: client.ToPtr(1800),
 			},
-			QuerySpec{
-				Calculations: []CalculationSpec{
+			client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
 						Op: "COUNT",
 					},
@@ -210,40 +212,40 @@ func TestQuerySpec_EquivalentTo(t *testing.T) {
 		},
 		{
 			"Different FilterCombinations",
-			QuerySpec{
+			client.QuerySpec{
 				FilterCombination: "OR",
 			},
-			QuerySpec{},
+			client.QuerySpec{},
 			false,
 		},
 		{
 			"Calculation different from DefaultCalc",
-			QuerySpec{
-				Calculations: []CalculationSpec{
+			client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
 						Op:     "MIN",
-						Column: ToPtr("metrics.cpu.utilization"),
+						Column: client.ToPtr("metrics.cpu.utilization"),
 					},
 				},
 			},
-			QuerySpec{},
+			client.QuerySpec{},
 			false,
 		},
 		{
 			"Different Calculations",
-			QuerySpec{
-				Calculations: []CalculationSpec{
+			client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
 						Op:     "MIN",
-						Column: ToPtr("metrics.cpu.utilization"),
+						Column: client.ToPtr("metrics.cpu.utilization"),
 					},
 				},
 			},
-			QuerySpec{
-				Calculations: []CalculationSpec{
+			client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
 						Op:     "MAX",
-						Column: ToPtr("metrics.cpu.utilization"),
+						Column: client.ToPtr("metrics.cpu.utilization"),
 					},
 				},
 			},
@@ -251,22 +253,22 @@ func TestQuerySpec_EquivalentTo(t *testing.T) {
 		},
 		{
 			"Different Number of Calculations",
-			QuerySpec{
-				Calculations: []CalculationSpec{
+			client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
 						Op:     "MIN",
-						Column: ToPtr("metrics.cpu.utilization"),
+						Column: client.ToPtr("metrics.cpu.utilization"),
 					},
 				},
 			},
-			QuerySpec{
-				Calculations: []CalculationSpec{
+			client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
 						Op: "COUNT_DISTINCT",
 					},
 					{
 						Op:     "MAX",
-						Column: ToPtr("metrics.cpu.utilization"),
+						Column: client.ToPtr("metrics.cpu.utilization"),
 					},
 				},
 			},
@@ -274,16 +276,16 @@ func TestQuerySpec_EquivalentTo(t *testing.T) {
 		},
 		{
 			"Equivalent column orders",
-			QuerySpec{
-				Orders: []OrderSpec{
-					{Column: ToPtr("column_1")},
+			client.QuerySpec{
+				Orders: []client.OrderSpec{
+					{Column: client.ToPtr("column_1")},
 				},
 			},
-			QuerySpec{
-				Orders: []OrderSpec{
+			client.QuerySpec{
+				Orders: []client.OrderSpec{
 					{
-						Column: ToPtr("column_1"),
-						Order:  ToPtr(SortOrderAsc),
+						Column: client.ToPtr("column_1"),
+						Order:  client.ToPtr(client.SortOrderAsc),
 					},
 				},
 			},
@@ -291,16 +293,16 @@ func TestQuerySpec_EquivalentTo(t *testing.T) {
 		},
 		{
 			"Not equivalent column orders",
-			QuerySpec{
-				Orders: []OrderSpec{
-					{Column: ToPtr("column_2")},
+			client.QuerySpec{
+				Orders: []client.OrderSpec{
+					{Column: client.ToPtr("column_2")},
 				},
 			},
-			QuerySpec{
-				Orders: []OrderSpec{
+			client.QuerySpec{
+				Orders: []client.OrderSpec{
 					{
-						Column: ToPtr("column_1"),
-						Order:  ToPtr(SortOrderAsc),
+						Column: client.ToPtr("column_1"),
+						Order:  client.ToPtr(client.SortOrderAsc),
 					},
 				},
 			},
@@ -308,37 +310,37 @@ func TestQuerySpec_EquivalentTo(t *testing.T) {
 		},
 		{
 			"Equivalent Op orders with unspecified default",
-			QuerySpec{
-				Orders: []OrderSpec{
+			client.QuerySpec{
+				Orders: []client.OrderSpec{
 					{
-						Op:    ToPtr(CalculationOpCount),
-						Order: ToPtr(SortOrderAsc),
+						Op:    client.ToPtr(client.CalculationOpCount),
+						Order: client.ToPtr(client.SortOrderAsc),
 					},
 				},
 			},
-			QuerySpec{
-				Orders: []OrderSpec{
-					{Op: ToPtr(CalculationOpCount)},
+			client.QuerySpec{
+				Orders: []client.OrderSpec{
+					{Op: client.ToPtr(client.CalculationOpCount)},
 				},
 			},
 			true,
 		},
 		{
 			"Not equivalent Op orders",
-			QuerySpec{
-				Orders: []OrderSpec{
+			client.QuerySpec{
+				Orders: []client.OrderSpec{
 					{
-						Op:     ToPtr(CalculationOpCountDistinct),
-						Column: ToPtr("column_1"),
-						Order:  ToPtr(SortOrderAsc),
+						Op:     client.ToPtr(client.CalculationOpCountDistinct),
+						Column: client.ToPtr("column_1"),
+						Order:  client.ToPtr(client.SortOrderAsc),
 					},
 				},
 			},
-			QuerySpec{
-				Orders: []OrderSpec{
+			client.QuerySpec{
+				Orders: []client.OrderSpec{
 					{
-						Op:    ToPtr(CalculationOpCount),
-						Order: ToPtr(SortOrderDesc),
+						Op:    client.ToPtr(client.CalculationOpCount),
+						Order: client.ToPtr(client.SortOrderDesc),
 					},
 				},
 			},
diff --git a/client/query_test.go b/client/query_test.go
index 820e4ca..e1c576b 100644
--- a/client/query_test.go
+++ b/client/query_test.go
@@ -1,9 +1,10 @@
-package client
+package client_test
 
 import (
 	"context"
 	"testing"
 
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
@@ -16,47 +17,47 @@ func TestQueries(t *testing.T) {
 	c := newTestClient(t)
 	dataset := testDataset(t)
 
-	var query *QuerySpec
+	var query *client.QuerySpec
 	var err error
 
 	floatCol, col1, col2 := createRandomTestColumns(t, c, dataset)
 
 	t.Run("Create", func(t *testing.T) {
-		data := &QuerySpec{
-			Calculations: []CalculationSpec{
+		data := &client.QuerySpec{
+			Calculations: []client.CalculationSpec{
 				{
-					Op: CalculationOpCount,
+					Op: client.CalculationOpCount,
 				},
 				{
-					Op:     CalculationOpHeatmap,
+					Op:     client.CalculationOpHeatmap,
 					Column: &floatCol.KeyName,
 				},
 			},
-			Filters: []FilterSpec{
+			Filters: []client.FilterSpec{
 				{
 					Column: col1.KeyName,
-					Op:     FilterOpExists,
+					Op:     client.FilterOpExists,
 				},
 				{
 					Column: floatCol.KeyName,
-					Op:     FilterOpSmallerThan,
+					Op:     client.FilterOpSmallerThan,
 					Value:  10000.0,
 				},
 			},
-			FilterCombination: FilterCombinationOr,
+			FilterCombination: client.FilterCombinationOr,
 			Breakdowns:        []string{col1.KeyName, col2.KeyName},
-			Orders: []OrderSpec{
+			Orders: []client.OrderSpec{
 				{
 					Column: &col1.KeyName,
 				},
 				{
-					Op:    ToPtr(CalculationOpCount),
-					Order: ToPtr(SortOrderDesc),
+					Op:    client.ToPtr(client.CalculationOpCount),
+					Order: client.ToPtr(client.SortOrderDesc),
 				},
 			},
-			Limit:       ToPtr(100),
-			TimeRange:   ToPtr(3600), // 1 hour
-			Granularity: ToPtr(60),   // 1 minute
+			Limit:       client.ToPtr(100),
+			TimeRange:   client.ToPtr(3600), // 1 hour
+			Granularity: client.ToPtr(60),   // 1 minute
 		}
 
 		query, err = c.Queries.Create(ctx, dataset, data)
diff --git a/client/recipient_test.go b/client/recipient_test.go
index 82ec4d8..b346c12 100644
--- a/client/recipient_test.go
+++ b/client/recipient_test.go
@@ -1,13 +1,15 @@
-package client
+package client_test
 
 import (
 	"context"
 	"testing"
 	"time"
 
-	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
+	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 )
 
 func TestRecipientsEmail(t *testing.T) {
@@ -15,15 +17,15 @@ func TestRecipientsEmail(t *testing.T) {
 
 	ctx := context.Background()
 
-	var rcpt *Recipient
+	var rcpt *client.Recipient
 	var err error
 
 	c := newTestClient(t)
 
 	t.Run("Create", func(t *testing.T) {
-		data := &Recipient{
-			Type: RecipientTypeEmail,
-			Details: RecipientDetails{
+		data := &client.Recipient{
+			Type: client.RecipientTypeEmail,
+			Details: client.RecipientDetails{
 				EmailAddress: test.RandomString(8) + "@example.com",
 			},
 		}
@@ -71,7 +73,7 @@ func TestRecipientsEmail(t *testing.T) {
 	t.Run("Fail to Get deleted Recipient", func(t *testing.T) {
 		_, err := c.Recipients.Get(ctx, rcpt.ID)
 
-		var de DetailedError
+		var de client.DetailedError
 		assert.Error(t, err)
 		assert.ErrorAs(t, err, &de)
 		assert.True(t, de.IsNotFound())
@@ -84,18 +86,18 @@ func TestRecipientsWebhooksandMSTeams(t *testing.T) {
 	ctx := context.Background()
 	c := newTestClient(t)
 
-	testRcpts := []Recipient{
+	testRcpts := []client.Recipient{
 		{
-			Type: RecipientTypeWebhook,
-			Details: RecipientDetails{
+			Type: client.RecipientTypeWebhook,
+			Details: client.RecipientDetails{
 				WebhookName:   test.RandomStringWithPrefix("test.", 10),
 				WebhookURL:    "https://example.com",
 				WebhookSecret: "secret",
 			},
 		},
 		{
-			Type: RecipientTypeMSTeams,
-			Details: RecipientDetails{
+			Type: client.RecipientTypeMSTeams,
+			Details: client.RecipientDetails{
 				WebhookName: test.RandomStringWithPrefix("test.", 10),
 				WebhookURL:  "https://corp.office.com/webhook",
 			},
diff --git a/client/slo_test.go b/client/slo_test.go
index d5605c8..1d889d0 100644
--- a/client/slo_test.go
+++ b/client/slo_test.go
@@ -1,12 +1,14 @@
-package client
+package client_test
 
 import (
 	"context"
 	"testing"
 
-	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
+	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 )
 
 func TestSLOs(t *testing.T) {
@@ -14,13 +16,13 @@ func TestSLOs(t *testing.T) {
 
 	ctx := context.Background()
 
-	var slo *SLO
+	var slo *client.SLO
 	var err error
 
 	c := newTestClient(t)
 	dataset := testDataset(t)
 
-	sli, err := c.DerivedColumns.Create(ctx, dataset, &DerivedColumn{
+	sli, err := c.DerivedColumns.Create(ctx, dataset, &client.DerivedColumn{
 		Alias:      test.RandomStringWithPrefix("test.", 10),
 		Expression: "BOOL(1)",
 	})
@@ -33,12 +35,12 @@ func TestSLOs(t *testing.T) {
 	})
 
 	t.Run("Create", func(t *testing.T) {
-		data := &SLO{
+		data := &client.SLO{
 			Name:             test.RandomStringWithPrefix("test.", 10),
 			Description:      "My Super Sweet Test",
 			TimePeriodDays:   30,
 			TargetPerMillion: 995000,
-			SLI:              SLIRef{Alias: sli.Alias},
+			SLI:              client.SLIRef{Alias: sli.Alias},
 		}
 		slo, err = c.SLOs.Create(ctx, dataset, data)
 
@@ -90,7 +92,7 @@ func TestSLOs(t *testing.T) {
 	t.Run("Fail to Get deleted SLO", func(t *testing.T) {
 		_, err := c.SLOs.Get(ctx, dataset, slo.ID)
 
-		var de DetailedError
+		var de client.DetailedError
 		assert.Error(t, err)
 		assert.ErrorAs(t, err, &de)
 		assert.True(t, de.IsNotFound())
diff --git a/client/trigger_test.go b/client/trigger_test.go
index 4b1d050..e4fa94e 100644
--- a/client/trigger_test.go
+++ b/client/trigger_test.go
@@ -1,13 +1,15 @@
-package client
+package client_test
 
 import (
 	"context"
 	"errors"
 	"testing"
 
-	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/client"
+	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
 )
 
 func TestTriggers(t *testing.T) {
@@ -15,7 +17,7 @@ func TestTriggers(t *testing.T) {
 
 	ctx := context.Background()
 
-	var trigger *Trigger
+	var trigger *client.Trigger
 	var err error
 
 	c := newTestClient(t)
@@ -23,39 +25,39 @@ func TestTriggers(t *testing.T) {
 	floatCol, col1, col2 := createRandomTestColumns(t, c, dataset)
 
 	t.Run("Create", func(t *testing.T) {
-		data := &Trigger{
+		data := &client.Trigger{
 			Name:        test.RandomStringWithPrefix("test.", 8),
 			Description: "Some description",
 			Disabled:    true,
-			Query: &QuerySpec{
+			Query: &client.QuerySpec{
 				Breakdowns: nil,
-				Calculations: []CalculationSpec{
+				Calculations: []client.CalculationSpec{
 					{
-						Op:     CalculationOpP99,
+						Op:     client.CalculationOpP99,
 						Column: &floatCol.KeyName,
 					},
 				},
-				Filters: []FilterSpec{
+				Filters: []client.FilterSpec{
 					{
 						Column: col1.KeyName,
-						Op:     FilterOpExists,
+						Op:     client.FilterOpExists,
 					},
 					{
 						Column: col2.KeyName,
-						Op:     FilterOpContains,
+						Op:     client.FilterOpContains,
 						Value:  "foobar",
 					},
 				},
-				FilterCombination: FilterCombinationOr,
+				FilterCombination: client.FilterCombinationOr,
 			},
 			Frequency: 300,
-			Threshold: &TriggerThreshold{
-				Op:    TriggerThresholdOpGreaterThan,
+			Threshold: &client.TriggerThreshold{
+				Op:    client.TriggerThresholdOpGreaterThan,
 				Value: 10000,
 			},
-			Recipients: []NotificationRecipient{
+			Recipients: []client.NotificationRecipient{
 				{
-					Type:   RecipientTypeMarker,
+					Type:   client.RecipientTypeMarker,
 					Target: "This marker is created by a trigger",
 				},
 			},
@@ -70,12 +72,12 @@ func TestTriggers(t *testing.T) {
 		data.AlertType = trigger.AlertType
 		data.Recipients[0].ID = trigger.Recipients[0].ID
 		// set default time range
-		data.Query.TimeRange = ToPtr(300)
+		data.Query.TimeRange = client.ToPtr(300)
 
 		// set the default alert type
-		data.AlertType = TriggerAlertTypeOnChange
+		data.AlertType = client.TriggerAlertTypeOnChange
 		// set the default evaluation window type
-		data.EvaluationScheduleType = TriggerEvaluationScheduleFrequency
+		data.EvaluationScheduleType = client.TriggerEvaluationScheduleFrequency
 		// set the default threshold exceeded limit
 		data.Threshold.ExceededLimit = 1
 
@@ -100,11 +102,11 @@ func TestTriggers(t *testing.T) {
 		trigger.Description = "A new description"
 
 		// update the alert type to on true
-		trigger.AlertType = TriggerAlertTypeOnTrue
+		trigger.AlertType = client.TriggerAlertTypeOnTrue
 		// update the evaluation schedule to a window type
-		trigger.EvaluationScheduleType = TriggerEvaluationScheduleWindow
-		trigger.EvaluationSchedule = &TriggerEvaluationSchedule{
-			Window: TriggerEvaluationWindow{
+		trigger.EvaluationScheduleType = client.TriggerEvaluationScheduleWindow
+		trigger.EvaluationSchedule = &client.TriggerEvaluationSchedule{
+			Window: client.TriggerEvaluationWindow{
 				DaysOfWeek: []string{"monday", "wednesday", "friday"},
 				StartTime:  "13:00",
 				EndTime:    "21:00",
@@ -130,7 +132,7 @@ func TestTriggers(t *testing.T) {
 	t.Run("Fail to Get deleted Trigger", func(t *testing.T) {
 		_, err := c.Triggers.Get(ctx, dataset, trigger.ID)
 
-		var de DetailedError
+		var de client.DetailedError
 		assert.Error(t, err)
 		assert.ErrorAs(t, err, &de)
 		assert.True(t, de.IsNotFound())
@@ -141,56 +143,56 @@ func TestMatchesTriggerSubset(t *testing.T) {
 	t.Parallel()
 
 	cases := []struct {
-		in          QuerySpec
+		in          client.QuerySpec
 		expectedErr error
 	}{
 		{
-			in: QuerySpec{
-				Calculations: []CalculationSpec{
+			in: client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
-						Op: CalculationOpCount,
+						Op: client.CalculationOpCount,
 					},
 				},
 			},
 			expectedErr: nil,
 		},
 		{
-			in: QuerySpec{
+			in: client.QuerySpec{
 				Calculations: nil,
 			},
 			expectedErr: errors.New("a trigger query should contain exactly one calculation"),
 		},
 		{
-			in: QuerySpec{
-				Calculations: []CalculationSpec{
+			in: client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
-						Op: CalculationOpHeatmap,
+						Op: client.CalculationOpHeatmap,
 					},
 				},
 			},
 			expectedErr: errors.New("a trigger query may not contain a HEATMAP calculation"),
 		},
 		{
-			in: QuerySpec{
-				Calculations: []CalculationSpec{
+			in: client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
-						Op: CalculationOpCount,
+						Op: client.CalculationOpCount,
 					},
 				},
-				Limit: ToPtr(100),
+				Limit: client.ToPtr(100),
 			},
 			expectedErr: errors.New("limit is not allowed in a trigger query"),
 		},
 		{
-			in: QuerySpec{
-				Calculations: []CalculationSpec{
+			in: client.QuerySpec{
+				Calculations: []client.CalculationSpec{
 					{
-						Op: CalculationOpCount,
+						Op: client.CalculationOpCount,
 					},
 				},
-				Orders: []OrderSpec{
+				Orders: []client.OrderSpec{
 					{
-						Column: ToPtr(test.RandomStringWithPrefix("test.", 8)),
+						Column: client.ToPtr(test.RandomStringWithPrefix("test.", 8)),
 					},
 				},
 			},
@@ -199,7 +201,7 @@ func TestMatchesTriggerSubset(t *testing.T) {
 	}
 
 	for i, c := range cases {
-		err := MatchesTriggerSubset(&c.in)
+		err := client.MatchesTriggerSubset(&c.in)
 
 		assert.Equal(t, c.expectedErr, err, "Test case %d, QuerySpec: %v", i, c.in)
 	}
diff --git a/honeycombio/provider_test.go b/honeycombio/provider_test.go
index 4a474dd..5421b8b 100644
--- a/honeycombio/provider_test.go
+++ b/honeycombio/provider_test.go
@@ -32,7 +32,7 @@ var testAccProviderFactories = map[string]func() (*schema.Provider, error){
 }
 
 func testAccClient(t *testing.T) *honeycombio.Client {
-	c, err := honeycombio.NewClient(honeycombio.DefaultConfig())
+	c, err := honeycombio.NewClient()
 	if err != nil {
 		t.Fatalf("could not initialize honeycombio.Client: %v", err)
 	}
diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go
index 5ab6f5f..d91ab3c 100644
--- a/internal/provider/provider_test.go
+++ b/internal/provider/provider_test.go
@@ -63,7 +63,7 @@ func testAccDataset() string {
 }
 
 func testAccClient(t *testing.T) *client.Client {
-	c, err := client.NewClient(client.DefaultConfig())
+	c, err := client.NewClient()
 	if err != nil {
 		t.Fatalf("could not initialize Honeycomb client: %v", err)
 	}