# This file was auto-generated by Fern from our API Definition.

import datetime as dt
import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError as core_api_error_ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..errors.bad_request_error import BadRequestError
from ..errors.forbidden_error import ForbiddenError
from ..errors.internal_server_error import InternalServerError
from ..errors.not_found_error import NotFoundError
from ..errors.unauthorized_error import UnauthorizedError
from ..types.api_error import ApiError as types_api_error_ApiError
from ..types.billing_product_pricing import BillingProductPricing
from ..types.billing_subscription_discount import BillingSubscriptionDiscount
from ..types.create_billing_price_tier_request_body import CreateBillingPriceTierRequestBody
from .types.count_billing_products_request_price_usage_type import CountBillingProductsRequestPriceUsageType
from .types.count_billing_products_response import CountBillingProductsResponse
from .types.count_customers_response import CountCustomersResponse
from .types.create_billing_price_request_body_billing_scheme import CreateBillingPriceRequestBodyBillingScheme
from .types.create_billing_price_request_body_tier_mode import CreateBillingPriceRequestBodyTierMode
from .types.create_billing_price_request_body_usage_type import CreateBillingPriceRequestBodyUsageType
from .types.create_billing_subscriptions_request_body_trial_end_setting import (
    CreateBillingSubscriptionsRequestBodyTrialEndSetting,
)
from .types.delete_billing_product_response import DeleteBillingProductResponse
from .types.delete_product_price_response import DeleteProductPriceResponse
from .types.list_billing_products_request_price_usage_type import ListBillingProductsRequestPriceUsageType
from .types.list_billing_products_response import ListBillingProductsResponse
from .types.list_coupons_response import ListCouponsResponse
from .types.list_customers_with_subscriptions_response import ListCustomersWithSubscriptionsResponse
from .types.list_invoices_response import ListInvoicesResponse
from .types.list_meters_response import ListMetersResponse
from .types.list_payment_methods_response import ListPaymentMethodsResponse
from .types.list_product_prices_request_price_usage_type import ListProductPricesRequestPriceUsageType
from .types.list_product_prices_response import ListProductPricesResponse
from .types.search_billing_prices_request_usage_type import SearchBillingPricesRequestUsageType
from .types.search_billing_prices_response import SearchBillingPricesResponse
from .types.upsert_billing_coupon_response import UpsertBillingCouponResponse
from .types.upsert_billing_customer_response import UpsertBillingCustomerResponse
from .types.upsert_billing_meter_response import UpsertBillingMeterResponse
from .types.upsert_billing_price_response import UpsertBillingPriceResponse
from .types.upsert_billing_product_response import UpsertBillingProductResponse
from .types.upsert_billing_subscription_response import UpsertBillingSubscriptionResponse
from .types.upsert_invoice_response import UpsertInvoiceResponse
from .types.upsert_payment_method_response import UpsertPaymentMethodResponse

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class RawBillingClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def list_coupons(
        self,
        *,
        is_active: typing.Optional[bool] = None,
        q: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ListCouponsResponse]:
        """
        Parameters
        ----------
        is_active : typing.Optional[bool]

        q : typing.Optional[str]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ListCouponsResponse]
            OK
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/coupons",
            method="GET",
            params={
                "is_active": is_active,
                "q": q,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListCouponsResponse,
                    parse_obj_as(
                        type_=ListCouponsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def upsert_billing_coupon(
        self,
        *,
        amount_off: int,
        duration: str,
        duration_in_months: int,
        external_id: str,
        max_redemptions: int,
        name: str,
        percent_off: float,
        times_redeemed: int,
        currency: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[UpsertBillingCouponResponse]:
        """
        Parameters
        ----------
        amount_off : int

        duration : str

        duration_in_months : int

        external_id : str

        max_redemptions : int

        name : str

        percent_off : float

        times_redeemed : int

        currency : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[UpsertBillingCouponResponse]
            Created
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/coupons",
            method="POST",
            json={
                "amount_off": amount_off,
                "currency": currency,
                "duration": duration,
                "duration_in_months": duration_in_months,
                "external_id": external_id,
                "max_redemptions": max_redemptions,
                "name": name,
                "percent_off": percent_off,
                "times_redeemed": times_redeemed,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertBillingCouponResponse,
                    parse_obj_as(
                        type_=UpsertBillingCouponResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def upsert_billing_customer(
        self,
        *,
        email: str,
        external_id: str,
        failed_to_import: bool,
        meta: typing.Dict[str, str],
        name: str,
        company_id: typing.Optional[str] = OMIT,
        default_payment_method_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[UpsertBillingCustomerResponse]:
        """
        Parameters
        ----------
        email : str

        external_id : str

        failed_to_import : bool

        meta : typing.Dict[str, str]

        name : str

        company_id : typing.Optional[str]

        default_payment_method_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[UpsertBillingCustomerResponse]
            Created
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/customer/upsert",
            method="POST",
            json={
                "company_id": company_id,
                "default_payment_method_id": default_payment_method_id,
                "email": email,
                "external_id": external_id,
                "failed_to_import": failed_to_import,
                "meta": meta,
                "name": name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertBillingCustomerResponse,
                    parse_obj_as(
                        type_=UpsertBillingCustomerResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def list_customers_with_subscriptions(
        self,
        *,
        company_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        name: typing.Optional[str] = None,
        failed_to_import: typing.Optional[bool] = None,
        q: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ListCustomersWithSubscriptionsResponse]:
        """
        Parameters
        ----------
        company_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        name : typing.Optional[str]

        failed_to_import : typing.Optional[bool]

        q : typing.Optional[str]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ListCustomersWithSubscriptionsResponse]
            OK
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/customers",
            method="GET",
            params={
                "company_ids": company_ids,
                "name": name,
                "failed_to_import": failed_to_import,
                "q": q,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListCustomersWithSubscriptionsResponse,
                    parse_obj_as(
                        type_=ListCustomersWithSubscriptionsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def count_customers(
        self,
        *,
        company_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        name: typing.Optional[str] = None,
        failed_to_import: typing.Optional[bool] = None,
        q: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CountCustomersResponse]:
        """
        Parameters
        ----------
        company_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        name : typing.Optional[str]

        failed_to_import : typing.Optional[bool]

        q : typing.Optional[str]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[CountCustomersResponse]
            OK
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/customers/count",
            method="GET",
            params={
                "company_ids": company_ids,
                "name": name,
                "failed_to_import": failed_to_import,
                "q": q,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CountCustomersResponse,
                    parse_obj_as(
                        type_=CountCustomersResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def list_invoices(
        self,
        *,
        customer_external_id: str,
        company_id: typing.Optional[str] = None,
        subscription_external_id: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ListInvoicesResponse]:
        """
        Parameters
        ----------
        customer_external_id : str

        company_id : typing.Optional[str]

        subscription_external_id : typing.Optional[str]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ListInvoicesResponse]
            OK
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/invoices",
            method="GET",
            params={
                "company_id": company_id,
                "customer_external_id": customer_external_id,
                "subscription_external_id": subscription_external_id,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListInvoicesResponse,
                    parse_obj_as(
                        type_=ListInvoicesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def upsert_invoice(
        self,
        *,
        amount_due: int,
        amount_paid: int,
        amount_remaining: int,
        collection_method: str,
        currency: str,
        customer_external_id: str,
        subtotal: int,
        due_date: typing.Optional[dt.datetime] = OMIT,
        external_id: typing.Optional[str] = OMIT,
        payment_method_external_id: typing.Optional[str] = OMIT,
        subscription_external_id: typing.Optional[str] = OMIT,
        url: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[UpsertInvoiceResponse]:
        """
        Parameters
        ----------
        amount_due : int

        amount_paid : int

        amount_remaining : int

        collection_method : str

        currency : str

        customer_external_id : str

        subtotal : int

        due_date : typing.Optional[dt.datetime]

        external_id : typing.Optional[str]

        payment_method_external_id : typing.Optional[str]

        subscription_external_id : typing.Optional[str]

        url : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[UpsertInvoiceResponse]
            Created
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/invoices",
            method="POST",
            json={
                "amount_due": amount_due,
                "amount_paid": amount_paid,
                "amount_remaining": amount_remaining,
                "collection_method": collection_method,
                "currency": currency,
                "customer_external_id": customer_external_id,
                "due_date": due_date,
                "external_id": external_id,
                "payment_method_external_id": payment_method_external_id,
                "subscription_external_id": subscription_external_id,
                "subtotal": subtotal,
                "url": url,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertInvoiceResponse,
                    parse_obj_as(
                        type_=UpsertInvoiceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def list_meters(
        self,
        *,
        display_name: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ListMetersResponse]:
        """
        Parameters
        ----------
        display_name : typing.Optional[str]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ListMetersResponse]
            OK
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/meter",
            method="GET",
            params={
                "display_name": display_name,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListMetersResponse,
                    parse_obj_as(
                        type_=ListMetersResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def upsert_billing_meter(
        self,
        *,
        display_name: str,
        event_name: str,
        event_payload_key: str,
        external_id: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[UpsertBillingMeterResponse]:
        """
        Parameters
        ----------
        display_name : str

        event_name : str

        event_payload_key : str

        external_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[UpsertBillingMeterResponse]
            Created
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/meter/upsert",
            method="POST",
            json={
                "display_name": display_name,
                "event_name": event_name,
                "event_payload_key": event_payload_key,
                "external_id": external_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertBillingMeterResponse,
                    parse_obj_as(
                        type_=UpsertBillingMeterResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def list_payment_methods(
        self,
        *,
        customer_external_id: str,
        company_id: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ListPaymentMethodsResponse]:
        """
        Parameters
        ----------
        customer_external_id : str

        company_id : typing.Optional[str]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ListPaymentMethodsResponse]
            OK
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/payment-methods",
            method="GET",
            params={
                "company_id": company_id,
                "customer_external_id": customer_external_id,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListPaymentMethodsResponse,
                    parse_obj_as(
                        type_=ListPaymentMethodsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def upsert_payment_method(
        self,
        *,
        customer_external_id: str,
        external_id: str,
        payment_method_type: str,
        account_last_4: typing.Optional[str] = OMIT,
        account_name: typing.Optional[str] = OMIT,
        bank_name: typing.Optional[str] = OMIT,
        billing_email: typing.Optional[str] = OMIT,
        billing_name: typing.Optional[str] = OMIT,
        card_brand: typing.Optional[str] = OMIT,
        card_exp_month: typing.Optional[int] = OMIT,
        card_exp_year: typing.Optional[int] = OMIT,
        card_last_4: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[UpsertPaymentMethodResponse]:
        """
        Parameters
        ----------
        customer_external_id : str

        external_id : str

        payment_method_type : str

        account_last_4 : typing.Optional[str]

        account_name : typing.Optional[str]

        bank_name : typing.Optional[str]

        billing_email : typing.Optional[str]

        billing_name : typing.Optional[str]

        card_brand : typing.Optional[str]

        card_exp_month : typing.Optional[int]

        card_exp_year : typing.Optional[int]

        card_last_4 : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[UpsertPaymentMethodResponse]
            Created
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/payment-methods",
            method="POST",
            json={
                "account_last4": account_last_4,
                "account_name": account_name,
                "bank_name": bank_name,
                "billing_email": billing_email,
                "billing_name": billing_name,
                "card_brand": card_brand,
                "card_exp_month": card_exp_month,
                "card_exp_year": card_exp_year,
                "card_last4": card_last_4,
                "customer_external_id": customer_external_id,
                "external_id": external_id,
                "payment_method_type": payment_method_type,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertPaymentMethodResponse,
                    parse_obj_as(
                        type_=UpsertPaymentMethodResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def search_billing_prices(
        self,
        *,
        ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        q: typing.Optional[str] = None,
        interval: typing.Optional[str] = None,
        usage_type: typing.Optional[SearchBillingPricesRequestUsageType] = None,
        price: typing.Optional[int] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[SearchBillingPricesResponse]:
        """
        Parameters
        ----------
        ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        q : typing.Optional[str]

        interval : typing.Optional[str]

        usage_type : typing.Optional[SearchBillingPricesRequestUsageType]

        price : typing.Optional[int]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[SearchBillingPricesResponse]
            OK
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/price",
            method="GET",
            params={
                "ids": ids,
                "q": q,
                "interval": interval,
                "usage_type": usage_type,
                "price": price,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchBillingPricesResponse,
                    parse_obj_as(
                        type_=SearchBillingPricesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def upsert_billing_price(
        self,
        *,
        billing_scheme: CreateBillingPriceRequestBodyBillingScheme,
        currency: str,
        external_account_id: str,
        interval: str,
        is_active: bool,
        price: int,
        price_external_id: str,
        price_tiers: typing.Sequence[CreateBillingPriceTierRequestBody],
        product_external_id: str,
        usage_type: CreateBillingPriceRequestBodyUsageType,
        meter_id: typing.Optional[str] = OMIT,
        package_size: typing.Optional[int] = OMIT,
        price_decimal: typing.Optional[str] = OMIT,
        tier_mode: typing.Optional[CreateBillingPriceRequestBodyTierMode] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[UpsertBillingPriceResponse]:
        """
        Parameters
        ----------
        billing_scheme : CreateBillingPriceRequestBodyBillingScheme

        currency : str

        external_account_id : str

        interval : str

        is_active : bool

        price : int

        price_external_id : str

        price_tiers : typing.Sequence[CreateBillingPriceTierRequestBody]

        product_external_id : str

        usage_type : CreateBillingPriceRequestBodyUsageType

        meter_id : typing.Optional[str]

        package_size : typing.Optional[int]

        price_decimal : typing.Optional[str]

        tier_mode : typing.Optional[CreateBillingPriceRequestBodyTierMode]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[UpsertBillingPriceResponse]
            Created
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/price/upsert",
            method="POST",
            json={
                "billing_scheme": billing_scheme,
                "currency": currency,
                "external_account_id": external_account_id,
                "interval": interval,
                "is_active": is_active,
                "meter_id": meter_id,
                "package_size": package_size,
                "price": price,
                "price_decimal": price_decimal,
                "price_external_id": price_external_id,
                "price_tiers": convert_and_respect_annotation_metadata(
                    object_=price_tiers,
                    annotation=typing.Sequence[CreateBillingPriceTierRequestBody],
                    direction="write",
                ),
                "product_external_id": product_external_id,
                "tier_mode": tier_mode,
                "usage_type": usage_type,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertBillingPriceResponse,
                    parse_obj_as(
                        type_=UpsertBillingPriceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def delete_billing_product(
        self, billing_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[DeleteBillingProductResponse]:
        """
        Parameters
        ----------
        billing_id : str
            billing_id

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[DeleteBillingProductResponse]
            OK
        """
        _response = self._client_wrapper.httpx_client.request(
            f"billing/product/{jsonable_encoder(billing_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteBillingProductResponse,
                    parse_obj_as(
                        type_=DeleteBillingProductResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def list_product_prices(
        self,
        *,
        ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        name: typing.Optional[str] = None,
        q: typing.Optional[str] = None,
        price_usage_type: typing.Optional[ListProductPricesRequestPriceUsageType] = None,
        without_linked_to_plan: typing.Optional[bool] = None,
        with_one_time_charges: typing.Optional[bool] = None,
        with_zero_price: typing.Optional[bool] = None,
        with_prices_only: typing.Optional[bool] = None,
        is_active: typing.Optional[bool] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ListProductPricesResponse]:
        """
        Parameters
        ----------
        ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        name : typing.Optional[str]

        q : typing.Optional[str]

        price_usage_type : typing.Optional[ListProductPricesRequestPriceUsageType]

        without_linked_to_plan : typing.Optional[bool]
            Filter products that are not linked to any plan

        with_one_time_charges : typing.Optional[bool]
            Filter products that are one time charges

        with_zero_price : typing.Optional[bool]
            Filter products that have zero price for free subscription type

        with_prices_only : typing.Optional[bool]
            Filter products that have prices

        is_active : typing.Optional[bool]
            Filter products that are active

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ListProductPricesResponse]
            OK
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/product/prices",
            method="GET",
            params={
                "ids": ids,
                "name": name,
                "q": q,
                "price_usage_type": price_usage_type,
                "without_linked_to_plan": without_linked_to_plan,
                "with_one_time_charges": with_one_time_charges,
                "with_zero_price": with_zero_price,
                "with_prices_only": with_prices_only,
                "is_active": is_active,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListProductPricesResponse,
                    parse_obj_as(
                        type_=ListProductPricesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def delete_product_price(
        self, billing_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[DeleteProductPriceResponse]:
        """
        Parameters
        ----------
        billing_id : str
            billing_id

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[DeleteProductPriceResponse]
            OK
        """
        _response = self._client_wrapper.httpx_client.request(
            f"billing/product/prices/{jsonable_encoder(billing_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteProductPriceResponse,
                    parse_obj_as(
                        type_=DeleteProductPriceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def upsert_billing_product(
        self,
        *,
        external_id: str,
        name: str,
        price: float,
        is_active: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[UpsertBillingProductResponse]:
        """
        Parameters
        ----------
        external_id : str

        name : str

        price : float

        is_active : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[UpsertBillingProductResponse]
            Created
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/product/upsert",
            method="POST",
            json={
                "external_id": external_id,
                "is_active": is_active,
                "name": name,
                "price": price,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertBillingProductResponse,
                    parse_obj_as(
                        type_=UpsertBillingProductResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def list_billing_products(
        self,
        *,
        ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        name: typing.Optional[str] = None,
        q: typing.Optional[str] = None,
        price_usage_type: typing.Optional[ListBillingProductsRequestPriceUsageType] = None,
        without_linked_to_plan: typing.Optional[bool] = None,
        with_one_time_charges: typing.Optional[bool] = None,
        with_zero_price: typing.Optional[bool] = None,
        with_prices_only: typing.Optional[bool] = None,
        is_active: typing.Optional[bool] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ListBillingProductsResponse]:
        """
        Parameters
        ----------
        ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        name : typing.Optional[str]

        q : typing.Optional[str]

        price_usage_type : typing.Optional[ListBillingProductsRequestPriceUsageType]

        without_linked_to_plan : typing.Optional[bool]
            Filter products that are not linked to any plan

        with_one_time_charges : typing.Optional[bool]
            Filter products that are one time charges

        with_zero_price : typing.Optional[bool]
            Filter products that have zero price for free subscription type

        with_prices_only : typing.Optional[bool]
            Filter products that have prices

        is_active : typing.Optional[bool]
            Filter products that are active

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ListBillingProductsResponse]
            OK
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/products",
            method="GET",
            params={
                "ids": ids,
                "name": name,
                "q": q,
                "price_usage_type": price_usage_type,
                "without_linked_to_plan": without_linked_to_plan,
                "with_one_time_charges": with_one_time_charges,
                "with_zero_price": with_zero_price,
                "with_prices_only": with_prices_only,
                "is_active": is_active,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListBillingProductsResponse,
                    parse_obj_as(
                        type_=ListBillingProductsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def count_billing_products(
        self,
        *,
        ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        name: typing.Optional[str] = None,
        q: typing.Optional[str] = None,
        price_usage_type: typing.Optional[CountBillingProductsRequestPriceUsageType] = None,
        without_linked_to_plan: typing.Optional[bool] = None,
        with_one_time_charges: typing.Optional[bool] = None,
        with_zero_price: typing.Optional[bool] = None,
        with_prices_only: typing.Optional[bool] = None,
        is_active: typing.Optional[bool] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CountBillingProductsResponse]:
        """
        Parameters
        ----------
        ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        name : typing.Optional[str]

        q : typing.Optional[str]

        price_usage_type : typing.Optional[CountBillingProductsRequestPriceUsageType]

        without_linked_to_plan : typing.Optional[bool]
            Filter products that are not linked to any plan

        with_one_time_charges : typing.Optional[bool]
            Filter products that are one time charges

        with_zero_price : typing.Optional[bool]
            Filter products that have zero price for free subscription type

        with_prices_only : typing.Optional[bool]
            Filter products that have prices

        is_active : typing.Optional[bool]
            Filter products that are active

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[CountBillingProductsResponse]
            OK
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/products/count",
            method="GET",
            params={
                "ids": ids,
                "name": name,
                "q": q,
                "price_usage_type": price_usage_type,
                "without_linked_to_plan": without_linked_to_plan,
                "with_one_time_charges": with_one_time_charges,
                "with_zero_price": with_zero_price,
                "with_prices_only": with_prices_only,
                "is_active": is_active,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CountBillingProductsResponse,
                    parse_obj_as(
                        type_=CountBillingProductsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    def upsert_billing_subscription(
        self,
        *,
        cancel_at_period_end: bool,
        currency: str,
        customer_external_id: str,
        discounts: typing.Sequence[BillingSubscriptionDiscount],
        expired_at: dt.datetime,
        product_external_ids: typing.Sequence[BillingProductPricing],
        subscription_external_id: str,
        total_price: int,
        cancel_at: typing.Optional[int] = OMIT,
        default_payment_method_id: typing.Optional[str] = OMIT,
        interval: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        period_end: typing.Optional[int] = OMIT,
        period_start: typing.Optional[int] = OMIT,
        status: typing.Optional[str] = OMIT,
        trial_end: typing.Optional[int] = OMIT,
        trial_end_setting: typing.Optional[CreateBillingSubscriptionsRequestBodyTrialEndSetting] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[UpsertBillingSubscriptionResponse]:
        """
        Parameters
        ----------
        cancel_at_period_end : bool

        currency : str

        customer_external_id : str

        discounts : typing.Sequence[BillingSubscriptionDiscount]

        expired_at : dt.datetime

        product_external_ids : typing.Sequence[BillingProductPricing]

        subscription_external_id : str

        total_price : int

        cancel_at : typing.Optional[int]

        default_payment_method_id : typing.Optional[str]

        interval : typing.Optional[str]

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]

        period_end : typing.Optional[int]

        period_start : typing.Optional[int]

        status : typing.Optional[str]

        trial_end : typing.Optional[int]

        trial_end_setting : typing.Optional[CreateBillingSubscriptionsRequestBodyTrialEndSetting]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[UpsertBillingSubscriptionResponse]
            Created
        """
        _response = self._client_wrapper.httpx_client.request(
            "billing/subscription/upsert",
            method="POST",
            json={
                "cancel_at": cancel_at,
                "cancel_at_period_end": cancel_at_period_end,
                "currency": currency,
                "customer_external_id": customer_external_id,
                "default_payment_method_id": default_payment_method_id,
                "discounts": convert_and_respect_annotation_metadata(
                    object_=discounts, annotation=typing.Sequence[BillingSubscriptionDiscount], direction="write"
                ),
                "expired_at": expired_at,
                "interval": interval,
                "metadata": metadata,
                "period_end": period_end,
                "period_start": period_start,
                "product_external_ids": convert_and_respect_annotation_metadata(
                    object_=product_external_ids, annotation=typing.Sequence[BillingProductPricing], direction="write"
                ),
                "status": status,
                "subscription_external_id": subscription_external_id,
                "total_price": total_price,
                "trial_end": trial_end,
                "trial_end_setting": trial_end_setting,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertBillingSubscriptionResponse,
                    parse_obj_as(
                        type_=UpsertBillingSubscriptionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )


class AsyncRawBillingClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list_coupons(
        self,
        *,
        is_active: typing.Optional[bool] = None,
        q: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ListCouponsResponse]:
        """
        Parameters
        ----------
        is_active : typing.Optional[bool]

        q : typing.Optional[str]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ListCouponsResponse]
            OK
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/coupons",
            method="GET",
            params={
                "is_active": is_active,
                "q": q,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListCouponsResponse,
                    parse_obj_as(
                        type_=ListCouponsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def upsert_billing_coupon(
        self,
        *,
        amount_off: int,
        duration: str,
        duration_in_months: int,
        external_id: str,
        max_redemptions: int,
        name: str,
        percent_off: float,
        times_redeemed: int,
        currency: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[UpsertBillingCouponResponse]:
        """
        Parameters
        ----------
        amount_off : int

        duration : str

        duration_in_months : int

        external_id : str

        max_redemptions : int

        name : str

        percent_off : float

        times_redeemed : int

        currency : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[UpsertBillingCouponResponse]
            Created
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/coupons",
            method="POST",
            json={
                "amount_off": amount_off,
                "currency": currency,
                "duration": duration,
                "duration_in_months": duration_in_months,
                "external_id": external_id,
                "max_redemptions": max_redemptions,
                "name": name,
                "percent_off": percent_off,
                "times_redeemed": times_redeemed,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertBillingCouponResponse,
                    parse_obj_as(
                        type_=UpsertBillingCouponResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def upsert_billing_customer(
        self,
        *,
        email: str,
        external_id: str,
        failed_to_import: bool,
        meta: typing.Dict[str, str],
        name: str,
        company_id: typing.Optional[str] = OMIT,
        default_payment_method_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[UpsertBillingCustomerResponse]:
        """
        Parameters
        ----------
        email : str

        external_id : str

        failed_to_import : bool

        meta : typing.Dict[str, str]

        name : str

        company_id : typing.Optional[str]

        default_payment_method_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[UpsertBillingCustomerResponse]
            Created
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/customer/upsert",
            method="POST",
            json={
                "company_id": company_id,
                "default_payment_method_id": default_payment_method_id,
                "email": email,
                "external_id": external_id,
                "failed_to_import": failed_to_import,
                "meta": meta,
                "name": name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertBillingCustomerResponse,
                    parse_obj_as(
                        type_=UpsertBillingCustomerResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def list_customers_with_subscriptions(
        self,
        *,
        company_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        name: typing.Optional[str] = None,
        failed_to_import: typing.Optional[bool] = None,
        q: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ListCustomersWithSubscriptionsResponse]:
        """
        Parameters
        ----------
        company_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        name : typing.Optional[str]

        failed_to_import : typing.Optional[bool]

        q : typing.Optional[str]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ListCustomersWithSubscriptionsResponse]
            OK
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/customers",
            method="GET",
            params={
                "company_ids": company_ids,
                "name": name,
                "failed_to_import": failed_to_import,
                "q": q,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListCustomersWithSubscriptionsResponse,
                    parse_obj_as(
                        type_=ListCustomersWithSubscriptionsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def count_customers(
        self,
        *,
        company_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        name: typing.Optional[str] = None,
        failed_to_import: typing.Optional[bool] = None,
        q: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CountCustomersResponse]:
        """
        Parameters
        ----------
        company_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        name : typing.Optional[str]

        failed_to_import : typing.Optional[bool]

        q : typing.Optional[str]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[CountCustomersResponse]
            OK
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/customers/count",
            method="GET",
            params={
                "company_ids": company_ids,
                "name": name,
                "failed_to_import": failed_to_import,
                "q": q,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CountCustomersResponse,
                    parse_obj_as(
                        type_=CountCustomersResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def list_invoices(
        self,
        *,
        customer_external_id: str,
        company_id: typing.Optional[str] = None,
        subscription_external_id: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ListInvoicesResponse]:
        """
        Parameters
        ----------
        customer_external_id : str

        company_id : typing.Optional[str]

        subscription_external_id : typing.Optional[str]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ListInvoicesResponse]
            OK
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/invoices",
            method="GET",
            params={
                "company_id": company_id,
                "customer_external_id": customer_external_id,
                "subscription_external_id": subscription_external_id,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListInvoicesResponse,
                    parse_obj_as(
                        type_=ListInvoicesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def upsert_invoice(
        self,
        *,
        amount_due: int,
        amount_paid: int,
        amount_remaining: int,
        collection_method: str,
        currency: str,
        customer_external_id: str,
        subtotal: int,
        due_date: typing.Optional[dt.datetime] = OMIT,
        external_id: typing.Optional[str] = OMIT,
        payment_method_external_id: typing.Optional[str] = OMIT,
        subscription_external_id: typing.Optional[str] = OMIT,
        url: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[UpsertInvoiceResponse]:
        """
        Parameters
        ----------
        amount_due : int

        amount_paid : int

        amount_remaining : int

        collection_method : str

        currency : str

        customer_external_id : str

        subtotal : int

        due_date : typing.Optional[dt.datetime]

        external_id : typing.Optional[str]

        payment_method_external_id : typing.Optional[str]

        subscription_external_id : typing.Optional[str]

        url : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[UpsertInvoiceResponse]
            Created
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/invoices",
            method="POST",
            json={
                "amount_due": amount_due,
                "amount_paid": amount_paid,
                "amount_remaining": amount_remaining,
                "collection_method": collection_method,
                "currency": currency,
                "customer_external_id": customer_external_id,
                "due_date": due_date,
                "external_id": external_id,
                "payment_method_external_id": payment_method_external_id,
                "subscription_external_id": subscription_external_id,
                "subtotal": subtotal,
                "url": url,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertInvoiceResponse,
                    parse_obj_as(
                        type_=UpsertInvoiceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def list_meters(
        self,
        *,
        display_name: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ListMetersResponse]:
        """
        Parameters
        ----------
        display_name : typing.Optional[str]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ListMetersResponse]
            OK
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/meter",
            method="GET",
            params={
                "display_name": display_name,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListMetersResponse,
                    parse_obj_as(
                        type_=ListMetersResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def upsert_billing_meter(
        self,
        *,
        display_name: str,
        event_name: str,
        event_payload_key: str,
        external_id: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[UpsertBillingMeterResponse]:
        """
        Parameters
        ----------
        display_name : str

        event_name : str

        event_payload_key : str

        external_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[UpsertBillingMeterResponse]
            Created
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/meter/upsert",
            method="POST",
            json={
                "display_name": display_name,
                "event_name": event_name,
                "event_payload_key": event_payload_key,
                "external_id": external_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertBillingMeterResponse,
                    parse_obj_as(
                        type_=UpsertBillingMeterResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def list_payment_methods(
        self,
        *,
        customer_external_id: str,
        company_id: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ListPaymentMethodsResponse]:
        """
        Parameters
        ----------
        customer_external_id : str

        company_id : typing.Optional[str]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ListPaymentMethodsResponse]
            OK
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/payment-methods",
            method="GET",
            params={
                "company_id": company_id,
                "customer_external_id": customer_external_id,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListPaymentMethodsResponse,
                    parse_obj_as(
                        type_=ListPaymentMethodsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def upsert_payment_method(
        self,
        *,
        customer_external_id: str,
        external_id: str,
        payment_method_type: str,
        account_last_4: typing.Optional[str] = OMIT,
        account_name: typing.Optional[str] = OMIT,
        bank_name: typing.Optional[str] = OMIT,
        billing_email: typing.Optional[str] = OMIT,
        billing_name: typing.Optional[str] = OMIT,
        card_brand: typing.Optional[str] = OMIT,
        card_exp_month: typing.Optional[int] = OMIT,
        card_exp_year: typing.Optional[int] = OMIT,
        card_last_4: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[UpsertPaymentMethodResponse]:
        """
        Parameters
        ----------
        customer_external_id : str

        external_id : str

        payment_method_type : str

        account_last_4 : typing.Optional[str]

        account_name : typing.Optional[str]

        bank_name : typing.Optional[str]

        billing_email : typing.Optional[str]

        billing_name : typing.Optional[str]

        card_brand : typing.Optional[str]

        card_exp_month : typing.Optional[int]

        card_exp_year : typing.Optional[int]

        card_last_4 : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[UpsertPaymentMethodResponse]
            Created
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/payment-methods",
            method="POST",
            json={
                "account_last4": account_last_4,
                "account_name": account_name,
                "bank_name": bank_name,
                "billing_email": billing_email,
                "billing_name": billing_name,
                "card_brand": card_brand,
                "card_exp_month": card_exp_month,
                "card_exp_year": card_exp_year,
                "card_last4": card_last_4,
                "customer_external_id": customer_external_id,
                "external_id": external_id,
                "payment_method_type": payment_method_type,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertPaymentMethodResponse,
                    parse_obj_as(
                        type_=UpsertPaymentMethodResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def search_billing_prices(
        self,
        *,
        ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        q: typing.Optional[str] = None,
        interval: typing.Optional[str] = None,
        usage_type: typing.Optional[SearchBillingPricesRequestUsageType] = None,
        price: typing.Optional[int] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[SearchBillingPricesResponse]:
        """
        Parameters
        ----------
        ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        q : typing.Optional[str]

        interval : typing.Optional[str]

        usage_type : typing.Optional[SearchBillingPricesRequestUsageType]

        price : typing.Optional[int]

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[SearchBillingPricesResponse]
            OK
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/price",
            method="GET",
            params={
                "ids": ids,
                "q": q,
                "interval": interval,
                "usage_type": usage_type,
                "price": price,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    SearchBillingPricesResponse,
                    parse_obj_as(
                        type_=SearchBillingPricesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def upsert_billing_price(
        self,
        *,
        billing_scheme: CreateBillingPriceRequestBodyBillingScheme,
        currency: str,
        external_account_id: str,
        interval: str,
        is_active: bool,
        price: int,
        price_external_id: str,
        price_tiers: typing.Sequence[CreateBillingPriceTierRequestBody],
        product_external_id: str,
        usage_type: CreateBillingPriceRequestBodyUsageType,
        meter_id: typing.Optional[str] = OMIT,
        package_size: typing.Optional[int] = OMIT,
        price_decimal: typing.Optional[str] = OMIT,
        tier_mode: typing.Optional[CreateBillingPriceRequestBodyTierMode] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[UpsertBillingPriceResponse]:
        """
        Parameters
        ----------
        billing_scheme : CreateBillingPriceRequestBodyBillingScheme

        currency : str

        external_account_id : str

        interval : str

        is_active : bool

        price : int

        price_external_id : str

        price_tiers : typing.Sequence[CreateBillingPriceTierRequestBody]

        product_external_id : str

        usage_type : CreateBillingPriceRequestBodyUsageType

        meter_id : typing.Optional[str]

        package_size : typing.Optional[int]

        price_decimal : typing.Optional[str]

        tier_mode : typing.Optional[CreateBillingPriceRequestBodyTierMode]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[UpsertBillingPriceResponse]
            Created
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/price/upsert",
            method="POST",
            json={
                "billing_scheme": billing_scheme,
                "currency": currency,
                "external_account_id": external_account_id,
                "interval": interval,
                "is_active": is_active,
                "meter_id": meter_id,
                "package_size": package_size,
                "price": price,
                "price_decimal": price_decimal,
                "price_external_id": price_external_id,
                "price_tiers": convert_and_respect_annotation_metadata(
                    object_=price_tiers,
                    annotation=typing.Sequence[CreateBillingPriceTierRequestBody],
                    direction="write",
                ),
                "product_external_id": product_external_id,
                "tier_mode": tier_mode,
                "usage_type": usage_type,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertBillingPriceResponse,
                    parse_obj_as(
                        type_=UpsertBillingPriceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def delete_billing_product(
        self, billing_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[DeleteBillingProductResponse]:
        """
        Parameters
        ----------
        billing_id : str
            billing_id

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[DeleteBillingProductResponse]
            OK
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"billing/product/{jsonable_encoder(billing_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteBillingProductResponse,
                    parse_obj_as(
                        type_=DeleteBillingProductResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def list_product_prices(
        self,
        *,
        ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        name: typing.Optional[str] = None,
        q: typing.Optional[str] = None,
        price_usage_type: typing.Optional[ListProductPricesRequestPriceUsageType] = None,
        without_linked_to_plan: typing.Optional[bool] = None,
        with_one_time_charges: typing.Optional[bool] = None,
        with_zero_price: typing.Optional[bool] = None,
        with_prices_only: typing.Optional[bool] = None,
        is_active: typing.Optional[bool] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ListProductPricesResponse]:
        """
        Parameters
        ----------
        ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        name : typing.Optional[str]

        q : typing.Optional[str]

        price_usage_type : typing.Optional[ListProductPricesRequestPriceUsageType]

        without_linked_to_plan : typing.Optional[bool]
            Filter products that are not linked to any plan

        with_one_time_charges : typing.Optional[bool]
            Filter products that are one time charges

        with_zero_price : typing.Optional[bool]
            Filter products that have zero price for free subscription type

        with_prices_only : typing.Optional[bool]
            Filter products that have prices

        is_active : typing.Optional[bool]
            Filter products that are active

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ListProductPricesResponse]
            OK
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/product/prices",
            method="GET",
            params={
                "ids": ids,
                "name": name,
                "q": q,
                "price_usage_type": price_usage_type,
                "without_linked_to_plan": without_linked_to_plan,
                "with_one_time_charges": with_one_time_charges,
                "with_zero_price": with_zero_price,
                "with_prices_only": with_prices_only,
                "is_active": is_active,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListProductPricesResponse,
                    parse_obj_as(
                        type_=ListProductPricesResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def delete_product_price(
        self, billing_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[DeleteProductPriceResponse]:
        """
        Parameters
        ----------
        billing_id : str
            billing_id

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[DeleteProductPriceResponse]
            OK
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"billing/product/prices/{jsonable_encoder(billing_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteProductPriceResponse,
                    parse_obj_as(
                        type_=DeleteProductPriceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def upsert_billing_product(
        self,
        *,
        external_id: str,
        name: str,
        price: float,
        is_active: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[UpsertBillingProductResponse]:
        """
        Parameters
        ----------
        external_id : str

        name : str

        price : float

        is_active : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[UpsertBillingProductResponse]
            Created
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/product/upsert",
            method="POST",
            json={
                "external_id": external_id,
                "is_active": is_active,
                "name": name,
                "price": price,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertBillingProductResponse,
                    parse_obj_as(
                        type_=UpsertBillingProductResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def list_billing_products(
        self,
        *,
        ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        name: typing.Optional[str] = None,
        q: typing.Optional[str] = None,
        price_usage_type: typing.Optional[ListBillingProductsRequestPriceUsageType] = None,
        without_linked_to_plan: typing.Optional[bool] = None,
        with_one_time_charges: typing.Optional[bool] = None,
        with_zero_price: typing.Optional[bool] = None,
        with_prices_only: typing.Optional[bool] = None,
        is_active: typing.Optional[bool] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ListBillingProductsResponse]:
        """
        Parameters
        ----------
        ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        name : typing.Optional[str]

        q : typing.Optional[str]

        price_usage_type : typing.Optional[ListBillingProductsRequestPriceUsageType]

        without_linked_to_plan : typing.Optional[bool]
            Filter products that are not linked to any plan

        with_one_time_charges : typing.Optional[bool]
            Filter products that are one time charges

        with_zero_price : typing.Optional[bool]
            Filter products that have zero price for free subscription type

        with_prices_only : typing.Optional[bool]
            Filter products that have prices

        is_active : typing.Optional[bool]
            Filter products that are active

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ListBillingProductsResponse]
            OK
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/products",
            method="GET",
            params={
                "ids": ids,
                "name": name,
                "q": q,
                "price_usage_type": price_usage_type,
                "without_linked_to_plan": without_linked_to_plan,
                "with_one_time_charges": with_one_time_charges,
                "with_zero_price": with_zero_price,
                "with_prices_only": with_prices_only,
                "is_active": is_active,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListBillingProductsResponse,
                    parse_obj_as(
                        type_=ListBillingProductsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def count_billing_products(
        self,
        *,
        ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        name: typing.Optional[str] = None,
        q: typing.Optional[str] = None,
        price_usage_type: typing.Optional[CountBillingProductsRequestPriceUsageType] = None,
        without_linked_to_plan: typing.Optional[bool] = None,
        with_one_time_charges: typing.Optional[bool] = None,
        with_zero_price: typing.Optional[bool] = None,
        with_prices_only: typing.Optional[bool] = None,
        is_active: typing.Optional[bool] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CountBillingProductsResponse]:
        """
        Parameters
        ----------
        ids : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        name : typing.Optional[str]

        q : typing.Optional[str]

        price_usage_type : typing.Optional[CountBillingProductsRequestPriceUsageType]

        without_linked_to_plan : typing.Optional[bool]
            Filter products that are not linked to any plan

        with_one_time_charges : typing.Optional[bool]
            Filter products that are one time charges

        with_zero_price : typing.Optional[bool]
            Filter products that have zero price for free subscription type

        with_prices_only : typing.Optional[bool]
            Filter products that have prices

        is_active : typing.Optional[bool]
            Filter products that are active

        limit : typing.Optional[int]
            Page limit (default 100)

        offset : typing.Optional[int]
            Page offset (default 0)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[CountBillingProductsResponse]
            OK
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/products/count",
            method="GET",
            params={
                "ids": ids,
                "name": name,
                "q": q,
                "price_usage_type": price_usage_type,
                "without_linked_to_plan": without_linked_to_plan,
                "with_one_time_charges": with_one_time_charges,
                "with_zero_price": with_zero_price,
                "with_prices_only": with_prices_only,
                "is_active": is_active,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CountBillingProductsResponse,
                    parse_obj_as(
                        type_=CountBillingProductsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )

    async def upsert_billing_subscription(
        self,
        *,
        cancel_at_period_end: bool,
        currency: str,
        customer_external_id: str,
        discounts: typing.Sequence[BillingSubscriptionDiscount],
        expired_at: dt.datetime,
        product_external_ids: typing.Sequence[BillingProductPricing],
        subscription_external_id: str,
        total_price: int,
        cancel_at: typing.Optional[int] = OMIT,
        default_payment_method_id: typing.Optional[str] = OMIT,
        interval: typing.Optional[str] = OMIT,
        metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        period_end: typing.Optional[int] = OMIT,
        period_start: typing.Optional[int] = OMIT,
        status: typing.Optional[str] = OMIT,
        trial_end: typing.Optional[int] = OMIT,
        trial_end_setting: typing.Optional[CreateBillingSubscriptionsRequestBodyTrialEndSetting] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[UpsertBillingSubscriptionResponse]:
        """
        Parameters
        ----------
        cancel_at_period_end : bool

        currency : str

        customer_external_id : str

        discounts : typing.Sequence[BillingSubscriptionDiscount]

        expired_at : dt.datetime

        product_external_ids : typing.Sequence[BillingProductPricing]

        subscription_external_id : str

        total_price : int

        cancel_at : typing.Optional[int]

        default_payment_method_id : typing.Optional[str]

        interval : typing.Optional[str]

        metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]

        period_end : typing.Optional[int]

        period_start : typing.Optional[int]

        status : typing.Optional[str]

        trial_end : typing.Optional[int]

        trial_end_setting : typing.Optional[CreateBillingSubscriptionsRequestBodyTrialEndSetting]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[UpsertBillingSubscriptionResponse]
            Created
        """
        _response = await self._client_wrapper.httpx_client.request(
            "billing/subscription/upsert",
            method="POST",
            json={
                "cancel_at": cancel_at,
                "cancel_at_period_end": cancel_at_period_end,
                "currency": currency,
                "customer_external_id": customer_external_id,
                "default_payment_method_id": default_payment_method_id,
                "discounts": convert_and_respect_annotation_metadata(
                    object_=discounts, annotation=typing.Sequence[BillingSubscriptionDiscount], direction="write"
                ),
                "expired_at": expired_at,
                "interval": interval,
                "metadata": metadata,
                "period_end": period_end,
                "period_start": period_start,
                "product_external_ids": convert_and_respect_annotation_metadata(
                    object_=product_external_ids, annotation=typing.Sequence[BillingProductPricing], direction="write"
                ),
                "status": status,
                "subscription_external_id": subscription_external_id,
                "total_price": total_price,
                "trial_end": trial_end,
                "trial_end_setting": trial_end_setting,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpsertBillingSubscriptionResponse,
                    parse_obj_as(
                        type_=UpsertBillingSubscriptionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        types_api_error_ApiError,
                        parse_obj_as(
                            type_=types_api_error_ApiError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise core_api_error_ApiError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
            )
        raise core_api_error_ApiError(
            status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
        )
