func (api *APIv4Impl) Send(req *SMSRequest) (*SMSResponse, error) {
	reqBytes, err := json.Marshal(req)
	if err != nil {
		return nil, err
	}
	reqBuf := bytes.NewBuffer(reqBytes)
	for tryNum := 0; ; tryNum++ {
		rsp, err := api.sendTry(reqBuf)
		if err == nil {
			return rsp, nil
		}
		if IsAPIError(err) {
			apiErr := err.(*APIError)
			if apiErr.Code() != RCThrottlingError {
				return rsp, err
			}
		}
		if tryNum >= api.preferences.MaxRetries {
			return rsp, err
		}
		time.Sleep(api.preferences.RetryPeriod)
	}
}
Send SMS over API.
FIXME add retry scheme if Do returns error or API returns throughput error.
package smsgate
import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strconv"
	"time"
)
type APIv4Preferences struct {
	HTTPClient  *http.Client
	RetryPeriod time.Duration
	MaxRetries  int
	SubmitURL   string
}
var DefaultAPIv4Preferences = APIv4Preferences{
	HTTPClient:  http.DefaultClient,
	RetryPeriod: 1 * time.Second,
	MaxRetries:  3,
}
type APIv4Impl struct {
	preferences APIv4Preferences
}
func NewAPIv4Impl(preferences *APIv4Preferences) *APIv4Impl {
	apiV4 := &APIv4Impl{}
	if preferences == nil {
		apiV4.preferences = DefaultAPIv4Preferences
	} else {
		apiV4.preferences = *preferences
	}
	if apiV4.preferences.HTTPClient == nil {
		apiV4.preferences.HTTPClient = DefaultAPIv4Preferences.HTTPClient
	}
	if apiV4.preferences.RetryPeriod == 0 {
		apiV4.preferences.RetryPeriod = DefaultAPIv4Preferences.RetryPeriod
	}
	if apiV4.preferences.MaxRetries == 0 {
		apiV4.preferences.MaxRetries = DefaultAPIv4Preferences.MaxRetries
	}
	return apiV4
}
type ErrorObjWO struct {
	Error *ErrorWO `json:"error"`
}
type ErrorWO struct {
	Code        string       `json:"code"`
	Message     string       `json:"message"`
	Description string       `json:"description,omitempty"`
	Items       []*ErrorItem `json:"items,omitempty"`
}
type ErrorItem struct {
	Name        string `json:"name"`
	Message     string `json:"message,omitempty"`
	Description string `json:"description,omitempty"`
}