diff --git a/stubs/oauthlib/METADATA.toml b/stubs/oauthlib/METADATA.toml
index 04672bf3475d..08c524099754 100644
--- a/stubs/oauthlib/METADATA.toml
+++ b/stubs/oauthlib/METADATA.toml
@@ -1,4 +1,4 @@
-version = "3.2.*"
+version = "3.3.*"
 upstream_repository = "https://github.com/oauthlib/oauthlib"
 partial_stub = true
 
diff --git a/stubs/oauthlib/oauthlib/oauth2/__init__.pyi b/stubs/oauthlib/oauthlib/oauth2/__init__.pyi
index 8d5cb1a614b6..117244ab80d8 100644
--- a/stubs/oauthlib/oauthlib/oauth2/__init__.pyi
+++ b/stubs/oauthlib/oauthlib/oauth2/__init__.pyi
@@ -58,3 +58,8 @@ from .rfc6749.request_validator import RequestValidator as RequestValidator
 from .rfc6749.tokens import BearerToken as BearerToken, OAuth2Token as OAuth2Token
 from .rfc6749.utils import is_secure_transport as is_secure_transport
 from .rfc8628.clients import DeviceClient as DeviceClient
+from .rfc8628.endpoints import (
+    DeviceApplicationServer as DeviceApplicationServer,
+    DeviceAuthorizationEndpoint as DeviceAuthorizationEndpoint,
+)
+from .rfc8628.grant_types import DeviceCodeGrant as DeviceCodeGrant
diff --git a/stubs/oauthlib/oauthlib/oauth2/rfc6749/endpoints/pre_configured.pyi b/stubs/oauthlib/oauthlib/oauth2/rfc6749/endpoints/pre_configured.pyi
index 581c565c82e5..02414844d9fc 100644
--- a/stubs/oauthlib/oauthlib/oauth2/rfc6749/endpoints/pre_configured.pyi
+++ b/stubs/oauthlib/oauthlib/oauth2/rfc6749/endpoints/pre_configured.pyi
@@ -2,6 +2,7 @@ from _typeshed import Unused
 from collections.abc import Callable
 
 from oauthlib.common import Request
+from oauthlib.oauth2.rfc8628.grant_types import DeviceCodeGrant
 
 from ..grant_types import (
     AuthorizationCodeGrant,
@@ -24,6 +25,7 @@ class Server(AuthorizationEndpoint, IntrospectEndpoint, TokenEndpoint, ResourceE
     password_grant: ResourceOwnerPasswordCredentialsGrant
     credentials_grant: ClientCredentialsGrant
     refresh_grant: RefreshTokenGrant
+    device_code_grant: DeviceCodeGrant
     bearer: BearerToken
     def __init__(
         self,
diff --git a/stubs/oauthlib/oauthlib/oauth2/rfc6749/parameters.pyi b/stubs/oauthlib/oauthlib/oauth2/rfc6749/parameters.pyi
index 0d8fdfcc0987..c82a710d5205 100644
--- a/stubs/oauthlib/oauthlib/oauth2/rfc6749/parameters.pyi
+++ b/stubs/oauthlib/oauthlib/oauth2/rfc6749/parameters.pyi
@@ -44,3 +44,4 @@ def parse_token_response(
     body: str | bytes | bytearray, scope: str | set[object] | tuple[object] | list[object] | None = None
 ) -> OAuth2Token: ...
 def validate_token_parameters(params: dict[str, Incomplete]) -> None: ...
+def parse_expires(params: dict[str, Incomplete]) -> tuple[int | None, float | None, float | None]: ...
diff --git a/stubs/oauthlib/oauthlib/oauth2/rfc8628/__init__.pyi b/stubs/oauthlib/oauthlib/oauth2/rfc8628/__init__.pyi
index cb35af91145e..8963764427d2 100644
--- a/stubs/oauthlib/oauthlib/oauth2/rfc8628/__init__.pyi
+++ b/stubs/oauthlib/oauthlib/oauth2/rfc8628/__init__.pyi
@@ -1,3 +1,9 @@
 from logging import Logger
 
+from .errors import (
+    AuthorizationPendingError as AuthorizationPendingError,
+    ExpiredTokenError as ExpiredTokenError,
+    SlowDownError as SlowDownError,
+)
+
 log: Logger
diff --git a/stubs/oauthlib/oauthlib/oauth2/rfc8628/endpoints/__init__.pyi b/stubs/oauthlib/oauthlib/oauth2/rfc8628/endpoints/__init__.pyi
new file mode 100644
index 000000000000..65712957c40d
--- /dev/null
+++ b/stubs/oauthlib/oauthlib/oauth2/rfc8628/endpoints/__init__.pyi
@@ -0,0 +1,2 @@
+from .device_authorization import DeviceAuthorizationEndpoint as DeviceAuthorizationEndpoint
+from .pre_configured import DeviceApplicationServer as DeviceApplicationServer
diff --git a/stubs/oauthlib/oauthlib/oauth2/rfc8628/endpoints/device_authorization.pyi b/stubs/oauthlib/oauthlib/oauth2/rfc8628/endpoints/device_authorization.pyi
new file mode 100644
index 000000000000..ee67416c128a
--- /dev/null
+++ b/stubs/oauthlib/oauthlib/oauth2/rfc8628/endpoints/device_authorization.pyi
@@ -0,0 +1,32 @@
+from collections.abc import Callable
+from logging import Logger
+
+from oauthlib.common import Request, _HTTPMethod
+from oauthlib.oauth2.rfc6749.endpoints.base import BaseEndpoint
+from oauthlib.openid.connect.core.request_validator import RequestValidator
+
+log: Logger
+
+class DeviceAuthorizationEndpoint(BaseEndpoint):
+    request_validator: RequestValidator
+    user_code_generator: Callable[[None], str] | None
+    def __init__(
+        self,
+        request_validator: RequestValidator,
+        verification_uri: str,
+        expires_in: int = 1800,
+        interval: int | None = None,
+        verification_uri_complete: str | None = None,
+        user_code_generator: Callable[[None], str] | None = None,
+    ) -> None: ...
+    @property
+    def interval(self) -> int | None: ...
+    @property
+    def expires_in(self) -> int: ...
+    @property
+    def verification_uri(self) -> str: ...
+    def verification_uri_complete(self, user_code: str) -> str | None: ...
+    def validate_device_authorization_request(self, request: Request) -> None: ...
+    def create_device_authorization_response(
+        self, uri: str, http_method: _HTTPMethod = "POST", body: str | None = None, headers: dict[str, str] | None = None
+    ) -> tuple[dict[str, str], dict[str, str | int], int]: ...
diff --git a/stubs/oauthlib/oauthlib/oauth2/rfc8628/endpoints/pre_configured.pyi b/stubs/oauthlib/oauthlib/oauth2/rfc8628/endpoints/pre_configured.pyi
new file mode 100644
index 000000000000..943520667914
--- /dev/null
+++ b/stubs/oauthlib/oauthlib/oauth2/rfc8628/endpoints/pre_configured.pyi
@@ -0,0 +1,16 @@
+from collections.abc import Callable
+
+from oauthlib.openid.connect.core.request_validator import RequestValidator
+
+from .device_authorization import DeviceAuthorizationEndpoint
+
+class DeviceApplicationServer(DeviceAuthorizationEndpoint):
+    def __init__(
+        self,
+        request_validator: RequestValidator,
+        verification_uri: str,
+        interval: int = 5,
+        verification_uri_complete: str | None = None,
+        user_code_generator: Callable[[None], str] | None = None,
+        **kwargs,
+    ) -> None: ...
diff --git a/stubs/oauthlib/oauthlib/oauth2/rfc8628/errors.pyi b/stubs/oauthlib/oauthlib/oauth2/rfc8628/errors.pyi
new file mode 100644
index 000000000000..9858cb379e23
--- /dev/null
+++ b/stubs/oauthlib/oauthlib/oauth2/rfc8628/errors.pyi
@@ -0,0 +1,13 @@
+from oauthlib.oauth2.rfc6749.errors import OAuth2Error
+
+class AuthorizationPendingError(OAuth2Error):
+    error: str
+
+class SlowDownError(OAuth2Error):
+    error: str
+
+class ExpiredTokenError(OAuth2Error):
+    error: str
+
+class AccessDenied(OAuth2Error):
+    error: str
diff --git a/stubs/oauthlib/oauthlib/oauth2/rfc8628/grant_types/__init__.pyi b/stubs/oauthlib/oauthlib/oauth2/rfc8628/grant_types/__init__.pyi
new file mode 100644
index 000000000000..6163747ce035
--- /dev/null
+++ b/stubs/oauthlib/oauthlib/oauth2/rfc8628/grant_types/__init__.pyi
@@ -0,0 +1 @@
+from .device_code import DeviceCodeGrant as DeviceCodeGrant
diff --git a/stubs/oauthlib/oauthlib/oauth2/rfc8628/grant_types/device_code.pyi b/stubs/oauthlib/oauthlib/oauth2/rfc8628/grant_types/device_code.pyi
new file mode 100644
index 000000000000..0f70cb3b542b
--- /dev/null
+++ b/stubs/oauthlib/oauthlib/oauth2/rfc8628/grant_types/device_code.pyi
@@ -0,0 +1,8 @@
+from oauthlib.common import Request
+from oauthlib.oauth2.rfc6749.grant_types.base import GrantTypeBase
+from oauthlib.oauth2.rfc6749.tokens import TokenBase
+
+class DeviceCodeGrant(GrantTypeBase):
+    def create_authorization_response(self, request: Request, token_handler: TokenBase) -> tuple[dict[str, str], str, int]: ...
+    def validate_token_request(self, request: Request) -> None: ...
+    def create_token_response(self, request: Request, token_handler: TokenBase) -> tuple[dict[str, str], str, int]: ...
diff --git a/stubs/oauthlib/oauthlib/oauth2/rfc8628/request_validator.pyi b/stubs/oauthlib/oauthlib/oauth2/rfc8628/request_validator.pyi
new file mode 100644
index 000000000000..9fa7b042c5a0
--- /dev/null
+++ b/stubs/oauthlib/oauthlib/oauth2/rfc8628/request_validator.pyi
@@ -0,0 +1,5 @@
+from oauthlib.common import Request
+from oauthlib.oauth2 import RequestValidator as OAuth2RequestValidator
+
+class RequestValidator(OAuth2RequestValidator):
+    def client_authentication_required(self, request: Request, *args, **kwargs) -> bool: ...
diff --git a/stubs/oauthlib/oauthlib/openid/connect/core/endpoints/pre_configured.pyi b/stubs/oauthlib/oauthlib/openid/connect/core/endpoints/pre_configured.pyi
index 0b6aae6a772e..379d9cd847bf 100644
--- a/stubs/oauthlib/oauthlib/openid/connect/core/endpoints/pre_configured.pyi
+++ b/stubs/oauthlib/oauthlib/openid/connect/core/endpoints/pre_configured.pyi
@@ -18,6 +18,7 @@ from oauthlib.oauth2.rfc6749.grant_types import (
 )
 from oauthlib.oauth2.rfc6749.request_validator import RequestValidator as OAuth2RequestValidator
 from oauthlib.oauth2.rfc6749.tokens import BearerToken
+from oauthlib.oauth2.rfc8628.grant_types import DeviceCodeGrant
 
 from ..grant_types import AuthorizationCodeGrant, HybridGrant, ImplicitGrant
 from ..grant_types.dispatchers import (
@@ -37,6 +38,7 @@ class Server(AuthorizationEndpoint, IntrospectEndpoint, TokenEndpoint, ResourceE
     openid_connect_auth: AuthorizationCodeGrant
     openid_connect_implicit: ImplicitGrant
     openid_connect_hybrid: HybridGrant
+    device_code_grant: DeviceCodeGrant
     bearer: BearerToken
     jwt: JWTToken
     auth_grant_choice: AuthorizationCodeGrantDispatcher