"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from .basesdk import BaseSDK
from enum import Enum
from postivo_client import errors, models, utils
from postivo_client._hooks import HookContext
from postivo_client.types import OptionalNullable, UNSET
from postivo_client.utils import get_security_from_env
from postivo_client.utils.unmarshal_json_response import unmarshal_json_response
from typing import Any, List, Mapping, Optional, Union


class StatusAcceptEnum(str, Enum):
    APPLICATION_JSON = "application/json"
    APPLICATION_PROBLEM_PLUS_JSON = "application/problem+json"


class CancelAcceptEnum(str, Enum):
    APPLICATION_JSON = "application/json"
    APPLICATION_PROBLEM_PLUS_JSON = "application/problem+json"


class DispatchAcceptEnum(str, Enum):
    APPLICATION_JSON = "application/json"
    APPLICATION_PROBLEM_PLUS_JSON = "application/problem+json"


class DocumentsAcceptEnum(str, Enum):
    APPLICATION_JSON = "application/json"
    APPLICATION_PROBLEM_PLUS_JSON = "application/problem+json"


class PriceAcceptEnum(str, Enum):
    APPLICATION_JSON = "application/json"
    APPLICATION_PROBLEM_PLUS_JSON = "application/problem+json"


class Shipments(BaseSDK):
    def status(
        self,
        *,
        ids: List[str],
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        accept_header_override: Optional[StatusAcceptEnum] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.GetStatusResponse:
        r"""Retrieve shipment details with status events

        Retrieve the current status and details for one or more shipments by their `ids`. Pass the unique shipment IDs (returned when the shipments were created) as a path parameter. To query provide a list (up to **50** IDs per call). For larger batches, split the requests.

        :param ids: Shipment IDs assigned by the system (comma-separated). The system accepts a maximum of **50** identifiers per call.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetStatusRequest(
            ids=ids,
        )

        req = self._build_request(
            method="GET",
            path="/shipment/{ids}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value=accept_header_override.value
            if accept_header_override is not None
            else "application/json;q=1, application/problem+json;q=0",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getStatus",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetStatusResponse(
                result=unmarshal_json_response(List[models.StatusDetails], http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(
            http_res, ["400", "401", "403", "404", "4XX"], "application/problem+json"
        ):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "5XX", "application/problem+json"):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "default", "application/problem+json"):
            return models.GetStatusResponse(
                result=unmarshal_json_response(models.ErrorResponse, http_res),
                headers={},
            )

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def status_async(
        self,
        *,
        ids: List[str],
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        accept_header_override: Optional[StatusAcceptEnum] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.GetStatusResponse:
        r"""Retrieve shipment details with status events

        Retrieve the current status and details for one or more shipments by their `ids`. Pass the unique shipment IDs (returned when the shipments were created) as a path parameter. To query provide a list (up to **50** IDs per call). For larger batches, split the requests.

        :param ids: Shipment IDs assigned by the system (comma-separated). The system accepts a maximum of **50** identifiers per call.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetStatusRequest(
            ids=ids,
        )

        req = self._build_request_async(
            method="GET",
            path="/shipment/{ids}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value=accept_header_override.value
            if accept_header_override is not None
            else "application/json;q=1, application/problem+json;q=0",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getStatus",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetStatusResponse(
                result=unmarshal_json_response(List[models.StatusDetails], http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(
            http_res, ["400", "401", "403", "404", "4XX"], "application/problem+json"
        ):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "5XX", "application/problem+json"):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "default", "application/problem+json"):
            return models.GetStatusResponse(
                result=unmarshal_json_response(models.ErrorResponse, http_res),
                headers={},
            )

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def cancel(
        self,
        *,
        ids: List[str],
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        accept_header_override: Optional[CancelAcceptEnum] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.CancelShipmentResponse:
        r"""Cancel shipments

        Cancel shipments that have not yet been processed by their `ids`. Pass the unique shipment IDs (returned when the shipment was created) as a parameter. To cancel multiple shipments at once, provide a list of IDs (up to **50** per call). For larger volumes, split the operation into multiple requests. Only shipments with status `ACCEPTED` can be cancelled.

        If duplicate shipment IDs are provided in a single call, the API processes each unique ID only once.

        :param ids: Shipment IDs assigned by the system (comma-separated). The system accepts a maximum of **50** identifiers per call.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.CancelShipmentRequest(
            ids=ids,
        )

        req = self._build_request(
            method="DELETE",
            path="/shipment/{ids}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value=accept_header_override.value
            if accept_header_override is not None
            else "application/json;q=1, application/problem+json;q=0",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="cancelShipment",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.CancelShipmentResponse(
                result=unmarshal_json_response(
                    List[models.ShipmentCancellation], http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(
            http_res, ["400", "401", "403", "404", "4XX"], "application/problem+json"
        ):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "5XX", "application/problem+json"):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "default", "application/problem+json"):
            return models.CancelShipmentResponse(
                result=unmarshal_json_response(models.ErrorResponse, http_res),
                headers={},
            )

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def cancel_async(
        self,
        *,
        ids: List[str],
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        accept_header_override: Optional[CancelAcceptEnum] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.CancelShipmentResponse:
        r"""Cancel shipments

        Cancel shipments that have not yet been processed by their `ids`. Pass the unique shipment IDs (returned when the shipment was created) as a parameter. To cancel multiple shipments at once, provide a list of IDs (up to **50** per call). For larger volumes, split the operation into multiple requests. Only shipments with status `ACCEPTED` can be cancelled.

        If duplicate shipment IDs are provided in a single call, the API processes each unique ID only once.

        :param ids: Shipment IDs assigned by the system (comma-separated). The system accepts a maximum of **50** identifiers per call.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.CancelShipmentRequest(
            ids=ids,
        )

        req = self._build_request_async(
            method="DELETE",
            path="/shipment/{ids}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value=accept_header_override.value
            if accept_header_override is not None
            else "application/json;q=1, application/problem+json;q=0",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="cancelShipment",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.CancelShipmentResponse(
                result=unmarshal_json_response(
                    List[models.ShipmentCancellation], http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(
            http_res, ["400", "401", "403", "404", "4XX"], "application/problem+json"
        ):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "5XX", "application/problem+json"):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "default", "application/problem+json"):
            return models.CancelShipmentResponse(
                result=unmarshal_json_response(models.ErrorResponse, http_res),
                headers={},
            )

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def dispatch(
        self,
        *,
        recipients: Union[
            models.ShipmentRecipients, models.ShipmentRecipientsTypedDict
        ],
        documents: Union[models.ShipmentDocuments, models.ShipmentDocumentsTypedDict],
        options: OptionalNullable[
            Union[models.Options, models.OptionsTypedDict]
        ] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        accept_header_override: Optional[DispatchAcceptEnum] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.ShipmentDispatchResponse:
        r"""Dispatch a new shipment

        Send a shipment to one or multiple recipients in a single request. Provide a `Shipment` object. The object includes properties that define the shipment (recipient details, included documents, and optional settings). Some fields are required.

        The system accepts up to **50** recipients per call. For larger volumes, split the operation into multiple requests.

        :param recipients: Recipient data for a single shipment. For one recipient, provide a `RecipientInline`, `RecipientFromAddressBook`, or `RecipientFromAddressBookByExternalId` object. For multiple recipients, provide an array of these objects (1–50).
        :param documents: Document payload to print and enclose into shipment. For a single document, provide `DocumentPdf`, `DocumentLibrary`, or `DocumentMock` (for checking the price only). For multiple documents, provide an array of `DocumentPdf`, `DocumentLibrary`, or `DocumentMock` objects (1–20).
        :param options:
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.Shipment(
            recipients=utils.get_pydantic_model(recipients, models.ShipmentRecipients),
            documents=utils.get_pydantic_model(documents, models.ShipmentDocuments),
            options=utils.get_pydantic_model(options, OptionalNullable[models.Options]),
        )

        req = self._build_request(
            method="POST",
            path="/shipment",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value=accept_header_override.value
            if accept_header_override is not None
            else "application/json;q=1, application/problem+json;q=0",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.Shipment
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="shipmentDispatch",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.ShipmentDispatchResponse(
                result=unmarshal_json_response(List[models.ShipmentDetails], http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(
            http_res, ["400", "401", "403", "4XX"], "application/problem+json"
        ):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "5XX", "application/problem+json"):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "default", "application/problem+json"):
            return models.ShipmentDispatchResponse(
                result=unmarshal_json_response(models.ErrorResponse, http_res),
                headers={},
            )

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def dispatch_async(
        self,
        *,
        recipients: Union[
            models.ShipmentRecipients, models.ShipmentRecipientsTypedDict
        ],
        documents: Union[models.ShipmentDocuments, models.ShipmentDocumentsTypedDict],
        options: OptionalNullable[
            Union[models.Options, models.OptionsTypedDict]
        ] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        accept_header_override: Optional[DispatchAcceptEnum] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.ShipmentDispatchResponse:
        r"""Dispatch a new shipment

        Send a shipment to one or multiple recipients in a single request. Provide a `Shipment` object. The object includes properties that define the shipment (recipient details, included documents, and optional settings). Some fields are required.

        The system accepts up to **50** recipients per call. For larger volumes, split the operation into multiple requests.

        :param recipients: Recipient data for a single shipment. For one recipient, provide a `RecipientInline`, `RecipientFromAddressBook`, or `RecipientFromAddressBookByExternalId` object. For multiple recipients, provide an array of these objects (1–50).
        :param documents: Document payload to print and enclose into shipment. For a single document, provide `DocumentPdf`, `DocumentLibrary`, or `DocumentMock` (for checking the price only). For multiple documents, provide an array of `DocumentPdf`, `DocumentLibrary`, or `DocumentMock` objects (1–20).
        :param options:
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.Shipment(
            recipients=utils.get_pydantic_model(recipients, models.ShipmentRecipients),
            documents=utils.get_pydantic_model(documents, models.ShipmentDocuments),
            options=utils.get_pydantic_model(options, OptionalNullable[models.Options]),
        )

        req = self._build_request_async(
            method="POST",
            path="/shipment",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value=accept_header_override.value
            if accept_header_override is not None
            else "application/json;q=1, application/problem+json;q=0",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.Shipment
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="shipmentDispatch",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.ShipmentDispatchResponse(
                result=unmarshal_json_response(List[models.ShipmentDetails], http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(
            http_res, ["400", "401", "403", "4XX"], "application/problem+json"
        ):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "5XX", "application/problem+json"):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "default", "application/problem+json"):
            return models.ShipmentDispatchResponse(
                result=unmarshal_json_response(models.ErrorResponse, http_res),
                headers={},
            )

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def documents(
        self,
        *,
        id: str,
        type_: models.DocumentType,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        accept_header_override: Optional[DocumentsAcceptEnum] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.GetDocumentsResponse:
        r"""Retrieve documents related to a shipment

        Download documents related to a shipment by its `id`. Pass the unique shipment `id` (returned when the shipment was created) as a parameter. The second parameter is the document type to download. Supported document types include: dispatch certificate, envelope template, and EPO (in PDF or XML formats).

        :param id: Single shipment ID assigned by the system when the shipment was created.
        :param type: Type of document/certificate to generate.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetDocumentsRequest(
            id=id,
            type=type_,
        )

        req = self._build_request(
            method="GET",
            path="/shipment/{id}/document/{type}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value=accept_header_override.value
            if accept_header_override is not None
            else "application/json;q=1, application/problem+json;q=0",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getDocuments",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetDocumentsResponse(
                result=unmarshal_json_response(models.DocumentResponse, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(
            http_res, ["400", "401", "403", "404", "4XX"], "application/problem+json"
        ):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "5XX", "application/problem+json"):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "default", "application/problem+json"):
            return models.GetDocumentsResponse(
                result=unmarshal_json_response(models.ErrorResponse, http_res),
                headers={},
            )

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def documents_async(
        self,
        *,
        id: str,
        type_: models.DocumentType,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        accept_header_override: Optional[DocumentsAcceptEnum] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.GetDocumentsResponse:
        r"""Retrieve documents related to a shipment

        Download documents related to a shipment by its `id`. Pass the unique shipment `id` (returned when the shipment was created) as a parameter. The second parameter is the document type to download. Supported document types include: dispatch certificate, envelope template, and EPO (in PDF or XML formats).

        :param id: Single shipment ID assigned by the system when the shipment was created.
        :param type: Type of document/certificate to generate.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.GetDocumentsRequest(
            id=id,
            type=type_,
        )

        req = self._build_request_async(
            method="GET",
            path="/shipment/{id}/document/{type}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value=accept_header_override.value
            if accept_header_override is not None
            else "application/json;q=1, application/problem+json;q=0",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="getDocuments",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.GetDocumentsResponse(
                result=unmarshal_json_response(models.DocumentResponse, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(
            http_res, ["400", "401", "403", "404", "4XX"], "application/problem+json"
        ):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "5XX", "application/problem+json"):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "default", "application/problem+json"):
            return models.GetDocumentsResponse(
                result=unmarshal_json_response(models.ErrorResponse, http_res),
                headers={},
            )

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    def price(
        self,
        *,
        recipients: Union[
            models.ShipmentRecipients, models.ShipmentRecipientsTypedDict
        ],
        documents: Union[models.ShipmentDocuments, models.ShipmentDocumentsTypedDict],
        options: OptionalNullable[
            Union[models.Options, models.OptionsTypedDict]
        ] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        accept_header_override: Optional[PriceAcceptEnum] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.ShipmentPriceResponse:
        r"""Check the shipment price

        Check the price of a shipment for one or multiple recipients. Provide a `Shipment` object in the request. Each object includes properties such as recipient details, included documents, and optional settings. Some fields are required.

        The system accepts up to **50** recipients per call. For larger volumes, split the operation into multiple requests.

        :param recipients: Recipient data for a single shipment. For one recipient, provide a `RecipientInline`, `RecipientFromAddressBook`, or `RecipientFromAddressBookByExternalId` object. For multiple recipients, provide an array of these objects (1–50).
        :param documents: Document payload to print and enclose into shipment. For a single document, provide `DocumentPdf`, `DocumentLibrary`, or `DocumentMock` (for checking the price only). For multiple documents, provide an array of `DocumentPdf`, `DocumentLibrary`, or `DocumentMock` objects (1–20).
        :param options:
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.Shipment(
            recipients=utils.get_pydantic_model(recipients, models.ShipmentRecipients),
            documents=utils.get_pydantic_model(documents, models.ShipmentDocuments),
            options=utils.get_pydantic_model(options, OptionalNullable[models.Options]),
        )

        req = self._build_request(
            method="POST",
            path="/shipment/price",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value=accept_header_override.value
            if accept_header_override is not None
            else "application/json;q=1, application/problem+json;q=0",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.Shipment
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="shipmentPrice",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.ShipmentPriceResponse(
                result=unmarshal_json_response(List[models.ShipmentPrice], http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(
            http_res, ["400", "401", "403", "4XX"], "application/problem+json"
        ):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "5XX", "application/problem+json"):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "default", "application/problem+json"):
            return models.ShipmentPriceResponse(
                result=unmarshal_json_response(models.ErrorResponse, http_res),
                headers={},
            )

        raise errors.SDKDefaultError("Unexpected response received", http_res)

    async def price_async(
        self,
        *,
        recipients: Union[
            models.ShipmentRecipients, models.ShipmentRecipientsTypedDict
        ],
        documents: Union[models.ShipmentDocuments, models.ShipmentDocumentsTypedDict],
        options: OptionalNullable[
            Union[models.Options, models.OptionsTypedDict]
        ] = UNSET,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        accept_header_override: Optional[PriceAcceptEnum] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.ShipmentPriceResponse:
        r"""Check the shipment price

        Check the price of a shipment for one or multiple recipients. Provide a `Shipment` object in the request. Each object includes properties such as recipient details, included documents, and optional settings. Some fields are required.

        The system accepts up to **50** recipients per call. For larger volumes, split the operation into multiple requests.

        :param recipients: Recipient data for a single shipment. For one recipient, provide a `RecipientInline`, `RecipientFromAddressBook`, or `RecipientFromAddressBookByExternalId` object. For multiple recipients, provide an array of these objects (1–50).
        :param documents: Document payload to print and enclose into shipment. For a single document, provide `DocumentPdf`, `DocumentLibrary`, or `DocumentMock` (for checking the price only). For multiple documents, provide an array of `DocumentPdf`, `DocumentLibrary`, or `DocumentMock` objects (1–20).
        :param options:
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param accept_header_override: Override the default accept header for this method
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.Shipment(
            recipients=utils.get_pydantic_model(recipients, models.ShipmentRecipients),
            documents=utils.get_pydantic_model(documents, models.ShipmentDocuments),
            options=utils.get_pydantic_model(options, OptionalNullable[models.Options]),
        )

        req = self._build_request_async(
            method="POST",
            path="/shipment/price",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value=accept_header_override.value
            if accept_header_override is not None
            else "application/json;q=1, application/problem+json;q=0",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.Shipment
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="shipmentPrice",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=["400", "401", "403", "4XX", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.ShipmentPriceResponse(
                result=unmarshal_json_response(List[models.ShipmentPrice], http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(
            http_res, ["400", "401", "403", "4XX"], "application/problem+json"
        ):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "5XX", "application/problem+json"):
            response_data = unmarshal_json_response(errors.ErrorResponseData, http_res)
            raise errors.ErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "default", "application/problem+json"):
            return models.ShipmentPriceResponse(
                result=unmarshal_json_response(models.ErrorResponse, http_res),
                headers={},
            )

        raise errors.SDKDefaultError("Unexpected response received", http_res)
