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

from .basesdk import BaseSDK
from jsonpath import JSONPath
from typing import Any, Dict, List, Mapping, Optional, Union
from unkey.py import errors, models, utils
from unkey.py._hooks import HookContext
from unkey.py.types import OptionalNullable, UNSET
from unkey.py.utils.unmarshal_json_response import unmarshal_json_response


class Identities(BaseSDK):
    r"""Identity management operations"""

    def create_identity(
        self,
        *,
        external_id: str,
        meta: Optional[Dict[str, Any]] = None,
        ratelimits: Optional[
            Union[List[models.RatelimitRequest], List[models.RatelimitRequestTypedDict]]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2IdentitiesCreateIdentityResponseBody:
        r"""Create Identity

        Create an identity to group multiple API keys under a single entity. Identities enable shared rate limits and metadata across all associated keys.

        Perfect for users with multiple devices, organizations with multiple API keys, or when you need unified rate limiting across different services.

        > **Important**
        > Requires `identity.*.create_identity` permission


        :param external_id: Creates an identity using your system's unique identifier for a user, organization, or entity. Must be stable and unique across your workspace - duplicate externalIds return CONFLICT errors. This identifier links Unkey identities to your authentication system, database records, or tenant structure.  Avoid changing externalIds after creation as this breaks the link between your systems. Use consistent identifier patterns across your application for easier management and debugging. Accepts letters, numbers, underscores, dots, and hyphens for flexible identifier formats. Essential for implementing proper multi-tenant isolation and user-specific rate limiting.
        :param meta: Stores arbitrary JSON metadata returned during key verification for contextual information. Eliminates additional database lookups during verification, improving performance for stateless services. Avoid storing sensitive data here as it's returned in verification responses.  Large metadata objects increase verification latency and should stay under 10KB total size. Use this for subscription details, feature flags, user preferences, and organization information. Metadata is returned as-is whenever keys associated with this identity are verified.
        :param ratelimits: Defines shared rate limits that apply to all keys belonging to this identity. Prevents abuse by users with multiple keys by enforcing consistent limits across their entire key portfolio. Essential for implementing fair usage policies and tiered access levels in multi-tenant applications.  Rate limit counters are shared across all keys with this identity, regardless of how many keys the user creates. During verification, specify which named limits to check for enforcement. Identity rate limits supplement any key-specific rate limits that may also be configured. - Each named limit can have different thresholds and windows  When verifying keys, you can specify which limits you want to use and all keys attached to this identity will share the limits, regardless of which specific key is used.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.V2IdentitiesCreateIdentityRequestBody(
            external_id=external_id,
            meta=meta,
            ratelimits=utils.get_pydantic_model(
                ratelimits, Optional[List[models.RatelimitRequest]]
            ),
        )

        req = self._build_request(
            method="POST",
            path="/v2/identities.createIdentity",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request,
                False,
                False,
                "json",
                models.V2IdentitiesCreateIdentityRequestBody,
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(50, 1000, 1.5, 10000), True
                )

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="identities.createIdentity",
                oauth2_scopes=[],
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "401", "403", "409", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.V2IdentitiesCreateIdentityResponseBody, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.BadRequestErrorResponseData, http_res
            )
            raise errors.BadRequestErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                errors.UnauthorizedErrorResponseData, http_res
            )
            raise errors.UnauthorizedErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(
                errors.ForbiddenErrorResponseData, http_res
            )
            raise errors.ForbiddenErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(
                errors.ConflictErrorResponseData, http_res
            )
            raise errors.ConflictErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.InternalServerErrorResponseData, http_res
            )
            raise errors.InternalServerErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)

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

    async def create_identity_async(
        self,
        *,
        external_id: str,
        meta: Optional[Dict[str, Any]] = None,
        ratelimits: Optional[
            Union[List[models.RatelimitRequest], List[models.RatelimitRequestTypedDict]]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2IdentitiesCreateIdentityResponseBody:
        r"""Create Identity

        Create an identity to group multiple API keys under a single entity. Identities enable shared rate limits and metadata across all associated keys.

        Perfect for users with multiple devices, organizations with multiple API keys, or when you need unified rate limiting across different services.

        > **Important**
        > Requires `identity.*.create_identity` permission


        :param external_id: Creates an identity using your system's unique identifier for a user, organization, or entity. Must be stable and unique across your workspace - duplicate externalIds return CONFLICT errors. This identifier links Unkey identities to your authentication system, database records, or tenant structure.  Avoid changing externalIds after creation as this breaks the link between your systems. Use consistent identifier patterns across your application for easier management and debugging. Accepts letters, numbers, underscores, dots, and hyphens for flexible identifier formats. Essential for implementing proper multi-tenant isolation and user-specific rate limiting.
        :param meta: Stores arbitrary JSON metadata returned during key verification for contextual information. Eliminates additional database lookups during verification, improving performance for stateless services. Avoid storing sensitive data here as it's returned in verification responses.  Large metadata objects increase verification latency and should stay under 10KB total size. Use this for subscription details, feature flags, user preferences, and organization information. Metadata is returned as-is whenever keys associated with this identity are verified.
        :param ratelimits: Defines shared rate limits that apply to all keys belonging to this identity. Prevents abuse by users with multiple keys by enforcing consistent limits across their entire key portfolio. Essential for implementing fair usage policies and tiered access levels in multi-tenant applications.  Rate limit counters are shared across all keys with this identity, regardless of how many keys the user creates. During verification, specify which named limits to check for enforcement. Identity rate limits supplement any key-specific rate limits that may also be configured. - Each named limit can have different thresholds and windows  When verifying keys, you can specify which limits you want to use and all keys attached to this identity will share the limits, regardless of which specific key is used.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.V2IdentitiesCreateIdentityRequestBody(
            external_id=external_id,
            meta=meta,
            ratelimits=utils.get_pydantic_model(
                ratelimits, Optional[List[models.RatelimitRequest]]
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/v2/identities.createIdentity",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request,
                False,
                False,
                "json",
                models.V2IdentitiesCreateIdentityRequestBody,
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(50, 1000, 1.5, 10000), True
                )

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="identities.createIdentity",
                oauth2_scopes=[],
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "401", "403", "409", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.V2IdentitiesCreateIdentityResponseBody, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.BadRequestErrorResponseData, http_res
            )
            raise errors.BadRequestErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                errors.UnauthorizedErrorResponseData, http_res
            )
            raise errors.UnauthorizedErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(
                errors.ForbiddenErrorResponseData, http_res
            )
            raise errors.ForbiddenErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "409", "application/json"):
            response_data = unmarshal_json_response(
                errors.ConflictErrorResponseData, http_res
            )
            raise errors.ConflictErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.InternalServerErrorResponseData, http_res
            )
            raise errors.InternalServerErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)

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

    def delete_identity(
        self,
        *,
        identity: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2IdentitiesDeleteIdentityResponseBody:
        r"""Delete Identity

        Permanently delete an identity. This operation cannot be undone.

        Use this for data cleanup, compliance requirements, or when removing entities from your system.

        > **Important**
        > Requires `identity.*.delete_identity` permission
        > Associated API keys remain functional but lose shared resources
        > External ID becomes available for reuse immediately


        :param identity: The ID of the identity to delete. This can be either the externalId (from your own system that was used during identity creation) or the identityId (the internal ID returned by the identity service).
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.V2IdentitiesDeleteIdentityRequestBody(
            identity=identity,
        )

        req = self._build_request(
            method="POST",
            path="/v2/identities.deleteIdentity",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request,
                False,
                False,
                "json",
                models.V2IdentitiesDeleteIdentityRequestBody,
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(50, 1000, 1.5, 10000), True
                )

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="v2.identities.deleteIdentity",
                oauth2_scopes=[],
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.V2IdentitiesDeleteIdentityResponseBody, http_res
            )
        if utils.match_response(http_res, "400", "application/problem+json"):
            response_data = unmarshal_json_response(
                errors.BadRequestErrorResponseData, http_res
            )
            raise errors.BadRequestErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/problem+json"):
            response_data = unmarshal_json_response(
                errors.UnauthorizedErrorResponseData, http_res
            )
            raise errors.UnauthorizedErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "403", "application/problem+json"):
            response_data = unmarshal_json_response(
                errors.ForbiddenErrorResponseData, http_res
            )
            raise errors.ForbiddenErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/problem+json"):
            response_data = unmarshal_json_response(
                errors.NotFoundErrorResponseData, http_res
            )
            raise errors.NotFoundErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/problem+json"):
            response_data = unmarshal_json_response(
                errors.InternalServerErrorResponseData, http_res
            )
            raise errors.InternalServerErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)

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

    async def delete_identity_async(
        self,
        *,
        identity: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2IdentitiesDeleteIdentityResponseBody:
        r"""Delete Identity

        Permanently delete an identity. This operation cannot be undone.

        Use this for data cleanup, compliance requirements, or when removing entities from your system.

        > **Important**
        > Requires `identity.*.delete_identity` permission
        > Associated API keys remain functional but lose shared resources
        > External ID becomes available for reuse immediately


        :param identity: The ID of the identity to delete. This can be either the externalId (from your own system that was used during identity creation) or the identityId (the internal ID returned by the identity service).
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.V2IdentitiesDeleteIdentityRequestBody(
            identity=identity,
        )

        req = self._build_request_async(
            method="POST",
            path="/v2/identities.deleteIdentity",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request,
                False,
                False,
                "json",
                models.V2IdentitiesDeleteIdentityRequestBody,
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(50, 1000, 1.5, 10000), True
                )

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="v2.identities.deleteIdentity",
                oauth2_scopes=[],
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.V2IdentitiesDeleteIdentityResponseBody, http_res
            )
        if utils.match_response(http_res, "400", "application/problem+json"):
            response_data = unmarshal_json_response(
                errors.BadRequestErrorResponseData, http_res
            )
            raise errors.BadRequestErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/problem+json"):
            response_data = unmarshal_json_response(
                errors.UnauthorizedErrorResponseData, http_res
            )
            raise errors.UnauthorizedErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "403", "application/problem+json"):
            response_data = unmarshal_json_response(
                errors.ForbiddenErrorResponseData, http_res
            )
            raise errors.ForbiddenErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/problem+json"):
            response_data = unmarshal_json_response(
                errors.NotFoundErrorResponseData, http_res
            )
            raise errors.NotFoundErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/problem+json"):
            response_data = unmarshal_json_response(
                errors.InternalServerErrorResponseData, http_res
            )
            raise errors.InternalServerErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)

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

    def get_identity(
        self,
        *,
        identity: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2IdentitiesGetIdentityResponseBody:
        r"""Get Identity

        Retrieve an identity by external ID. Returns metadata, rate limits, and other associated data.

        Use this to check if an identity exists, view configurations, or build management dashboards.

        > **Important**
        > Requires `identity.*.read_identity` permission


        :param identity: The ID of the identity to retrieve. This can be either the externalId (from your own system that was used during identity creation) or the identityId (the internal ID returned by the identity service).
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.V2IdentitiesGetIdentityRequestBody(
            identity=identity,
        )

        req = self._build_request(
            method="POST",
            path="/v2/identities.getIdentity",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.V2IdentitiesGetIdentityRequestBody
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(50, 1000, 1.5, 10000), True
                )

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

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

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.V2IdentitiesGetIdentityResponseBody, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.BadRequestErrorResponseData, http_res
            )
            raise errors.BadRequestErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                errors.UnauthorizedErrorResponseData, http_res
            )
            raise errors.UnauthorizedErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(
                errors.ForbiddenErrorResponseData, http_res
            )
            raise errors.ForbiddenErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                errors.NotFoundErrorResponseData, http_res
            )
            raise errors.NotFoundErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.InternalServerErrorResponseData, http_res
            )
            raise errors.InternalServerErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)

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

    async def get_identity_async(
        self,
        *,
        identity: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2IdentitiesGetIdentityResponseBody:
        r"""Get Identity

        Retrieve an identity by external ID. Returns metadata, rate limits, and other associated data.

        Use this to check if an identity exists, view configurations, or build management dashboards.

        > **Important**
        > Requires `identity.*.read_identity` permission


        :param identity: The ID of the identity to retrieve. This can be either the externalId (from your own system that was used during identity creation) or the identityId (the internal ID returned by the identity service).
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.V2IdentitiesGetIdentityRequestBody(
            identity=identity,
        )

        req = self._build_request_async(
            method="POST",
            path="/v2/identities.getIdentity",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request, False, False, "json", models.V2IdentitiesGetIdentityRequestBody
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(50, 1000, 1.5, 10000), True
                )

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

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

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.V2IdentitiesGetIdentityResponseBody, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.BadRequestErrorResponseData, http_res
            )
            raise errors.BadRequestErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                errors.UnauthorizedErrorResponseData, http_res
            )
            raise errors.UnauthorizedErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(
                errors.ForbiddenErrorResponseData, http_res
            )
            raise errors.ForbiddenErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                errors.NotFoundErrorResponseData, http_res
            )
            raise errors.NotFoundErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.InternalServerErrorResponseData, http_res
            )
            raise errors.InternalServerErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)

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

    def list_identities(
        self,
        *,
        limit: Optional[int] = 100,
        cursor: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.IdentitiesListIdentitiesResponse]:
        r"""List Identities

        Get a paginated list of all identities in your workspace. Returns metadata and rate limit configurations.

        Perfect for building management dashboards, auditing configurations, or browsing your identities.

        > **Important**
        > Requires `identity.*.read_identity` permission


        :param limit: The maximum number of identities to return in a single request. Use this to control response size and loading performance.
        :param cursor: Pagination cursor from a previous response. Use this to fetch subsequent pages of results when the response contains a cursor value.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.V2IdentitiesListIdentitiesRequestBody(
            limit=limit,
            cursor=cursor,
        )

        req = self._build_request(
            method="POST",
            path="/v2/identities.listIdentities",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request,
                False,
                False,
                "json",
                models.V2IdentitiesListIdentitiesRequestBody,
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(50, 1000, 1.5, 10000), True
                )

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="identities.listIdentities",
                oauth2_scopes=[],
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "401", "403", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        def next_func() -> Optional[models.IdentitiesListIdentitiesResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])
            next_cursor = JSONPath("$.data.cursor").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None:
                return None

            return self.list_identities(
                limit=limit,
                cursor=next_cursor,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.IdentitiesListIdentitiesResponse(
                result=unmarshal_json_response(
                    models.V2IdentitiesListIdentitiesResponseBody, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.BadRequestErrorResponseData, http_res
            )
            raise errors.BadRequestErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                errors.UnauthorizedErrorResponseData, http_res
            )
            raise errors.UnauthorizedErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(
                errors.ForbiddenErrorResponseData, http_res
            )
            raise errors.ForbiddenErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.InternalServerErrorResponseData, http_res
            )
            raise errors.InternalServerErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)

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

    async def list_identities_async(
        self,
        *,
        limit: Optional[int] = 100,
        cursor: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> Optional[models.IdentitiesListIdentitiesResponse]:
        r"""List Identities

        Get a paginated list of all identities in your workspace. Returns metadata and rate limit configurations.

        Perfect for building management dashboards, auditing configurations, or browsing your identities.

        > **Important**
        > Requires `identity.*.read_identity` permission


        :param limit: The maximum number of identities to return in a single request. Use this to control response size and loading performance.
        :param cursor: Pagination cursor from a previous response. Use this to fetch subsequent pages of results when the response contains a cursor value.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.V2IdentitiesListIdentitiesRequestBody(
            limit=limit,
            cursor=cursor,
        )

        req = self._build_request_async(
            method="POST",
            path="/v2/identities.listIdentities",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request,
                False,
                False,
                "json",
                models.V2IdentitiesListIdentitiesRequestBody,
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(50, 1000, 1.5, 10000), True
                )

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

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

        def next_func() -> Optional[models.IdentitiesListIdentitiesResponse]:
            body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]])
            next_cursor = JSONPath("$.data.cursor").parse(body)

            if len(next_cursor) == 0:
                return None

            next_cursor = next_cursor[0]
            if next_cursor is None:
                return None

            return self.list_identities(
                limit=limit,
                cursor=next_cursor,
                retries=retries,
            )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.IdentitiesListIdentitiesResponse(
                result=unmarshal_json_response(
                    models.V2IdentitiesListIdentitiesResponseBody, http_res
                ),
                next=next_func,
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.BadRequestErrorResponseData, http_res
            )
            raise errors.BadRequestErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                errors.UnauthorizedErrorResponseData, http_res
            )
            raise errors.UnauthorizedErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(
                errors.ForbiddenErrorResponseData, http_res
            )
            raise errors.ForbiddenErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.InternalServerErrorResponseData, http_res
            )
            raise errors.InternalServerErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)

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

    def update_identity(
        self,
        *,
        external_id: str,
        meta: Optional[Dict[str, Any]] = None,
        ratelimits: Optional[
            Union[List[models.RatelimitRequest], List[models.RatelimitRequestTypedDict]]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2IdentitiesUpdateIdentityResponseBody:
        r"""Update Identity

        Update an identity's metadata and rate limits. Only specified fields are modified - others remain unchanged.

        Perfect for subscription changes, plan upgrades, or updating user information. Changes take effect immediately.

        > **Important**
        > Requires `identity.*.update_identity` permission
        > Rate limit changes propagate within 30 seconds


        :param external_id: Specifies which identity to update using your system's identifier from identity creation. Use this when you track identities by your own user IDs, organization IDs, or tenant identifiers. Accepts letters, numbers, underscores, dots, and hyphens for flexible identifier formats.
        :param meta: Replaces all existing metadata with this new metadata object. Omitting this field preserves existing metadata, while providing an empty object clears all metadata. Avoid storing sensitive data here as it's returned in verification responses. Large metadata objects increase verification latency and should stay under 10KB total size.
        :param ratelimits: Replaces all existing identity rate limits with this complete list of rate limits. Omitting this field preserves existing rate limits, while providing an empty array removes all rate limits. These limits are shared across all keys belonging to this identity, preventing abuse through multiple keys. Rate limit changes take effect immediately but may take up to 30 seconds to propagate across all regions.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.V2IdentitiesUpdateIdentityRequestBody(
            external_id=external_id,
            meta=meta,
            ratelimits=utils.get_pydantic_model(
                ratelimits, Optional[List[models.RatelimitRequest]]
            ),
        )

        req = self._build_request(
            method="POST",
            path="/v2/identities.updateIdentity",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request,
                False,
                False,
                "json",
                models.V2IdentitiesUpdateIdentityRequestBody,
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(50, 1000, 1.5, 10000), True
                )

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

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="v2.identities.updateIdentity",
                oauth2_scopes=[],
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.V2IdentitiesUpdateIdentityResponseBody, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.BadRequestErrorResponseData, http_res
            )
            raise errors.BadRequestErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                errors.UnauthorizedErrorResponseData, http_res
            )
            raise errors.UnauthorizedErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(
                errors.ForbiddenErrorResponseData, http_res
            )
            raise errors.ForbiddenErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                errors.NotFoundErrorResponseData, http_res
            )
            raise errors.NotFoundErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.InternalServerErrorResponseData, http_res
            )
            raise errors.InternalServerErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)

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

    async def update_identity_async(
        self,
        *,
        external_id: str,
        meta: Optional[Dict[str, Any]] = None,
        ratelimits: Optional[
            Union[List[models.RatelimitRequest], List[models.RatelimitRequestTypedDict]]
        ] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2IdentitiesUpdateIdentityResponseBody:
        r"""Update Identity

        Update an identity's metadata and rate limits. Only specified fields are modified - others remain unchanged.

        Perfect for subscription changes, plan upgrades, or updating user information. Changes take effect immediately.

        > **Important**
        > Requires `identity.*.update_identity` permission
        > Rate limit changes propagate within 30 seconds


        :param external_id: Specifies which identity to update using your system's identifier from identity creation. Use this when you track identities by your own user IDs, organization IDs, or tenant identifiers. Accepts letters, numbers, underscores, dots, and hyphens for flexible identifier formats.
        :param meta: Replaces all existing metadata with this new metadata object. Omitting this field preserves existing metadata, while providing an empty object clears all metadata. Avoid storing sensitive data here as it's returned in verification responses. Large metadata objects increase verification latency and should stay under 10KB total size.
        :param ratelimits: Replaces all existing identity rate limits with this complete list of rate limits. Omitting this field preserves existing rate limits, while providing an empty array removes all rate limits. These limits are shared across all keys belonging to this identity, preventing abuse through multiple keys. Rate limit changes take effect immediately but may take up to 30 seconds to propagate across all regions.
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

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

        request = models.V2IdentitiesUpdateIdentityRequestBody(
            external_id=external_id,
            meta=meta,
            ratelimits=utils.get_pydantic_model(
                ratelimits, Optional[List[models.RatelimitRequest]]
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/v2/identities.updateIdentity",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request,
                False,
                False,
                "json",
                models.V2IdentitiesUpdateIdentityRequestBody,
            ),
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(50, 1000, 1.5, 10000), True
                )

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

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="v2.identities.updateIdentity",
                oauth2_scopes=[],
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "4XX", "500", "5XX"],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return unmarshal_json_response(
                models.V2IdentitiesUpdateIdentityResponseBody, http_res
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                errors.BadRequestErrorResponseData, http_res
            )
            raise errors.BadRequestErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "401", "application/json"):
            response_data = unmarshal_json_response(
                errors.UnauthorizedErrorResponseData, http_res
            )
            raise errors.UnauthorizedErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "403", "application/json"):
            response_data = unmarshal_json_response(
                errors.ForbiddenErrorResponseData, http_res
            )
            raise errors.ForbiddenErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "404", "application/json"):
            response_data = unmarshal_json_response(
                errors.NotFoundErrorResponseData, http_res
            )
            raise errors.NotFoundErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(
                errors.InternalServerErrorResponseData, http_res
            )
            raise errors.InternalServerErrorResponse(response_data, http_res)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise errors.APIError("API error occurred", http_res, http_res_text)

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