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

import typing
from ..core.client_wrapper import SyncClientWrapper
from ..role_base.types.resources import Resources
from ..permissionset_base.types.permissions import Permissions
from ..core.request_options import RequestOptions
from .types.create_token_response import CreateTokenResponse
from ..core.unchecked_base_model import construct_type
from ..common.errors.bad_request_error import BadRequestError
from ..common.types.problem import Problem
from ..common.errors.unauthorized_error import UnauthorizedError
from ..common.errors.forbidden_error import ForbiddenError
from ..common.errors.not_found_error import NotFoundError
from ..common.errors.method_not_allowed_error import MethodNotAllowedError
from ..common.errors.conflict_error import ConflictError
from ..common.errors.unsupported_media_type_error import UnsupportedMediaTypeError
from ..common.errors.too_many_requests_error import TooManyRequestsError
from ..common.errors.internal_server_error import InternalServerError
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from .types.mcp_token_scope import McpTokenScope
from .types.create_mcp_token_response import CreateMcpTokenResponse
from ..account_base.types.account_id import AccountId
from ..integration_base.types.integration_id import IntegrationId
from .types.create_integration_token_response import CreateIntegrationTokenResponse
from ..core.jsonable_encoder import jsonable_encoder
from .types.create_synqly_integrations_token_response import (
    CreateSynqlyIntegrationsTokenResponse,
)
from ..token_base.types.token_id import TokenId
from .types.list_tokens_response import ListTokensResponse
from .types.get_token_response import GetTokenResponse
from ..common.types.id import Id
from .types.reset_token_response import ResetTokenResponse
from .types.rotate_token_response import RotateTokenResponse
from .types.refresh_token_response import RefreshTokenResponse
from ..core.client_wrapper import AsyncClientWrapper

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


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

    def create_token(
        self,
        *,
        resources: Resources,
        permission_set: Permissions,
        name: typing.Optional[str] = OMIT,
        fullname: typing.Optional[str] = OMIT,
        token_ttl: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateTokenResponse:
        """
        Create an adhoc organization token restricted to specified resources and permission set.
        Tokens can only be reduced in scope, never expanded.
        Permissions are inherited from the token used to call this API.
        Permissions assigned to the new token will not be persisted, this is not a way to create roles.

        Parameters
        ----------
        resources : Resources
            Limit access to supplied resources

        permission_set : Permissions
            Limit access to supplied permissions

        name : typing.Optional[str]
            Unique short name for this token (lowercase [a-z0-9_-], can be used in URLs). Also used for case insensitive duplicate name detection and default sort order. Defaults to TokenId if both name and fullname are not specified.

        fullname : typing.Optional[str]
            Human friendly display name for this Token, will auto-generate 'name' field (if 'name' is not specified). Defaults to the same value as the 'name' field if not specified.

        token_ttl : typing.Optional[str]
            Token time-to-live. If not provided, defaults to 24 hours. Use the format "1h", "1m", "1s" for hours, minutes, and seconds respectively, e.g., "24h" for 24 hours.

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

        Returns
        -------
        CreateTokenResponse

        Examples
        --------
        from synqly import SynqlyManagement
        from synqly.permissionset_base import Permissions
        from synqly.role_base import Resources

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.tokens.create_token(
            name="string",
            fullname="string",
            resources=Resources(),
            permission_set=Permissions.ADMINISTRATOR,
            token_ttl="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/tokens",
            method="POST",
            json={
                "name": name,
                "fullname": fullname,
                "resources": resources,
                "permission_set": permission_set,
                "token_ttl": token_ttl,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CreateTokenResponse,
                    construct_type(
                        type_=CreateTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create_mcp_token(
        self,
        *,
        scope: McpTokenScope,
        token_ttl: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateMcpTokenResponse:
        """
        Create a token for MCP authentication. This token is soley for MCP authentication and cannot
        authenticate with any other API.

        Parameters
        ----------
        scope : McpTokenScope
            Controls the tools that are available to the MCP server,
            and the APIs that can be accessed by the MCP server.

        token_ttl : typing.Optional[str]
            Token time-to-live. If not provided, defaults to 1 hour. May be set to a maximum of 24 hours. Use the format "1h", "1m", "1s" for hours, minutes, and seconds respectively, e.g., "2h" for 2 hours.

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

        Returns
        -------
        CreateMcpTokenResponse

        Examples
        --------
        from synqly import SynqlyManagement
        from synqly.tokens import McpTokenScope_Management

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.tokens.create_mcp_token(
            token_ttl="string",
            scope=McpTokenScope_Management(),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/tokens/mcp",
            method="POST",
            json={
                "token_ttl": token_ttl,
                "scope": scope,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CreateMcpTokenResponse,
                    construct_type(
                        type_=CreateMcpTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create_integration_token(
        self,
        account_id: AccountId,
        integration_id: IntegrationId,
        *,
        name: typing.Optional[str] = OMIT,
        token_ttl: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateIntegrationTokenResponse:
        """
        Create an adhoc integration token restricted to a single integration. The token used to call
        this API must have the necessary permissions to create tokens and have access to the account
        and integration IDs. Permissions may not be escalated, so any operation that the invocation
        token does not have access to cannot be granted.

        Parameters
        ----------
        account_id : AccountId

        integration_id : IntegrationId

        name : typing.Optional[str]
            Unique name token. If not provided, defaults to generated newly created refresh token id.

        token_ttl : typing.Optional[str]
            Token time-to-live. If not provided, defaults to 10 minutes. Use the format "1h", "1m", "1s" for hours, minutes, and seconds respectively, e.g., "2h" for 2 hours.

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

        Returns
        -------
        CreateIntegrationTokenResponse

        Examples
        --------
        from synqly import SynqlyManagement

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.tokens.create_integration_token(
            account_id="string",
            integration_id="string",
            name="string",
            token_ttl="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(account_id)}/{jsonable_encoder(integration_id)}",
            method="POST",
            json={
                "name": name,
                "token_ttl": token_ttl,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CreateIntegrationTokenResponse,
                    construct_type(
                        type_=CreateIntegrationTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create_synqly_integrations_token(
        self,
        *,
        token_ttl: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateSynqlyIntegrationsTokenResponse:
        """
        Create a token for managing Synqly-specific integrations. This token can be used with the integration APIs to manage
        integrations for Synqly-specific integrations, such as status events exports and async operations. See the
        [Synqly Integrations](https://docs.synqly.com/guides/synqly-integrations) documentation for more information.

        Parameters
        ----------
        token_ttl : typing.Optional[str]
            Token time-to-live. If not provided, defaults to 24 hours. Use the format "1h", "1m", "1s" for hours, minutes, and seconds respectively, e.g., "24h" for 24 hours.

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

        Returns
        -------
        CreateSynqlyIntegrationsTokenResponse

        Examples
        --------
        from synqly import SynqlyManagement

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.tokens.create_synqly_integrations_token(
            token_ttl="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/tokens/synqly-integrations",
            method="POST",
            json={
                "token_ttl": token_ttl,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CreateSynqlyIntegrationsTokenResponse,
                    construct_type(
                        type_=CreateSynqlyIntegrationsTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def delete(
        self,
        refresh_token_id: TokenId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Deletes the Refresh Token with id `{id}`. This immediately
        invalidates both the primary and secondary token pairs.

        Parameters
        ----------
        refresh_token_id : TokenId

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

        Returns
        -------
        None

        Examples
        --------
        from synqly import SynqlyManagement

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.tokens.delete(
            refresh_token_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(refresh_token_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def list(
        self,
        *,
        limit: typing.Optional[int] = None,
        start_after: typing.Optional[str] = None,
        order: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        filter: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ListTokensResponse:
        """
        Returns a list of all `RefreshToken` objects belonging to the Authorization Bearer
        token. For more infromation on Tokens, refer to
        [Authentication](/api-reference/authentication).

        Parameters
        ----------
        limit : typing.Optional[int]
            Number of `Token` objects to return in this page. Defaults to 100.

        start_after : typing.Optional[str]
            Return `Token` objects starting after this `name`.

        order : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Select a field to order the results by. Defaults to `name`. To control the direction of the sorting, append
            `[asc]` or `[desc]` to the field name. For example, `name[desc]` will sort the results by `name` in descending order.
            The ordering defaults to `asc` if not specified. May be used multiple times to order by multiple fields, and the
            ordering is applied in the order the fields are specified.

        filter : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Filter results by this query. For more information on filtering, refer to our Filtering Guide. Defaults to no filter.
            If used more than once, the queries are ANDed together.

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

        Returns
        -------
        ListTokensResponse

        Examples
        --------
        from synqly import SynqlyManagement

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.tokens.list(
            limit=1,
            start_after="string",
            order="string",
            filter="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/tokens",
            method="GET",
            params={
                "limit": limit,
                "start_after": start_after,
                "order": order,
                "filter": filter,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ListTokensResponse,
                    construct_type(
                        type_=ListTokensResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get(
        self,
        refresh_token_id: TokenId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetTokenResponse:
        """
        Returns the `RefreshToken` object matching `{tokenId}`. For more information on
        Tokens, refer to
        [Authentication](/api-reference/authentication).

        Parameters
        ----------
        refresh_token_id : TokenId

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

        Returns
        -------
        GetTokenResponse

        Examples
        --------
        from synqly import SynqlyManagement

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.tokens.get(
            refresh_token_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(refresh_token_id)}/info",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetTokenResponse,
                    construct_type(
                        type_=GetTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def reset(
        self,
        owner_id: Id,
        refresh_token_id: TokenId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ResetTokenResponse:
        """
        This API can be used to reset `Organization` or `Integration` `RefreshTokens`.
        Resets the specified `RefreshToken` and expiration time, removes the secondary, and resets access and refresh tokens for the
        `RefreshToken` object matching `{ownerId}/{refreshTokenId}` where `ownerId` is an `organizationId` or `integrationId`.
        An `Organization` token with `administrator` permissions can be used to perform this operation.

        Parameters
        ----------
        owner_id : Id

        refresh_token_id : TokenId

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

        Returns
        -------
        ResetTokenResponse

        Examples
        --------
        from synqly import SynqlyManagement

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.tokens.reset(
            owner_id="string",
            refresh_token_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(owner_id)}/{jsonable_encoder(refresh_token_id)}/reset",
            method="PUT",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ResetTokenResponse,
                    construct_type(
                        type_=ResetTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def rotate(
        self,
        owner_id: Id,
        refresh_token_id: TokenId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RotateTokenResponse:
        """
        This API can be used to rotate an `Organization` or `Integration` `RefreshTokens`.
        Rotate deletes the existing `Secondary` TokenPair, moves the `Primary` TokenPair to the `Secondary` TokenPair and creates a new `Primary` TokenPair for the
        `RefreshToken` object matching `{ownerId}/{refreshTokenId}` where `ownerId` is an `organizationId` or `integrationId`.
        An `Organization` token with `administrator` permissions can be used to perform this operation.

        Parameters
        ----------
        owner_id : Id

        refresh_token_id : TokenId

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

        Returns
        -------
        RotateTokenResponse

        Examples
        --------
        from synqly import SynqlyManagement

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.tokens.rotate(
            owner_id="string",
            refresh_token_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(owner_id)}/{jsonable_encoder(refresh_token_id)}/rotate",
            method="PUT",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    RotateTokenResponse,
                    construct_type(
                        type_=RotateTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def refresh(
        self,
        refresh_token_id: TokenId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RefreshTokenResponse:
        """
        Creates a new primary `TokenPair` object, setting the secondary `TokenPair`
        to the previous primary value. Call `/v1/removeSecondaryToken` to remove
        this secondary backup once the new primary `TokenPair` has been deployed.

        Parameters
        ----------
        refresh_token_id : TokenId

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

        Returns
        -------
        RefreshTokenResponse

        Examples
        --------
        from synqly import SynqlyManagement

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.tokens.refresh(
            refresh_token_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(refresh_token_id)}/refresh",
            method="PUT",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    RefreshTokenResponse,
                    construct_type(
                        type_=RefreshTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def remove_secondary(
        self,
        refresh_token_id: TokenId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Deletes the secondary `TokenPair` for the `RefreshToken` object
        matching `{refreshTokenId}`.

        Parameters
        ----------
        refresh_token_id : TokenId

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

        Returns
        -------
        None

        Examples
        --------
        from synqly import SynqlyManagement

        client = SynqlyManagement(
            token="YOUR_TOKEN",
        )
        client.tokens.remove_secondary(
            refresh_token_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(refresh_token_id)}/secondary",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


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

    async def create_token(
        self,
        *,
        resources: Resources,
        permission_set: Permissions,
        name: typing.Optional[str] = OMIT,
        fullname: typing.Optional[str] = OMIT,
        token_ttl: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateTokenResponse:
        """
        Create an adhoc organization token restricted to specified resources and permission set.
        Tokens can only be reduced in scope, never expanded.
        Permissions are inherited from the token used to call this API.
        Permissions assigned to the new token will not be persisted, this is not a way to create roles.

        Parameters
        ----------
        resources : Resources
            Limit access to supplied resources

        permission_set : Permissions
            Limit access to supplied permissions

        name : typing.Optional[str]
            Unique short name for this token (lowercase [a-z0-9_-], can be used in URLs). Also used for case insensitive duplicate name detection and default sort order. Defaults to TokenId if both name and fullname are not specified.

        fullname : typing.Optional[str]
            Human friendly display name for this Token, will auto-generate 'name' field (if 'name' is not specified). Defaults to the same value as the 'name' field if not specified.

        token_ttl : typing.Optional[str]
            Token time-to-live. If not provided, defaults to 24 hours. Use the format "1h", "1m", "1s" for hours, minutes, and seconds respectively, e.g., "24h" for 24 hours.

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

        Returns
        -------
        CreateTokenResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement
        from synqly.permissionset_base import Permissions
        from synqly.role_base import Resources

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.tokens.create_token(
                name="string",
                fullname="string",
                resources=Resources(),
                permission_set=Permissions.ADMINISTRATOR,
                token_ttl="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/tokens",
            method="POST",
            json={
                "name": name,
                "fullname": fullname,
                "resources": resources,
                "permission_set": permission_set,
                "token_ttl": token_ttl,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CreateTokenResponse,
                    construct_type(
                        type_=CreateTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create_mcp_token(
        self,
        *,
        scope: McpTokenScope,
        token_ttl: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateMcpTokenResponse:
        """
        Create a token for MCP authentication. This token is soley for MCP authentication and cannot
        authenticate with any other API.

        Parameters
        ----------
        scope : McpTokenScope
            Controls the tools that are available to the MCP server,
            and the APIs that can be accessed by the MCP server.

        token_ttl : typing.Optional[str]
            Token time-to-live. If not provided, defaults to 1 hour. May be set to a maximum of 24 hours. Use the format "1h", "1m", "1s" for hours, minutes, and seconds respectively, e.g., "2h" for 2 hours.

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

        Returns
        -------
        CreateMcpTokenResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement
        from synqly.tokens import McpTokenScope_Management

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.tokens.create_mcp_token(
                token_ttl="string",
                scope=McpTokenScope_Management(),
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/tokens/mcp",
            method="POST",
            json={
                "token_ttl": token_ttl,
                "scope": scope,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CreateMcpTokenResponse,
                    construct_type(
                        type_=CreateMcpTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create_integration_token(
        self,
        account_id: AccountId,
        integration_id: IntegrationId,
        *,
        name: typing.Optional[str] = OMIT,
        token_ttl: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateIntegrationTokenResponse:
        """
        Create an adhoc integration token restricted to a single integration. The token used to call
        this API must have the necessary permissions to create tokens and have access to the account
        and integration IDs. Permissions may not be escalated, so any operation that the invocation
        token does not have access to cannot be granted.

        Parameters
        ----------
        account_id : AccountId

        integration_id : IntegrationId

        name : typing.Optional[str]
            Unique name token. If not provided, defaults to generated newly created refresh token id.

        token_ttl : typing.Optional[str]
            Token time-to-live. If not provided, defaults to 10 minutes. Use the format "1h", "1m", "1s" for hours, minutes, and seconds respectively, e.g., "2h" for 2 hours.

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

        Returns
        -------
        CreateIntegrationTokenResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.tokens.create_integration_token(
                account_id="string",
                integration_id="string",
                name="string",
                token_ttl="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(account_id)}/{jsonable_encoder(integration_id)}",
            method="POST",
            json={
                "name": name,
                "token_ttl": token_ttl,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CreateIntegrationTokenResponse,
                    construct_type(
                        type_=CreateIntegrationTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create_synqly_integrations_token(
        self,
        *,
        token_ttl: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CreateSynqlyIntegrationsTokenResponse:
        """
        Create a token for managing Synqly-specific integrations. This token can be used with the integration APIs to manage
        integrations for Synqly-specific integrations, such as status events exports and async operations. See the
        [Synqly Integrations](https://docs.synqly.com/guides/synqly-integrations) documentation for more information.

        Parameters
        ----------
        token_ttl : typing.Optional[str]
            Token time-to-live. If not provided, defaults to 24 hours. Use the format "1h", "1m", "1s" for hours, minutes, and seconds respectively, e.g., "24h" for 24 hours.

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

        Returns
        -------
        CreateSynqlyIntegrationsTokenResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.tokens.create_synqly_integrations_token(
                token_ttl="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/tokens/synqly-integrations",
            method="POST",
            json={
                "token_ttl": token_ttl,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CreateSynqlyIntegrationsTokenResponse,
                    construct_type(
                        type_=CreateSynqlyIntegrationsTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def delete(
        self,
        refresh_token_id: TokenId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Deletes the Refresh Token with id `{id}`. This immediately
        invalidates both the primary and secondary token pairs.

        Parameters
        ----------
        refresh_token_id : TokenId

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

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.tokens.delete(
                refresh_token_id="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(refresh_token_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def list(
        self,
        *,
        limit: typing.Optional[int] = None,
        start_after: typing.Optional[str] = None,
        order: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        filter: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ListTokensResponse:
        """
        Returns a list of all `RefreshToken` objects belonging to the Authorization Bearer
        token. For more infromation on Tokens, refer to
        [Authentication](/api-reference/authentication).

        Parameters
        ----------
        limit : typing.Optional[int]
            Number of `Token` objects to return in this page. Defaults to 100.

        start_after : typing.Optional[str]
            Return `Token` objects starting after this `name`.

        order : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Select a field to order the results by. Defaults to `name`. To control the direction of the sorting, append
            `[asc]` or `[desc]` to the field name. For example, `name[desc]` will sort the results by `name` in descending order.
            The ordering defaults to `asc` if not specified. May be used multiple times to order by multiple fields, and the
            ordering is applied in the order the fields are specified.

        filter : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Filter results by this query. For more information on filtering, refer to our Filtering Guide. Defaults to no filter.
            If used more than once, the queries are ANDed together.

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

        Returns
        -------
        ListTokensResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.tokens.list(
                limit=1,
                start_after="string",
                order="string",
                filter="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/tokens",
            method="GET",
            params={
                "limit": limit,
                "start_after": start_after,
                "order": order,
                "filter": filter,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ListTokensResponse,
                    construct_type(
                        type_=ListTokensResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get(
        self,
        refresh_token_id: TokenId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> GetTokenResponse:
        """
        Returns the `RefreshToken` object matching `{tokenId}`. For more information on
        Tokens, refer to
        [Authentication](/api-reference/authentication).

        Parameters
        ----------
        refresh_token_id : TokenId

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

        Returns
        -------
        GetTokenResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.tokens.get(
                refresh_token_id="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(refresh_token_id)}/info",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    GetTokenResponse,
                    construct_type(
                        type_=GetTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def reset(
        self,
        owner_id: Id,
        refresh_token_id: TokenId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ResetTokenResponse:
        """
        This API can be used to reset `Organization` or `Integration` `RefreshTokens`.
        Resets the specified `RefreshToken` and expiration time, removes the secondary, and resets access and refresh tokens for the
        `RefreshToken` object matching `{ownerId}/{refreshTokenId}` where `ownerId` is an `organizationId` or `integrationId`.
        An `Organization` token with `administrator` permissions can be used to perform this operation.

        Parameters
        ----------
        owner_id : Id

        refresh_token_id : TokenId

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

        Returns
        -------
        ResetTokenResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.tokens.reset(
                owner_id="string",
                refresh_token_id="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(owner_id)}/{jsonable_encoder(refresh_token_id)}/reset",
            method="PUT",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ResetTokenResponse,
                    construct_type(
                        type_=ResetTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def rotate(
        self,
        owner_id: Id,
        refresh_token_id: TokenId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RotateTokenResponse:
        """
        This API can be used to rotate an `Organization` or `Integration` `RefreshTokens`.
        Rotate deletes the existing `Secondary` TokenPair, moves the `Primary` TokenPair to the `Secondary` TokenPair and creates a new `Primary` TokenPair for the
        `RefreshToken` object matching `{ownerId}/{refreshTokenId}` where `ownerId` is an `organizationId` or `integrationId`.
        An `Organization` token with `administrator` permissions can be used to perform this operation.

        Parameters
        ----------
        owner_id : Id

        refresh_token_id : TokenId

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

        Returns
        -------
        RotateTokenResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.tokens.rotate(
                owner_id="string",
                refresh_token_id="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(owner_id)}/{jsonable_encoder(refresh_token_id)}/rotate",
            method="PUT",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    RotateTokenResponse,
                    construct_type(
                        type_=RotateTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def refresh(
        self,
        refresh_token_id: TokenId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RefreshTokenResponse:
        """
        Creates a new primary `TokenPair` object, setting the secondary `TokenPair`
        to the previous primary value. Call `/v1/removeSecondaryToken` to remove
        this secondary backup once the new primary `TokenPair` has been deployed.

        Parameters
        ----------
        refresh_token_id : TokenId

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

        Returns
        -------
        RefreshTokenResponse

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.tokens.refresh(
                refresh_token_id="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(refresh_token_id)}/refresh",
            method="PUT",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    RefreshTokenResponse,
                    construct_type(
                        type_=RefreshTokenResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def remove_secondary(
        self,
        refresh_token_id: TokenId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Deletes the secondary `TokenPair` for the `RefreshToken` object
        matching `{refreshTokenId}`.

        Parameters
        ----------
        refresh_token_id : TokenId

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

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from synqly import AsyncSynqlyManagement

        client = AsyncSynqlyManagement(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.tokens.remove_secondary(
                refresh_token_id="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/tokens/{jsonable_encoder(refresh_token_id)}/secondary",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowedError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 409:
                raise ConflictError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 415:
                raise UnsupportedMediaTypeError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        Problem,
                        construct_type(
                            type_=Problem,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
