code: func (c *Client) Do(ctx context.Context, req *http.Request, resBody interface{}) error {
  	switch req.Method {
  	case http.MethodPost, http.MethodPatch:
  		req.Header.Set("Content-Type", "application/json")
  	}
  
  	req.Header.Set("Accept", "application/json")
  
  	if s, ok := ctx.Value(signerContext{}).(Signer); ok {
  		if err := s.SignRequest(req); err != nil {
  			return err
  		}
  	}
  
  	return c.Client.Do(ctx, req, func(res *http.Response) error {
  		switch res.StatusCode {
  		case http.StatusOK:
  		case http.StatusBadRequest:
  			// TODO: structured error types
  			detail, err := ioutil.ReadAll(res.Body)
  			if err != nil {
  				return err
  			}
  			return fmt.Errorf("%s: %s", res.Status, bytes.TrimSpace(detail))
  		default:
  			return fmt.Errorf("%s %s: %s", req.Method, req.URL, res.Status)
  		}
  
  		if resBody == nil {
  			return nil
  		}
  
  		switch b := resBody.(type) {
  		case io.Writer:
  			_, err := io.Copy(b, res.Body)
  			return err
  		default:
  			val := struct {
  				Value interface{} `json:"value,omitempty"`
  			}{
  				resBody,
  			}
  			return json.NewDecoder(res.Body).Decode(&val)
  		}
  	})
  }
docs: // Do sends the http.Request, decoding resBody if provided.