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

from .basesdk import BaseSDK
from typing import Any, Mapping, Optional
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 Apis(BaseSDK):
    r"""API management operations"""

    def create_api(
        self,
        *,
        name: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2ApisCreateAPIResponseBody:
        r"""Create API namespace

        Create an API namespace for organizing keys by environment, service, or product.

        Use this to separate production from development keys, isolate different services, or manage multiple products. Each API gets a unique identifier and dedicated infrastructure for secure key operations.

        **Important**: API names must be unique within your workspace and cannot be changed after creation.

        **Required Permissions**

        Your root key must have one of the following permissions:
        - `api.*.create_api` (to create APIs in any workspace)


        :param name: Unique identifier for this API namespace within your workspace. Use descriptive names like 'payment-service-prod' or 'user-api-dev' to clearly identify purpose and environment.
        :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.V2ApisCreateAPIRequestBody(
            name=name,
        )

        req = self._build_request(
            method="POST",
            path="/v2/apis.createApi",
            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.V2ApisCreateAPIRequestBody
            ),
            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="createApi",
                oauth2_scopes=[],
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "401", "403", "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.V2ApisCreateAPIResponseBody, 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, "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_api_async(
        self,
        *,
        name: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2ApisCreateAPIResponseBody:
        r"""Create API namespace

        Create an API namespace for organizing keys by environment, service, or product.

        Use this to separate production from development keys, isolate different services, or manage multiple products. Each API gets a unique identifier and dedicated infrastructure for secure key operations.

        **Important**: API names must be unique within your workspace and cannot be changed after creation.

        **Required Permissions**

        Your root key must have one of the following permissions:
        - `api.*.create_api` (to create APIs in any workspace)


        :param name: Unique identifier for this API namespace within your workspace. Use descriptive names like 'payment-service-prod' or 'user-api-dev' to clearly identify purpose and environment.
        :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.V2ApisCreateAPIRequestBody(
            name=name,
        )

        req = self._build_request_async(
            method="POST",
            path="/v2/apis.createApi",
            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.V2ApisCreateAPIRequestBody
            ),
            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="createApi",
                oauth2_scopes=[],
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "401", "403", "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.V2ApisCreateAPIResponseBody, 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, "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_api(
        self,
        *,
        api_id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2ApisDeleteAPIResponseBody:
        r"""Delete API namespace

        Permanently delete an API namespace and immediately invalidate all associated keys.

        Use this for cleaning up development environments, retiring deprecated services, or removing unused resources. All keys in the namespace are immediately marked as deleted and will fail verification with `code=NOT_FOUND`.

        **Important**: This operation is immediate and permanent. Verify you have the correct API ID before deletion. If delete protection is enabled, disable it first through the dashboard or API configuration.

        **Required Permissions**

        Your root key must have one of the following permissions:
        - `api.*.delete_api` (to delete any API)
        - `api.<api_id>.delete_api` (to delete a specific API)


        :param api_id: Specifies which API namespace to permanently delete from your workspace. Must be a valid API ID that begins with 'api_' and exists within your workspace.  Before proceeding, ensure you have the correct API ID and understand that this action cannot be undone. If you need to migrate functionality, create replacement keys in a new API namespace and update client applications before deletion.
        :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.V2ApisDeleteAPIRequestBody(
            api_id=api_id,
        )

        req = self._build_request(
            method="POST",
            path="/v2/apis.deleteApi",
            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.V2ApisDeleteAPIRequestBody
            ),
            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="deleteApi",
                oauth2_scopes=[],
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "412", "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.V2ApisDeleteAPIResponseBody, 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, "412", "application/json"):
            response_data = unmarshal_json_response(
                errors.PreconditionFailedErrorResponseData, http_res
            )
            raise errors.PreconditionFailedErrorResponse(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 delete_api_async(
        self,
        *,
        api_id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2ApisDeleteAPIResponseBody:
        r"""Delete API namespace

        Permanently delete an API namespace and immediately invalidate all associated keys.

        Use this for cleaning up development environments, retiring deprecated services, or removing unused resources. All keys in the namespace are immediately marked as deleted and will fail verification with `code=NOT_FOUND`.

        **Important**: This operation is immediate and permanent. Verify you have the correct API ID before deletion. If delete protection is enabled, disable it first through the dashboard or API configuration.

        **Required Permissions**

        Your root key must have one of the following permissions:
        - `api.*.delete_api` (to delete any API)
        - `api.<api_id>.delete_api` (to delete a specific API)


        :param api_id: Specifies which API namespace to permanently delete from your workspace. Must be a valid API ID that begins with 'api_' and exists within your workspace.  Before proceeding, ensure you have the correct API ID and understand that this action cannot be undone. If you need to migrate functionality, create replacement keys in a new API namespace and update client applications before deletion.
        :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.V2ApisDeleteAPIRequestBody(
            api_id=api_id,
        )

        req = self._build_request_async(
            method="POST",
            path="/v2/apis.deleteApi",
            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.V2ApisDeleteAPIRequestBody
            ),
            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="deleteApi",
                oauth2_scopes=[],
                security_source=self.sdk_configuration.security,
            ),
            request=req,
            error_status_codes=["400", "401", "403", "404", "412", "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.V2ApisDeleteAPIResponseBody, 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, "412", "application/json"):
            response_data = unmarshal_json_response(
                errors.PreconditionFailedErrorResponseData, http_res
            )
            raise errors.PreconditionFailedErrorResponse(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 get_api(
        self,
        *,
        api_id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2ApisGetAPIResponseBody:
        r"""Get API namespace

        Retrieve basic information about an API namespace including its ID and name.

        Use this to verify an API exists before performing operations, get the human-readable name when you only have the API ID, or confirm access to a specific namespace. For detailed key information, use the `listKeys` endpoint instead.

        **Required Permissions**

        Your root key must have one of the following permissions:
        - `api.*.read_api` (to read any API)
        - `api.<api_id>.read_api` (to read a specific API)


        :param api_id: Specifies which API to retrieve by its unique identifier. Must be a valid API ID that begins with 'api_' and exists within your workspace.
        :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.V2ApisGetAPIRequestBody(
            api_id=api_id,
        )

        req = self._build_request(
            method="POST",
            path="/v2/apis.getApi",
            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.V2ApisGetAPIRequestBody
            ),
            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="getApi",
                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.V2ApisGetAPIResponseBody, 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_api_async(
        self,
        *,
        api_id: str,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2ApisGetAPIResponseBody:
        r"""Get API namespace

        Retrieve basic information about an API namespace including its ID and name.

        Use this to verify an API exists before performing operations, get the human-readable name when you only have the API ID, or confirm access to a specific namespace. For detailed key information, use the `listKeys` endpoint instead.

        **Required Permissions**

        Your root key must have one of the following permissions:
        - `api.*.read_api` (to read any API)
        - `api.<api_id>.read_api` (to read a specific API)


        :param api_id: Specifies which API to retrieve by its unique identifier. Must be a valid API ID that begins with 'api_' and exists within your workspace.
        :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.V2ApisGetAPIRequestBody(
            api_id=api_id,
        )

        req = self._build_request_async(
            method="POST",
            path="/v2/apis.getApi",
            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.V2ApisGetAPIRequestBody
            ),
            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="getApi",
                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.V2ApisGetAPIResponseBody, 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_keys(
        self,
        *,
        api_id: str,
        limit: Optional[int] = 100,
        cursor: Optional[str] = None,
        external_id: Optional[str] = None,
        decrypt: Optional[bool] = False,
        revalidate_keys_cache: Optional[bool] = False,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2ApisListKeysResponseBody:
        r"""List API keys

        Retrieve a paginated list of API keys for dashboard and administrative interfaces.

        Use this to build key management dashboards, filter keys by user with `externalId`, or retrieve key details for administrative purposes. Each key includes status, metadata, permissions, and usage limits.

        **Important**: Set `decrypt: true` only in secure contexts to retrieve plaintext key values from recoverable keys.

        **Required Permissions**

        Your root key must have one of the following permissions for basic key listing:
        - `api.*.read_key` (to read keys from any API)
        - `api.<api_id>.read_key` (to read keys from a specific API)

        Additionally, you need read access to the API itself:
        - `api.*.read_api` or `api.<api_id>.read_api`

        Additional permission required for decrypt functionality:
        - `api.*.decrypt_key` or `api.<api_id>.decrypt_key`


        :param api_id: The API namespace whose keys you want to list. Returns all keys in this API, subject to pagination and filters.
        :param limit: Maximum number of keys to return per request. Balance between response size and number of pagination calls needed.
        :param cursor: Pagination cursor from previous response to fetch next page. Use when `hasMore: true` in previous response.
        :param external_id: Filter keys by external ID to find keys for a specific user or entity. Must exactly match the externalId set during key creation.
        :param decrypt: When true, attempts to include the plaintext key value in the response. SECURITY WARNING: - This requires special permissions on the calling root key - Only works for keys created with 'recoverable: true' - Exposes sensitive key material in the response - Should only be used in secure administrative contexts - Never enable this in user-facing applications
        :param revalidate_keys_cache: EXPERIMENTAL: Skip the cache and fetch the keys directly from the database. This ensures you see the most recent state, including keys created moments ago. Use this when: - You've just created a key and need to display it immediately - You need absolute certainty about the current key state - You're debugging cache consistency issues  This parameter comes with a performance cost and should be used sparingly.
        :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.V2ApisListKeysRequestBody(
            api_id=api_id,
            limit=limit,
            cursor=cursor,
            external_id=external_id,
            decrypt=decrypt,
            revalidate_keys_cache=revalidate_keys_cache,
        )

        req = self._build_request(
            method="POST",
            path="/v2/apis.listKeys",
            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.V2ApisListKeysRequestBody
            ),
            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="listKeys",
                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.V2ApisListKeysResponseBody, 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 list_keys_async(
        self,
        *,
        api_id: str,
        limit: Optional[int] = 100,
        cursor: Optional[str] = None,
        external_id: Optional[str] = None,
        decrypt: Optional[bool] = False,
        revalidate_keys_cache: Optional[bool] = False,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.V2ApisListKeysResponseBody:
        r"""List API keys

        Retrieve a paginated list of API keys for dashboard and administrative interfaces.

        Use this to build key management dashboards, filter keys by user with `externalId`, or retrieve key details for administrative purposes. Each key includes status, metadata, permissions, and usage limits.

        **Important**: Set `decrypt: true` only in secure contexts to retrieve plaintext key values from recoverable keys.

        **Required Permissions**

        Your root key must have one of the following permissions for basic key listing:
        - `api.*.read_key` (to read keys from any API)
        - `api.<api_id>.read_key` (to read keys from a specific API)

        Additionally, you need read access to the API itself:
        - `api.*.read_api` or `api.<api_id>.read_api`

        Additional permission required for decrypt functionality:
        - `api.*.decrypt_key` or `api.<api_id>.decrypt_key`


        :param api_id: The API namespace whose keys you want to list. Returns all keys in this API, subject to pagination and filters.
        :param limit: Maximum number of keys to return per request. Balance between response size and number of pagination calls needed.
        :param cursor: Pagination cursor from previous response to fetch next page. Use when `hasMore: true` in previous response.
        :param external_id: Filter keys by external ID to find keys for a specific user or entity. Must exactly match the externalId set during key creation.
        :param decrypt: When true, attempts to include the plaintext key value in the response. SECURITY WARNING: - This requires special permissions on the calling root key - Only works for keys created with 'recoverable: true' - Exposes sensitive key material in the response - Should only be used in secure administrative contexts - Never enable this in user-facing applications
        :param revalidate_keys_cache: EXPERIMENTAL: Skip the cache and fetch the keys directly from the database. This ensures you see the most recent state, including keys created moments ago. Use this when: - You've just created a key and need to display it immediately - You need absolute certainty about the current key state - You're debugging cache consistency issues  This parameter comes with a performance cost and should be used sparingly.
        :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.V2ApisListKeysRequestBody(
            api_id=api_id,
            limit=limit,
            cursor=cursor,
            external_id=external_id,
            decrypt=decrypt,
            revalidate_keys_cache=revalidate_keys_cache,
        )

        req = self._build_request_async(
            method="POST",
            path="/v2/apis.listKeys",
            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.V2ApisListKeysRequestBody
            ),
            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="listKeys",
                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.V2ApisListKeysResponseBody, 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)
