func (c *Client) MakeRequest(ctx context.Context, method string, pathPart string, data url.Values, v interface{}) error {
	if !strings.HasPrefix(pathPart, "/"+c.APIVersion) {
		pathPart = c.FullPath(pathPart)
	}
	rb := new(strings.Reader)
	if data != nil && (method == "POST" || method == "PUT") {
		rb = strings.NewReader(data.Encode())
	}
	if method == "GET" && data != nil {
		pathPart = pathPart + "?" + data.Encode()
	}
	req, err := c.NewRequest(method, pathPart, rb)
	if err != nil {
		return err
	}
	req = withContext(req, ctx)
	if ua := req.Header.Get("User-Agent"); ua == "" {
		req.Header.Set("User-Agent", userAgent)
	} else {
		req.Header.Set("User-Agent", userAgent+" "+ua)
	}
	return c.Do(req, &v)
}
Make a request to the Twilio API.
package twilio
import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
	"github.com/kevinburke/rest"
)
const Version = "2.2"
const userAgent = "twilio-go/" + Version
var BaseURL = "https://api.twilio.com"
var MonitorBaseURL = "https://monitor.twilio.com"
const MonitorVersion = "v1"
var PricingBaseURL = "https://pricing.twilio.com"
const PricingVersion = "v2"
var FaxBaseURL = "https://fax.twilio.com"
const FaxVersion = "v1"
var WirelessBaseURL = "https://wireless.twilio.com"
const WirelessVersion = "v1"
const APIVersion = "2010-04-01"
const NotifyBaseURL = "https://notify.twilio.com"
const NotifyVersion = "v1"
const LookupBaseURL = "https://lookups.twilio.com"
const LookupVersion = "v1"
const VerifyBaseURL = "https://verify.twilio.com"
const VerifyVersion = "v2"
var VideoBaseUrl = "https://video.twilio.com"
const VideoVersion = "v1"
var TaskRouterBaseUrl = "https://taskrouter.twilio.com"
const TaskRouterVersion = "v1"
type Client struct {
	*rest.Client
	Monitor    *Client
	Pricing    *Client
	Fax        *Client
	Wireless   *Client
	Notify     *Client
	Lookup     *Client
	Verify     *Client
	Video      *Client
	TaskRouter *Client
	FullPath func(pathPart string) string
	APIVersion string
	AccountSid string
	AuthToken  string
	Accounts          *AccountService
	Applications      *ApplicationService
	Calls             *CallService
	Conferences       *ConferenceService
	IncomingNumbers   *IncomingNumberService
	Keys              *KeyService
	Media             *MediaService
	Messages          *MessageService
	OutgoingCallerIDs *OutgoingCallerIDService
	Queues            *QueueService
	Recordings        *RecordingService
	Transcriptions    *TranscriptionService
	AvailableNumbers  *AvailableNumberService
	Alerts *AlertService
	Voice        *VoicePriceService
	Messaging    *MessagingPriceService
	PhoneNumbers *PhoneNumberPriceService
	Faxes *FaxService
	Sims     *SimService
	Commands *CommandService
	Credentials *NotifyCredentialsService
	LookupPhoneNumbers *LookupPhoneNumbersService
	Verifications *VerifyPhoneNumberService
	Rooms           *RoomService
	VideoRecordings *VideoRecordingService
	Workspace func(sid string) *WorkspaceService
}
const defaultTimeout = 30*time.Second + 500*time.Millisecond
var defaultHttpClient *http.Client
func init() {
	defaultHttpClient = &http.Client{
		Timeout:   defaultTimeout,
		Transport: rest.DefaultTransport,
	}
}
type twilioError struct {
	Code     int    `json:"code"`
	Message  string `json:"message"`
	MoreInfo string `json:"more_info"`
	Status int `json:"status"`
}
func parseTwilioError(resp *http.Response) error {
	resBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	if err := resp.Body.Close(); err != nil {
		return err
	}
	rerr := new(twilioError)
	err = json.Unmarshal(resBody, rerr)
	if err != nil {
		return fmt.Errorf("invalid response body: %s", string(resBody))
	}
	if rerr.Message == "" {
		return fmt.Errorf("invalid response body: %s", string(resBody))
	}
	return &rest.Error{
		Title:  rerr.Message,
		Type:   rerr.MoreInfo,
		ID:     strconv.Itoa(rerr.Code),
		Status: resp.StatusCode,
	}
}
func NewFaxClient(accountSid string, authToken string, httpClient *http.Client) *Client {
	if httpClient == nil {
		httpClient = defaultHttpClient
	}
	restClient := rest.NewClient(accountSid, authToken, FaxBaseURL)
	restClient.Client = httpClient
	restClient.UploadType = rest.FormURLEncoded
	restClient.ErrorParser = parseTwilioError
	c := &Client{
		Client:     restClient,
		AccountSid: accountSid,
		AuthToken:  authToken,
	}
	c.FullPath = func(pathPart string) string {
		return "/" + c.APIVersion + "/" + pathPart
	}
	c.APIVersion = FaxVersion
	c.Faxes = &FaxService{client: c}
	return c
}
func newNewClient(sid, token, baseURL string, client *http.Client) *Client {
	if client == nil {
		client = defaultHttpClient
	}
	restClient := rest.NewClient(sid, token, baseURL)
	restClient.Client = client
	restClient.UploadType = rest.FormURLEncoded
	restClient.ErrorParser = parseTwilioError
	c := &Client{
		Client:     restClient,
		AccountSid: sid,
		AuthToken:  token,
	}
	c.FullPath = func(pathPart string) string {
		return "/" + c.APIVersion + "/" + pathPart
	}
	return c
}
func NewWirelessClient(accountSid string, authToken string, httpClient *http.Client) *Client {
	c := newNewClient(accountSid, authToken, WirelessBaseURL, httpClient)
	c.APIVersion = WirelessVersion
	c.Sims = &SimService{client: c}
	c.Commands = &CommandService{client: c}
	return c
}
func NewMonitorClient(accountSid string, authToken string, httpClient *http.Client) *Client {
	c := newNewClient(accountSid, authToken, MonitorBaseURL, httpClient)
	c.APIVersion = MonitorVersion
	c.Alerts = &AlertService{client: c}
	return c
}
func NewTaskRouterClient(accountSid string, authToken string, httpClient *http.Client) *Client {
	if httpClient == nil {
		httpClient = &http.Client{Timeout: defaultTimeout}
	}
	c := newNewClient(accountSid, authToken, TaskRouterBaseUrl, httpClient)
	c.APIVersion = TaskRouterVersion
	c.Workspace = func(sid string) *WorkspaceService {
		return &WorkspaceService{
			Activities: &ActivityService{
				workspaceSid: sid,
				client:       c,
			},
			Queues: &TaskQueueService{
				workspaceSid: sid,
				client:       c,
			},
			Workflows: &WorkflowService{
				workspaceSid: sid,
				client:       c,
			},
			Workers: &WorkerService{
				workspaceSid: sid,
				client:       c,
			},
		}
	}
	return c
}
func NewPricingClient(accountSid string, authToken string, httpClient *http.Client) *Client {
	c := newNewClient(accountSid, authToken, PricingBaseURL, httpClient)
	c.APIVersion = PricingVersion
	c.Voice = &VoicePriceService{
		Countries: &CountryVoicePriceService{client: c},
		Numbers:   &NumberVoicePriceService{client: c},
	}
	c.Messaging = &MessagingPriceService{
		Countries: &CountryMessagingPriceService{client: c},
	}
	c.PhoneNumbers = &PhoneNumberPriceService{
		Countries: &CountryPhoneNumberPriceService{client: c},
	}
	return c
}
func NewNotifyClient(accountSid string, authToken string, httpClient *http.Client) *Client {
	c := newNewClient(accountSid, authToken, NotifyBaseURL, httpClient)
	c.APIVersion = NotifyVersion
	c.Credentials = &NotifyCredentialsService{client: c}
	return c
}
func NewLookupClient(accountSid string, authToken string, httpClient *http.Client) *Client {
	c := newNewClient(accountSid, authToken, LookupBaseURL, httpClient)
	c.APIVersion = LookupVersion
	c.LookupPhoneNumbers = &LookupPhoneNumbersService{client: c}
	return c
}
func NewVerifyClient(accountSid string, authToken string, httpClient *http.Client) *Client {
	c := newNewClient(accountSid, authToken, VerifyBaseURL, httpClient)
	c.APIVersion = VerifyVersion
	c.Verifications = &VerifyPhoneNumberService{client: c}
	return c
}
func NewVideoClient(accountSid string, authToken string, httpClient *http.Client) *Client {
	c := newNewClient(accountSid, authToken, VideoBaseUrl, httpClient)
	c.APIVersion = VideoVersion
	c.Rooms = &RoomService{client: c}
	c.VideoRecordings = &VideoRecordingService{client: c}
	return c
}
func NewClient(accountSid string, authToken string, httpClient *http.Client) *Client {
	if httpClient == nil {
		httpClient = defaultHttpClient
	}
	restClient := rest.NewClient(accountSid, authToken, BaseURL)
	restClient.Client = httpClient
	restClient.UploadType = rest.FormURLEncoded
	restClient.ErrorParser = parseTwilioError
	c := &Client{Client: restClient, AccountSid: accountSid, AuthToken: authToken}
	c.APIVersion = APIVersion
	c.FullPath = func(pathPart string) string {
		return "/" + strings.Join([]string{c.APIVersion, "Accounts", c.AccountSid, pathPart + ".json"}, "/")
	}
	c.Monitor = NewMonitorClient(accountSid, authToken, httpClient)
	c.Pricing = NewPricingClient(accountSid, authToken, httpClient)
	c.Fax = NewFaxClient(accountSid, authToken, httpClient)
	c.Wireless = NewWirelessClient(accountSid, authToken, httpClient)
	c.Notify = NewNotifyClient(accountSid, authToken, httpClient)
	c.Lookup = NewLookupClient(accountSid, authToken, httpClient)
	c.Verify = NewVerifyClient(accountSid, authToken, httpClient)
	c.Video = NewVideoClient(accountSid, authToken, httpClient)
	c.TaskRouter = NewTaskRouterClient(accountSid, authToken, httpClient)
	c.Accounts = &AccountService{client: c}
	c.Applications = &ApplicationService{client: c}
	c.Calls = &CallService{client: c}
	c.Conferences = &ConferenceService{client: c}
	c.Keys = &KeyService{client: c}
	c.Media = &MediaService{client: c}
	c.Messages = &MessageService{client: c}
	c.OutgoingCallerIDs = &OutgoingCallerIDService{client: c}
	c.Queues = &QueueService{client: c}
	c.Recordings = &RecordingService{client: c}
	c.Transcriptions = &TranscriptionService{client: c}
	c.IncomingNumbers = &IncomingNumberService{
		NumberPurchasingService: &NumberPurchasingService{
			client:   c,
			pathPart: "",
		},
		client: c,
		Local: &NumberPurchasingService{
			client:   c,
			pathPart: "Local",
		},
		TollFree: &NumberPurchasingService{
			client:   c,
			pathPart: "TollFree",
		},
	}
	c.AvailableNumbers = &AvailableNumberService{
		Local: &AvailableNumberBase{
			client:   c,
			pathPart: "Local",
		},
		Mobile: &AvailableNumberBase{
			client:   c,
			pathPart: "Mobile",
		},
		TollFree: &AvailableNumberBase{
			client:   c,
			pathPart: "TollFree",
		},
		SupportedCountries: &SupportedCountriesService{
			client: c,
		},
	}
	return c
}
func (c *Client) RequestOnBehalfOf(subaccountSid string) {
	c.FullPath = func(pathPart string) string {
		return "/" + strings.Join([]string{c.APIVersion, "Accounts", subaccountSid, pathPart + ".json"}, "/")
	}
}
func (c *Client) UseSecretKey(key string) {
	c.Client.ID = key
	if c.Monitor != nil {
		c.Monitor.UseSecretKey(key)
	}
	if c.Pricing != nil {
		c.Pricing.UseSecretKey(key)
	}
	if c.Fax != nil {
		c.Fax.UseSecretKey(key)
	}
	if c.Wireless != nil {
		c.Wireless.UseSecretKey(key)
	}
}
func (c *Client) GetResource(ctx context.Context, pathPart string, sid string, v interface{}) error {
	sidPart := strings.Join([]string{pathPart, sid}, "/")
	return c.MakeRequest(ctx, "GET", sidPart, nil, v)
}
func (c *Client) CreateResource(ctx context.Context, pathPart string, data url.Values, v interface{}) error {
	return c.MakeRequest(ctx, "POST", pathPart, data, v)
}
func (c *Client) UpdateResource(ctx context.Context, pathPart string, sid string, data url.Values, v interface{}) error {
	sidPart := strings.Join([]string{pathPart, sid}, "/")
	return c.MakeRequest(ctx, "POST", sidPart, data, v)
}
func (c *Client) DeleteResource(ctx context.Context, pathPart string, sid string) error {
	sidPart := strings.Join([]string{pathPart, sid}, "/")
	err := c.MakeRequest(ctx, "DELETE", sidPart, nil, nil)
	if err == nil {
		return nil
	}
	rerr, ok := err.(*rest.Error)
	if ok && rerr.Status == http.StatusNotFound {
		return nil
	}
	return err
}
func (c *Client) ListResource(ctx context.Context, pathPart string, data url.Values, v interface{}) error {
	return c.MakeRequest(ctx, "GET", pathPart, data, v)
}
func (c *Client) GetNextPage(ctx context.Context, fullUri string, v interface{}) error {
	fullUri = strings.TrimPrefix(fullUri, c.Base)
	return c.MakeRequest(ctx, "GET", fullUri, nil, v)
}