/// <summary>
        /// This POST operation rates a package for one or more services before a shipment label is purchased and printed.
        ///
        /// Things to Consider:
        ///     * In order to rate a package for a single service, you must specify the rates.parcelType and rates.serviceId fields.
        ///     * In order to rate a package for multiple services (Rate Shopping) for a single parcel type, you must specify the
        ///     rates.parcelType field and omit the rates.serviceId field.
        ///     * You can also find rates for multiple parcel types and services with one call by omitting both the rates.parcelType
        ///     and rates.serviceId fields.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="request"></param>
        /// <param name="session"></param>
        /// <returns></returns>
        public async static Task <ShippingApiResponse <T> > Rates <T>(T request, ISession session = null) where T : IShipment, new()
        {
            var ratesRequest = new JsonShipment <T>(request);

            return(await WebMethod.Post <T, JsonShipment <T> >("/shippingservices/v1/rates", ratesRequest, session));
        }
        /// <summary>
        /// <para>
        /// This POST operation creates a shipment and purchases a shipment label.The API returns the label as either a Base64 string or a link
        /// to a PDF.
        /// </para>
        /// <para>
        /// Scan-Based Return Shipment
        /// </para>
        /// <para>
        /// This operation prints a USPS scan-based return (SBR) label. Unlike prepaid return services, SBR services allow you to print return
        /// labels without incurring postage charges at the time of print. Postage is automatically deducted only when the return label is scanned
        /// into the USPS mail stream. If the label is not used, no charges incur.
        /// </para>
        /// Before you can print SBR labels, you must enable SBR services on your account. To enable this service, please contact the PB support
        /// team at: ShippingAPISupport @pb.com.
        /// <para>
        /// PMOD Shipment
        /// </para>
        /// Priority Mail Open and Distribute (PMOD) expedites the movement of lower classes of mail by using Priority Mail to send the mailings to
        /// a destination center for processing.Shippers place mail pieces into an approved USPS Priority Mail container(sack, tray, or tub), affix
        /// a PMOD address label to the container, and ship the container to a USPS authorized acceptance location. The postal facility opens the
        /// container and processes the individual shipments according to their mail classes.The postage price is based on the weight of the contents
        /// (excluding the tare weight of the external container) and regular Priority Mail distance-based prices.
        /// <para>
        /// To begin printing PMOD labels, contact the PB support team at ShippingAPISupport @pb.com for requirements.
        /// </para>
        /// </summary>
        /// <typeparam name="T">Class to use for the shipment object. Implements IShipment</typeparam>
        /// <param name="request"></param>
        /// <param name="session"></param>
        /// <returns>ShippingApiResponse</returns>
        public async static Task <ShippingApiResponse <T> > CreateShipment <T>(T request, ISession session = null) where T : IShipment, new()
        {
            var wrapped = new JsonShipment <T>(request);

            return(WebMethod.Post <T, JsonShipment <T> >("/shippingservices/v1/shipments", wrapped, session).GetAwaiter().GetResult());
        }