func (cli *Client) GetData(url *url.URL, target interface{}, options ...RequestOption) (*Response, error) {
	resp, err := cli.Get(url, options...)
	if err != nil {
		return nil, err
	}
	decoder := json.NewDecoder(bytes.NewReader(resp.Data))
	decoder.UseNumber()
	return resp, decoder.Decode(target)
}
GetData sends a GET request to the specified API endpoint and unmarshals the
JSON-encoded data received in the API response. The unmarshalled data is put
into the specified target. The target must be of an appropriate type capable
of receiving the data returned by the the endpoint. If the data returned by
the endpoint is an object you can use GetObject instead.
package vt
import (
	"bytes"
	"compress/gzip"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strings"
)
type Client struct {
	APIKey string
	Agent      string
	httpClient *http.Client
}
type requestOptions struct {
	headers map[string]string
}
type RequestOption func(*requestOptions)
func WithHeader(header, value string) RequestOption {
	return func(opts *requestOptions) {
		if opts.headers == nil {
			opts.headers = make(map[string]string)
		}
		opts.headers[header] = value
	}
}
func opts(opts ...RequestOption) *requestOptions {
	o := &requestOptions{}
	for _, opt := range opts {
		opt(o)
	}
	return o
}
type ClientOption func(*Client)
func WithHTTPClient(httpClient *http.Client) ClientOption {
	return func(c *Client) {
		c.httpClient = httpClient
	}
}
func NewClient(APIKey string, opts ...ClientOption) *Client {
	c := &Client{APIKey: APIKey, httpClient: &http.Client{}}
	for _, o := range opts {
		o(c)
	}
	return c
}
func (cli *Client) sendRequest(method string, url *url.URL, body io.Reader, headers map[string]string) (*http.Response, error) {
	req, err := http.NewRequest(method, url.String(), body)
	if err != nil {
		return nil, err
	}
	agent := cli.Agent
	if agent == "" {
		agent = "unknown"
	}
	req.Header.Set("User-Agent", fmt.Sprintf("%s; vtgo %s; gzip", agent, version))
	req.Header.Set("Accept-Encoding", "gzip")
	req.Header.Set("X-Apikey", cli.APIKey)
	if headers != nil {
		for k, v := range headers {
			req.Header.Set(k, v)
		}
	}
	return (cli.httpClient).Do(req)
}
func (cli *Client) parseResponse(resp *http.Response) (*Response, error) {
	apiresp := &Response{}
	if resp.ContentLength == 0 {
		return apiresp, nil
	}
	if !strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") {
		return nil, fmt.Errorf("Expecting JSON response from %s %s",
			resp.Request.Method, resp.Request.URL.String())
	}
	ungzipper, err := gzip.NewReader(resp.Body)
	if err != nil {
		return nil, err
	}
	defer ungzipper.Close()
	if err := json.NewDecoder(ungzipper).Decode(apiresp); err != nil {
		return nil, err
	}
	if apiresp.Error.Code != "" {
		return apiresp, apiresp.Error
	}
	return apiresp, nil
}
func (cli *Client) Get(url *url.URL, options ...RequestOption) (*Response, error) {
	o := opts(options...)
	httpResp, err := cli.sendRequest("GET", url, nil, o.headers)
	if err != nil {
		return nil, err
	}
	defer httpResp.Body.Close()
	return cli.parseResponse(httpResp)
}
func (cli *Client) Post(url *url.URL, req *Request, options ...RequestOption) (*Response, error) {
	var b []byte
	var err error
	if req != nil {
		b, err = json.Marshal(req)
		if err != nil {
			return nil, err
		}
	}
	o := opts(options...)
	httpResp, err := cli.sendRequest("POST", url, bytes.NewReader(b), o.headers)
	if err != nil {
		return nil, err
	}
	defer httpResp.Body.Close()
	return cli.parseResponse(httpResp)
}
func (cli *Client) Patch(url *url.URL, req *Request, options ...RequestOption) (*Response, error) {
	var b []byte
	var err error
	if req != nil {
		b, err = json.Marshal(req)
		if err != nil {
			return nil, err
		}
	}
	o := opts(options...)
	httpResp, err := cli.sendRequest("PATCH", url, bytes.NewReader(b), o.headers)
	if err != nil {
		return nil, err
	}
	defer httpResp.Body.Close()
	return cli.parseResponse(httpResp)
}
func (cli *Client) Delete(url *url.URL, options ...RequestOption) (*Response, error) {
	o := opts(options...)
	httpResp, err := cli.sendRequest("DELETE", url, nil, o.headers)
	if err != nil {
		return nil, err
	}
	defer httpResp.Body.Close()
	return cli.parseResponse(httpResp)
}