Repository: auth0/auth0-python
Pull request #227 (2020-07-03 08:40:36)

Add Hooks management API
### Changes

Adds the Hooks management API that was missing in auth0-python, along with unit tests.
It also includes Hooks Secrets management.

### References

API docs: https://auth0.com/docs/api/management/v2#!/Hooks/get_hooks
Closes https://github.com/auth0/auth0-python/issues/224

### Testing

- [X] This change adds unit test coverage
- [X] This change has been tested on Python 3.8

### Checklist

- [X] I have read the [Auth0 general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
- [X] I have read the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
- [X] All existing and new tests complete without errors



Patch:
diff --git a/README.rst b/README.rst
index c80209a..d405e16 100644
--- a/README.rst
+++ b/README.rst
@@ -229,15 +229,19 @@ Available Management Endpoints
 - Blacklists() ( ``Auth0().blacklists`` )
 - Clients() ( ``Auth0().clients`` )
 - ClientGrants() ( ``Auth0().client_grants`` )
+- CustomDomains() ( ``Auth0().custom_domains`` )
 - Connections() ( ``Auth0().connections`` )
 - DeviceCredentials() ( ``Auth0().device_credentials`` )
 - Emails() ( ``Auth0().emails`` )
 - EmailTemplates() ( ``Auth0().email_templates`` )
+- Grants() ( ``Auth0().grants`` )
 - Guardian() ( ``Auth0().guardian`` )
 - Jobs() ( ``Auth0().jobs`` )
 - Logs() ( ``Auth0().logs`` )
 - ResourceServers() (``Auth0().resource_servers`` )
+- Roles() ( ``Auth0().roles`` )
 - Rules() ( ``Auth0().rules`` )
+- RulesConfigs() ( ``Auth0().rules_configs`` )
 - Stats() ( ``Auth0().stats`` )
 - Tenants() ( ``Auth0().tenants`` )
 - Tickets() ( ``Auth0().tickets`` )
diff --git a/auth0/v3/authentication/database.py b/auth0/v3/authentication/database.py
index f867384..e89a825 100644
--- a/auth0/v3/authentication/database.py
+++ b/auth0/v3/authentication/database.py
@@ -1,9 +1,9 @@
-from .base import AuthenticationBase
 import warnings
 
+from .base import AuthenticationBase
 
-class Database(AuthenticationBase):
 
+class Database(AuthenticationBase):
     """Database & Active Directory / LDAP Authentication.
 
     Args:
@@ -21,24 +21,25 @@ class Database(AuthenticationBase):
         Windows Azure AD and ADFS.
         """
         warnings.warn("/oauth/ro will be deprecated in future releases", DeprecationWarning)
-        return self.post(
-            'https://{}/oauth/ro'.format(self.domain),
-            data={
-                'client_id': client_id,
-                'username': username,
-                'password': password,
-                'id_token': id_token,
-                'connection': connection,
-                'device': device,
-                'grant_type': grant_type,
-                'scope': scope,
-            }
-        )
-
-    def signup(self, client_id, email, password, connection, username=None,
-             user_metadata=None):
+
+        body = {
+            'client_id': client_id,
+            'username': username,
+            'password': password,
+            'connection': connection,
+            'grant_type': grant_type,
+            'scope': scope,
+        }
+        if id_token:
+            body.update({'id_token': id_token})
+        if device:
+            body.update({'device': device})
+        return self.post('https://{}/oauth/ro'.format(self.domain), data=body)
+
+    def signup(self, client_id, email, password, connection, username=None, user_metadata=None,
+               given_name=None, family_name=None, name=None, nickname=None, picture=None):
         """Signup using email and password.
-        
+
         Args:
            client_id (str): ID of the application to use.
 
@@ -53,6 +54,17 @@ class Database(AuthenticationBase):
            user_metadata (dict, optional): Additional key-value information to store for the user.
                     Some limitations apply, see: https://auth0.com/docs/metadata#metadata-restrictions
 
+           given_name (str, optional): The user's given name(s).
+
+           family_name (str, optional): The user's family name(s).
+
+           name (str, optional): The user's full name.
+
+           nickname (str, optional): The user's nickname.
+
+           picture (str, optional): A URI pointing to the user's picture.
+
+
         See: https://auth0.com/docs/api/authentication#signup
         """
         body = {
@@ -60,25 +72,37 @@ class Database(AuthenticationBase):
             'email': email,
             'password': password,
             'connection': connection,
-            'username': username,
-            'user_metadata': user_metadata
         }
-
-        return self.post(
-            'https://{}/dbconnections/signup'.format(self.domain),
-            data=body
-        )
+        if username:
+            body.update({'username': username})
+        if user_metadata:
+            body.update({'user_metadata': user_metadata})
+        if given_name:
+            body.update({'given_name': given_name})
+        if family_name:
+            body.update({'family_name': family_name})
+        if name:
+            body.update({'name': name})
+        if nickname:
+            body.update({'nickname': nickname})
+        if picture:
+            body.update({'picture': picture})
+
+        return self.post('https://{}/dbconnections/signup'.format(self.domain), data=body)
 
     def change_password(self, client_id, email, connection, password=None):
         """Asks to change a password for a given user.
-        """
+            
+           client_id (str): ID of the application to use.
+
+           email (str): The user's email address.
 
-        return self.post(
-            'https://{}/dbconnections/change_password'.format(self.domain),
-            data={
-                'client_id': client_id,
-                'email': email,
-                'password': password,
-                'connection': connection,
-            }
-        )
+           connection (str): The name of the database connection where this user should be created.
+        """
+        body = {
+            'client_id': client_id,
+            'email': email,
+            'connection': connection,
+        }
+        
+        return self.post('https://{}/dbconnections/change_password'.format(self.domain), data=body)
diff --git a/auth0/v3/authentication/delegated.py b/auth0/v3/authentication/delegated.py
index 5c738de..f84cef2 100644
--- a/auth0/v3/authentication/delegated.py
+++ b/auth0/v3/authentication/delegated.py
@@ -2,7 +2,6 @@ from .base import AuthenticationBase
 
 
 class Delegated(AuthenticationBase):
-
     """Delegated authentication endpoints.
 
     Args:
@@ -35,7 +34,4 @@ class Delegated(AuthenticationBase):
             raise ValueError('Either id_token or refresh_token must '
                              'have a value')
 
-        return self.post(
-            'https://{}/delegation'.format(self.domain),
-            data=data
-        )
+        return self.post('https://{}/delegation'.format(self.domain), data=data)
diff --git a/auth0/v3/authentication/revoke_token.py b/auth0/v3/authentication/revoke_token.py
index 1705bb1..9523c5f 100644
--- a/auth0/v3/authentication/revoke_token.py
+++ b/auth0/v3/authentication/revoke_token.py
@@ -2,7 +2,6 @@ from .base import AuthenticationBase
 
 
 class RevokeToken(AuthenticationBase):
-
     """Revoke Refresh Token endpoint
 
     Args:
@@ -30,8 +29,9 @@ class RevokeToken(AuthenticationBase):
         body = {
             'client_id': client_id,
             'token': token,
-            'client_secret': client_secret
         }
 
-        return self.post(
-            'https://{}/oauth/revoke'.format(self.domain), data=body)
+        if client_secret:
+            body.update({'client_secret': client_secret})
+
+        return self.post('https://{}/oauth/revoke'.format(self.domain), data=body)
diff --git a/auth0/v3/authentication/token_verifier.py b/auth0/v3/authentication/token_verifier.py
index 70a42ea..e86938a 100644
--- a/auth0/v3/authentication/token_verifier.py
+++ b/auth0/v3/authentication/token_verifier.py
@@ -82,7 +82,8 @@ class SymmetricSignatureVerifier(SignatureVerifier):
     """Verifier for HMAC signatures, which rely on shared secrets.
 
     Args:
-        algorithm (str, optional): The expected signing algorithm. Defaults to "RS256".
+        shared_secret (str): The shared secret used to decode the token.
+        algorithm (str, optional): The expected signing algorithm. Defaults to "HS256".
     """
 
     def __init__(self, shared_secret, algorithm="HS256"):
@@ -97,7 +98,8 @@ class AsymmetricSignatureVerifier(SignatureVerifier):
     """Verifier for RSA signatures, which rely on public key certificates.
 
     Args:
-        algorithm (str, optional): The expected signing algorithm. Defaults to "HS256".
+        jwks_url (str): The url where the JWK set is located.
+        algorithm (str, optional): The expected signing algorithm. Defaults to "RS256".
     """
 
     def __init__(self, jwks_url, algorithm="RS256"):
diff --git a/auth0/v3/management/__init__.py b/auth0/v3/management/__init__.py
index 3c8c032..547425f 100644
--- a/auth0/v3/management/__init__.py
+++ b/auth0/v3/management/__init__.py
@@ -1,12 +1,12 @@
 from .auth0 import Auth0
 from .blacklists import Blacklists
-from .clients import Clients
 from .client_grants import ClientGrants
+from .clients import Clients
 from .connections import Connections
 from .custom_domains import CustomDomains
 from .device_credentials import DeviceCredentials
-from .emails import Emails
 from .email_templates import EmailTemplates
+from .emails import Emails
 from .grants import Grants
 from .guardian import Guardian
 from .jobs import Jobs
diff --git a/auth0/v3/management/auth0.py b/auth0/v3/management/auth0.py
index f51ef69..850e599 100644
--- a/auth0/v3/management/auth0.py
+++ b/auth0/v3/management/auth0.py
@@ -1,13 +1,14 @@
-from .grants import Grants
-from .custom_domains import CustomDomains
 from .blacklists import Blacklists
-from .clients import Clients
 from .client_grants import ClientGrants
+from .clients import Clients
 from .connections import Connections
+from .custom_domains import CustomDomains
 from .device_credentials import DeviceCredentials
-from .emails import Emails
 from .email_templates import EmailTemplates
+from .emails import Emails
+from .grants import Grants
 from .guardian import Guardian
+from .hooks import Hooks
 from .jobs import Jobs
 from .logs import Logs
 from .resource_servers import ResourceServers
@@ -42,6 +43,7 @@ class Auth0(object):
         self.email_templates = EmailTemplates(domain, token)
         self.grants = Grants(domain, token)
         self.guardian = Guardian(domain, token)
+        self.hooks = Hooks(domain, token)
         self.jobs = Jobs(domain, token)
         self.logs = Logs(domain, token)
         self.resource_servers = ResourceServers(domain, token)
diff --git a/auth0/v3/management/blacklists.py b/auth0/v3/management/blacklists.py
index c1fe86b..219a0fd 100644
--- a/auth0/v3/management/blacklists.py
+++ b/auth0/v3/management/blacklists.py
@@ -39,16 +39,22 @@ class Blacklists(object):
 
         return self.client.get(self.url, params=params)
 
-    def create(self, jti, aud=''):
+    def create(self, jti, aud=None):
         """Adds a token to the blacklist.
 
         Args:
             jti (str): the jti of the JWT to blacklist.
+
             aud (str, optional): The JWT's aud claim. The client_id of the
                 application for which it was issued.
 
-            body (dict):
-            	See: https://auth0.com/docs/api/management/v2#!/Blacklists/post_tokens
+        See: https://auth0.com/docs/api/management/v2#!/Blacklists/post_tokens
         """
+        body = {
+            'jti': jti,
+        }
+
+        if aud:
+            body.update({'aud': aud})
 
-        return self.client.post(self.url, data={'jti': jti, 'aud': aud})
+        return self.client.post(self.url, data=body)
diff --git a/auth0/v3/management/client_grants.py b/auth0/v3/management/client_grants.py
index b64ae82..3c16904 100644
--- a/auth0/v3/management/client_grants.py
+++ b/auth0/v3/management/client_grants.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class ClientGrants(object):
-
     """Auth0 client grants endpoints
 
     Args:
@@ -34,16 +33,18 @@ class ClientGrants(object):
 
         Args:
             audience (str, optional): URL encoded audience of a Resource Server
-                to filter
+                to filter.
 
-            page (int, optional): The result's page number (zero based).
+            page (int, optional): The result's page number (zero based). When not set,
+                the default value is up to the server.
 
-            per_page (int, optional): The amount of entries per page.
+            per_page (int, optional): The amount of entries per page. When not set,
+                the default value is up to the server.
 
             include_totals (bool, optional): True if the query summary is
-                to be included in the result, False otherwise.
+                to be included in the result, False otherwise. Defaults to False.
 
-            client_id (string, optional): The id of a client to filter
+            client_id (string, optional): The id of a client to filter.
 
         See: https://auth0.com/docs/api/management/v2#!/Client_Grants/get_client_grants
         """
@@ -63,7 +64,8 @@ class ClientGrants(object):
 
         Args:
            body (dict): Attributes for the new client grant.
-              See: https://auth0.com/docs/api/management/v2#!/Client_Grants/post_client_grants
+
+        See: https://auth0.com/docs/api/management/v2#!/Client_Grants/post_client_grants
         """
 
         return self.client.post(self._url(), data=body)
@@ -74,7 +76,6 @@ class ClientGrants(object):
         Args:
            id (str): Id of client grant to delete.
 
-
         See: https://auth0.com/docs/api/management/v2#!/Client_Grants/delete_client_grants_by_id
         """
 
@@ -86,8 +87,9 @@ class ClientGrants(object):
         Args:
            id (str): The id of the client grant to modify.
 
-           body (dict): Attributes to modify.
-              See: https://auth0.com/docs/api/management/v2#!/Client_Grants/patch_client_grants_by_id
+           body (dict): Attributes to update.
+
+        See: https://auth0.com/docs/api/management/v2#!/Client_Grants/patch_client_grants_by_id
         """
 
         return self.client.patch(self._url(id), data=body)
diff --git a/auth0/v3/management/clients.py b/auth0/v3/management/clients.py
index 3bedd58..2360c91 100644
--- a/auth0/v3/management/clients.py
+++ b/auth0/v3/management/clients.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class Clients(object):
-
     """Auth0 applications endpoints
 
     Args:
@@ -37,21 +36,22 @@ class Clients(object):
 
         Args:
            fields (list of str, optional): A list of fields to include or
-              exclude from the result (depending on include_fields). Empty to
+              exclude from the result (depending on include_fields). Leave empty to
               retrieve all fields.
 
            include_fields (bool, optional): True if the fields specified are
-              to be included in the result, False otherwise.
+              to be included in the result, False otherwise. Defaults to True.
 
-           page (int): The result's page number (zero based).
+           page (int): The result's page number (zero based). When not set,
+              the default value is up to the server.
 
-           per_page (int, optional): The amount of entries per page.
+           per_page (int, optional): The amount of entries per page. When not set,
+              the default value is up to the server.
 
            extra_params (dictionary, optional): The extra parameters to add to
              the request. The fields, include_fields, page and per_page values
              specified as parameters take precedence over the ones defined here.
 
-
         See: https://auth0.com/docs/api/management/v2#!/Clients/get_clients
         """
         params = extra_params or {}
@@ -67,7 +67,8 @@ class Clients(object):
 
         Args:
            body (dict): Attributes for the new application.
-              See: https://auth0.com/docs/api/v2#!/Clients/post_clients
+
+        See: https://auth0.com/docs/api/v2#!/Clients/post_clients
         """
 
         return self.client.post(self._url(), data=body)
@@ -82,12 +83,11 @@ class Clients(object):
            id (str): Id of the application to get.
 
            fields (list of str, optional): A list of fields to include or
-              exclude from the result (depending on include_fields). Empty to
+              exclude from the result (depending on include_fields). Leave empty to
               retrieve all fields.
 
            include_fields (bool, optional): True if the fields specified are
-              to be included in the result, False otherwise.
-
+              to be included in the result, False otherwise. Defaults to True.
 
         See: https://auth0.com/docs/api/management/v2#!/Clients/get_clients_by_id
         """
@@ -103,7 +103,6 @@ class Clients(object):
         Args:
            id (str): Id of application to delete.
 
-
         See: https://auth0.com/docs/api/management/v2#!/Clients/delete_clients_by_id
         """
 
@@ -119,7 +118,8 @@ class Clients(object):
            id (str): Client ID of the application.
 
            body (dict): Attributes to modify.
-              See: https://auth0.com/docs/api/management/v2#!/Clients/patch_clients_by_id
+
+        See: https://auth0.com/docs/api/management/v2#!/Clients/patch_clients_by_id
         """
 
         return self.client.patch(self._url(id), data=body)
@@ -130,11 +130,10 @@ class Clients(object):
         Args:
            id (str): Client ID of the application.
 
-           body (dict): Attributes to modify.
-              See: https://auth0.com/docs/api/management/v2#!/Clients/post_rotate_secret
+        See: https://auth0.com/docs/api/management/v2#!/Clients/post_rotate_secret
         """
 
-        data = {'id': id }
+        data = {'id': id}
 
         url = self._url('%s/rotate-secret' % id)
-        return self.client.post(url, data=data)
\ No newline at end of file
+        return self.client.post(url, data=data)
diff --git a/auth0/v3/management/connections.py b/auth0/v3/management/connections.py
index 3c372df..a32953c 100644
--- a/auth0/v3/management/connections.py
+++ b/auth0/v3/management/connections.py
@@ -36,15 +36,17 @@ class Connections(object):
               this strategy type. (e.g: strategy='amazon')
 
            fields (list of str, optional): A list of fields to include or
-              exclude from the result (depending on include_fields). Empty to
-              retrieve all fields.
+              exclude from the result (depending on include_fields). Leave empty to
+              retrieve all fields. By default, all the fields will be retrieved.
 
            include_fields (bool, optional): True if the fields specified are
-              to be included in the result, False otherwise.
+              to be included in the result, False otherwise. Defaults to True.
 
-           page (int): The result's page number (zero based).
+           page (int): The result's page number (zero based). When not set,
+              the default value is up to the server.
 
-           per_page (int, optional): The amount of entries per page.
+           per_page (int, optional): The amount of entries per page. When not set,
+              the default value is up to the server.
 
            extra_params (dictionary, optional): The extra parameters to add to
              the request. The fields, include_fields, page and per_page values
@@ -72,11 +74,11 @@ class Connections(object):
            id (str): Id of the connection to get.
 
            fields (list of str, optional): A list of fields to include or
-              exclude from the result (depending on include_fields). Empty to
-              retrieve all fields.
+              exclude from the result (depending on include_fields). Leave empty to
+              retrieve all fields. By default, all the fields will be retrieved.
 
            include_fields (bool, optional): True if the fields specified are
-              to be included in the result, False otherwise.
+              to be included in the result, False otherwise. Defaults to True.
 
         See: https://auth0.com/docs/api/management/v2#!/Connections/get_connections_by_id
 
@@ -109,9 +111,9 @@ class Connections(object):
         Args:
            id: Id of the connection.
 
-           body (dict): Specifies which fields are to be modified, and to what
-              values.
-              See: https://auth0.com/docs/api/management/v2#!/Connections/patch_connections_by_id
+           body (dict): Specifies which fields are to be modified, and to what values.
+
+        See: https://auth0.com/docs/api/management/v2#!/Connections/patch_connections_by_id
 
         Returns:
            The modified connection object.
@@ -125,7 +127,8 @@ class Connections(object):
         Args:
             body (dict): Attributes used to create the connection. Mandatory
                 attributes are: 'name' and 'strategy'.
-                See: https://auth0.com/docs/api/management/v2#!/Connections/post_connections
+
+        See: https://auth0.com/docs/api/management/v2#!/Connections/post_connections
         """
 
         return self.client.post(self._url(), data=body)
diff --git a/auth0/v3/management/custom_domains.py b/auth0/v3/management/custom_domains.py
index c31f19d..c463da8 100644
--- a/auth0/v3/management/custom_domains.py
+++ b/auth0/v3/management/custom_domains.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class CustomDomains(object):
-
     """Auth0 custom domains endpoints
 
     Args:
@@ -48,8 +47,7 @@ class CustomDomains(object):
         """Deletes a grant.
 
         Args:
-           id (str): The id of the custom domain to delete
-
+           id (str): The id of the custom domain to delete.
 
         See: https://auth0.com/docs/api/management/v2#!/Custom_Domains/delete_custom_domains_by_id
         """
@@ -57,24 +55,22 @@ class CustomDomains(object):
         return self.client.delete(url)
 
     def create_new(self, body):
-        """Configure a new custom domain
+        """Configure a new custom domain.
 
         Args:
-           body (str): The domain, tye and verification method in json
-
+           body (str): The domain, tye and verification method in json.
 
         See: https://auth0.com/docs/api/management/v2#!/Custom_Domains/post_custom_domains
         """
         return self.client.post(self._url(), data=body)
 
     def verify(self, id):
-        """Verify a custom domain
+        """Verify a custom domain.
 
         Args:
-           id (str): The id of the custom domain to delete
-
+           id (str): The id of the custom domain to delete.
 
         See: https://auth0.com/docs/api/management/v2#!/Custom_Domains/post_verify
         """
         url = self._url('%s/verify' % (id))
-        return self.client.post(url)
\ No newline at end of file
+        return self.client.post(url)
diff --git a/auth0/v3/management/device_credentials.py b/auth0/v3/management/device_credentials.py
index 6b7b31d..ff49bf3 100644
--- a/auth0/v3/management/device_credentials.py
+++ b/auth0/v3/management/device_credentials.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class DeviceCredentials(object):
-
     """Auth0 connection endpoints
 
     Args:
@@ -40,13 +39,11 @@ class DeviceCredentials(object):
             type (str): The type of credentials (public_key, refresh_token).
 
             fields (list, optional): A list of fields to include or exclude
-                (depending on include_fields) from the result, empty to
-                retrieve all fields
+                (depending on include_fields) from the result. Leave empty to
+                retrieve all fields.
 
             include_fields (bool, optional): True if the fields specified are
-                to be included in the result, False otherwise
-                (defaults to true)
-
+                to be included in the result, False otherwise. Defaults to True.
 
         See: https://auth0.com/docs/api/management/v2#!/Device_Credentials/get_device_credentials
         """
@@ -66,7 +63,8 @@ class DeviceCredentials(object):
         Args:
             body (dict): parameters for creating the public key (e.g: type,
                 device_name, client_id, etc).
-                Please see: https://auth0.com/docs/api/v2#!/Device_Credentials/post_device_credentials
+
+        See: https://auth0.com/docs/api/v2#!/Device_Credentials/post_device_credentials
         """
         return self.client.post(self._url(), data=body)
 
@@ -74,8 +72,7 @@ class DeviceCredentials(object):
         """Delete credential.
 
         Args:
-            id (str):  The id of the credential to delete
-
+            id (str):  The id of the credential to delete.
 
         See: https://auth0.com/docs/api/management/v2#!/Device_Credentials/delete_device_credentials_by_id
         """
diff --git a/auth0/v3/management/email_templates.py b/auth0/v3/management/email_templates.py
index dcda2bf..47fc68d 100644
--- a/auth0/v3/management/email_templates.py
+++ b/auth0/v3/management/email_templates.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class EmailTemplates(object):
-
     """Auth0 email templates endpoints
 
     Args:
@@ -34,7 +33,8 @@ class EmailTemplates(object):
 
         Args:
            body (dict): Attributes for the new email template.
-              See: https://auth0.com/docs/api/management/v2#!/Email_Templates/post_email_templates
+
+        See: https://auth0.com/docs/api/management/v2#!/Email_Templates/post_email_templates
         """
 
         return self.client.post(self._url(), data=body)
@@ -63,8 +63,8 @@ class EmailTemplates(object):
               'change_password', 'password_reset', 'mfa_oob_code'.
 
            body (dict): Attributes to update on the email template.
-              See: https://auth0.com/docs/api/management/v2#!/Email_Templates/patch_email_templates_by_templateName
 
+        See: https://auth0.com/docs/api/management/v2#!/Email_Templates/patch_email_templates_by_templateName
         """
 
         return self.client.patch(self._url(template_name), data=body)
diff --git a/auth0/v3/management/emails.py b/auth0/v3/management/emails.py
index e88f4e7..9934212 100644
--- a/auth0/v3/management/emails.py
+++ b/auth0/v3/management/emails.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class Emails(object):
-
     """Auth0 email endpoints
 
     Args:
@@ -34,11 +33,11 @@ class Emails(object):
 
         Args:
             fields (list of str, optional): A list of fields to include or
-                exclude from the result (depending on include_fields). Empty
-                to retrieve all fields.
+                exclude from the result (depending on include_fields). Leave empty to
+                retrieve all fields.
 
             include_fields (bool, optional): True if the fields specified are
-                to be included in the result, False otherwise.
+                to be included in the result, False otherwise. Defaults to True.
 
         See: https://auth0.com/docs/api/management/v2#!/Emails/get_provider
         """
@@ -51,7 +50,9 @@ class Emails(object):
         """Configure the email provider.
 
         Args:
-            body (dict): Please see: https://auth0.com/docs/api/v2#!/Emails/post_provider
+            body (dict): attributes of the created email provider.
+
+        See: https://auth0.com/docs/api/v2#!/Emails/post_provider
         """
         return self.client.post(self._url(), data=body)
 
@@ -66,6 +67,8 @@ class Emails(object):
         """Update the email provider.
 
         Args:
-            body (dict): Please see: https://auth0.com/docs/api/v2#!/Emails/patch_provider
+            body (dict): attributes to update on the email provider
+
+        See: https://auth0.com/docs/api/v2#!/Emails/patch_provider
         """
         return self.client.patch(self._url(), data=body)
diff --git a/auth0/v3/management/grants.py b/auth0/v3/management/grants.py
index d80c4f4..a5d8b4f 100644
--- a/auth0/v3/management/grants.py
+++ b/auth0/v3/management/grants.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class Grants(object):
-
     """Auth0 grants endpoints
 
     Args:
@@ -33,16 +32,18 @@ class Grants(object):
         """Retrieves all grants.
 
         Args:
-            page (int, optional): The result's page number (zero based).
+            page (int, optional): The result's page number (zero based). When not set,
+               the default value is up to the server.
 
-            per_page (int, optional): The amount of entries per page.
+            per_page (int, optional): The amount of entries per page. When not set,
+               the default value is up to the server.
 
             include_totals (bool, optional): True if the query summary is
-                to be included in the result, False otherwise.
+               to be included in the result, False otherwise. Defaults to False.
 
            extra_params (dictionary, optional): The extra parameters to add to
-             the request. The page, per_page, and include_totals values
-             specified as parameters take precedence over the ones defined here.
+               the request. The page, per_page, and include_totals values
+               specified as parameters take precedence over the ones defined here.
             
         See: https://auth0.com/docs/api/management/v2#!/Grants/get_grants
         """
@@ -59,10 +60,9 @@ class Grants(object):
         """Deletes a grant.
 
         Args:
-           id (str): The id of the grant to delete
-
+           id (str): The id of the grant to delete.
 
         See: https://auth0.com/docs/api/management/v2#!/Grants/delete_grants_by_id
         """
         url = self._url('%s' % (id))
-        return self.client.delete(url)
\ No newline at end of file
+        return self.client.delete(url)
diff --git a/auth0/v3/management/guardian.py b/auth0/v3/management/guardian.py
index ff77a60..01f6456 100644
--- a/auth0/v3/management/guardian.py
+++ b/auth0/v3/management/guardian.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class Guardian(object):
-
     """Auth0 guardian endpoints
 
     Args:
@@ -39,13 +38,15 @@ class Guardian(object):
         return self.client.get(self._url('factors'))
 
     def update_factor(self, name, body):
-        """Update Guardian factor
-        Useful to enable / disable factor
+        """Update Guardian factor.
+        Useful to enable / disable factor.
 
         Args:
-            name (str): Either push-notification or sms
+            name (str): Either push-notification or sms.
+
             body (dict): Attributes to modify.
-            See: https://auth0.com/docs/api/management/v2#!/Guardian/put_factors_by_name
+
+        See: https://auth0.com/docs/api/management/v2#!/Guardian/put_factors_by_name
         """
         url = self._url('factors/{}'.format(name))
         return self.client.put(url, data=body)
@@ -53,22 +54,22 @@ class Guardian(object):
     def update_templates(self, body):
         """Update enrollment and verification SMS templates.
 
-        Useful to send custom messages on sms enrollment and verification
+        Useful to send custom messages on sms enrollment and verification.
 
         Args:
             body (dict): Attributes to modify.
-            See: https://auth0.com/docs/api/management/v2#!/Guardian/put_templates
+
+        See: https://auth0.com/docs/api/management/v2#!/Guardian/put_templates
         """
 
         return self.client.put(self._url('factors/sms/templates'), data=body)
 
     def get_templates(self):
-        """Get enrollment and verification templates
+        """Get enrollment and verification templates.
 
         Retrieve both templates. Useful to check if a different template than
             default was set.
 
-
         See: https://auth0.com/docs/api/management/v2#!/Guardian/get_templates
         """
 
@@ -79,8 +80,7 @@ class Guardian(object):
         Useful to check its type and related metadata.
 
         Args:
-           id (str): The id of the device account to update
-
+           id (str): The id of the device account to update.
 
         See: https://auth0.com/docs/api/management/v2#!/Guardian/get_enrollments_by_id
         """
@@ -93,8 +93,7 @@ class Guardian(object):
         Useful when you want to force re-enroll.
 
         Args:
-           id (str): The id of the device account to update
-
+           id (str): The id of the device account to update.
 
         See: https://auth0.com/docs/api/management/v2#!/Guardian/delete_enrollments_by_id
         """
@@ -105,41 +104,44 @@ class Guardian(object):
         """Creates an enrollment ticket for user_id
 
         A useful way to send an email to a user, with a link that lead to
-            start the enrollment process
+            start the enrollment process.
 
         Args:
             body (dict): Details of the user to send the ticket to.
-            See: https://auth0.com/docs/api/management/v2#!/Guardian/post_ticket
+
+        See: https://auth0.com/docs/api/management/v2#!/Guardian/post_ticket
         """
         return self.client.post(self._url('enrollments/ticket'), data=body)
 
     def get_factor_providers(self, factor_name, name):
         """Get Guardian SNS or SMS factor providers.
 
-        Returns provider configuration
+        Returns provider configuration.
+
         Args:
-           factor_name (str): Either push-notification or sms
-           name (str): Name of the provider
+           factor_name (str): Either push-notification or sms.
 
+           name (str): Name of the provider.
 
         See: https://auth0.com/docs/api/management/v2#!/Guardian/get_sns
              https://auth0.com/docs/api/management/v2#!/Guardian/get_twilio
-"""
+        """
         url = self._url('factors/{}/providers/{}'.format(factor_name, name))
         return self.client.get(url)
 
     def update_factor_providers(self, factor_name, name, body):
         """Get Guardian factor providers.
 
-        Returns provider configuration
+        Returns provider configuration.
+
         Args:
-           factor_name (str): Either push-notification or sms
-           name (str): Name of the provider
+           factor_name (str): Either push-notification or sms.
+
+           name (str): Name of the provider.
 
-           body (dict):
-               See: https://auth0.com/docs/api/management/v2#!/Guardian/put_twilio
+           body (dict): Details of the factor provider.
+
+        See: https://auth0.com/docs/api/management/v2#!/Guardian/put_twilio
         """
         url = self._url('factors/{}/providers/{}'.format(factor_name, name))
         return self.client.put(url, data=body)
-
-
diff --git a/auth0/v3/management/hooks.py b/auth0/v3/management/hooks.py
new file mode 100644
index 0000000..0493b6c
--- /dev/null
+++ b/auth0/v3/management/hooks.py
@@ -0,0 +1,172 @@
+from .rest import RestClient
+
+
+class Hooks(object):
+
+    """Hooks endpoint implementation.
+
+    Args:
+        domain (str): Your Auth0 domain, e.g: 'username.auth0.com'
+
+        token (str): Management API v2 Token
+
+        telemetry (bool, optional): Enable or disable Telemetry
+            (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
+    """
+
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
+        self.domain = domain
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
+
+    def _url(self, id=None):
+        url = "https://{}/api/v2/hooks".format(self.domain)
+        if id is not None:
+            return "{}/{}".format(url, id)
+        return url
+
+    def all(
+        self,
+        enabled=True,
+        fields=None,
+        include_fields=True,
+        page=None,
+        per_page=None,
+        include_totals=False,
+    ):
+        """Retrieves a list of all hooks.
+
+        Args:
+            enabled (bool, optional): If provided, retrieves hooks that match
+                the value, otherwise all hooks are retrieved.
+
+            fields (list, optional): A list of fields to include or exclude
+                (depending on include_fields) from the result, empty to
+                retrieve all fields.
+
+            include_fields (bool, optional): True if the fields specified are
+                to be included in the result, False otherwise
+                (defaults to true).
+
+            page (int, optional): The result's page number (zero based).
+
+            per_page (int, optional): The amount of entries per page.
+
+            include_totals (bool, optional): True if the query summary is
+                to be included in the result, False otherwise.
+
+        See: https://auth0.com/docs/api/management/v2#!/Hooks/get_hooks
+        """
+
+        params = {
+            "fields": fields and ",".join(fields) or None,
+            "include_fields": str(include_fields).lower(),
+            "page": page,
+            "per_page": per_page,
+            "include_totals": str(include_totals).lower(),
+        }
+
+        # since the default is True, this is here to disable the filter
+        if enabled is not None:
+            params["enabled"] = str(enabled).lower()
+
+        return self.client.get(self._url(), params=params)
+
+    def create(self, body):
+        """Creates a new Hook.
+
+        Args:
+            body (dict): Attributes for the newly created hook,
+                See: https://auth0.com/docs/api/v2#!/Hooks/post_hooks
+        """
+        return self.client.post(self._url(), data=body)
+
+    def get(self, id, fields=None):
+        """Retrieves a hook by its ID.
+
+        Args:
+            id (str): The id of the hook to retrieve.
+
+            fields (list, optional): A list of fields to include or exclude
+                (depending on include_fields) from the result, empty to
+                retrieve all fields.
+
+        See: https://auth0.com/docs/api/management/v2#!/Hooks/get_hooks_by_id
+        """
+        params = {
+            "fields": fields and ",".join(fields) or None,
+        }
+        return self.client.get(self._url(id), params=params)
+
+    def delete(self, id):
+        """Deletes a hook.
+
+        Args:
+            id (str): The id of the hook to delete.
+
+        See: https://auth0.com/docs/api/management/v2#!/Hooks/delete_hooks_by_id
+        """
+        return self.client.delete(self._url(id))
+
+    def update(self, id, body):
+        """Updates an existing hook.
+
+        Args:
+            id (str): The id of the hook to modify.
+
+            body (dict): Attributes to modify.
+
+        See: https://auth0.com/docs/api/v2#!/Hooks/patch_hooks_by_id
+        """
+        return self.client.patch(self._url(id), data=body)
+
+    def get_secrets(self, id):
+        """Retrieves a hook's secrets.
+
+        Args:
+            id (str): The id of the hook to retrieve secrets from.
+
+        See: https://auth0.com/docs/api/management/v2#!/Hooks/get_secrets
+        """
+
+        return self.client.get(self._url("%s/secrets" % id))
+
+    def add_secrets(self, id, body):
+        """Add one or more secrets for an existing hook.
+
+        Args:
+            id (str): The id of the hook to add secrets to.
+
+            body (dict): Dict of key-value pairs where the value must be a string.
+
+        See: https://auth0.com/docs/api/management/v2#!/Hooks/post_secrets
+        """
+        return self.client.post(self._url("%s/secrets" % id), data=body)
+
+    def delete_secrets(self, id, body):
+        """Delete one or more existing secrets for an existing hook.
+
+        Args:
+            id (str): The id of the hook to add secrets to.
+
+            body (list): List of secret names to delete.
+
+        See: https://auth0.com/docs/api/management/v2#!/Hooks/delete_secrets
+        """
+        return self.client.delete(self._url("%s/secrets" % id), data=body)
+
+    def update_secrets(self, id, body):
+        """Update one or more existing secrets for an existing hook.
+
+        Args:
+            id (str): The id of the hook to add secrets to.
+
+            body (dict): Dict of key-value pairs where the value must be a string.
+
+        See: https://auth0.com/docs/api/management/v2#!/Hooks/patch_secrets
+        """
+        return self.client.patch(self._url("%s/secrets" % id), data=body)
diff --git a/auth0/v3/management/jobs.py b/auth0/v3/management/jobs.py
index aa7cde4..e629715 100644
--- a/auth0/v3/management/jobs.py
+++ b/auth0/v3/management/jobs.py
@@ -39,7 +39,7 @@ class Jobs(object):
         return self.client.get(self._url(id))
 
     def get_failed_job(self, id):
-        """Get failed job error details
+        """Get failed job error details.
 
         Args:
             id (str): The id of the job.
@@ -53,7 +53,7 @@ class Jobs(object):
         """Get results of a job
 
         Args:
-            job_id (str): The ID of the job.
+            job_id (str): The id of the job.
 
         See: https://auth0.com/docs/api/management/v2#!/Jobs/get_results
         """
@@ -67,7 +67,9 @@ class Jobs(object):
         included in the status once the job is complete.
 
         Args:
-            body (dict): Please see: https://auth0.com/docs/api/management/v2#!/Jobs/post_users_exports
+            body (dict): The details of the export users request.
+
+        See: https://auth0.com/docs/api/management/v2#!/Jobs/post_users_exports
         """
         return self.client.post(self._url('users-exports'), data=body)
 
@@ -79,18 +81,18 @@ class Jobs(object):
                 users will be inserted.
 
             file_obj (file): A file-like object to upload. The format for
-                this file is explained in: https://auth0.com/docs/bulk-import
+                this file is explained in: https://auth0.com/docs/bulk-import.
 
-            upsert (bool): When set to False, pre-existing users that match on email address, user ID, or username
+            upsert (bool, optional): When set to False, pre-existing users that match on email address, user ID, or username
                 will fail. When set to True, pre-existing users that match on any of these fields will be updated, but
                 only with upsertable attributes. Defaults to False.
                 For a list of user profile fields that can be upserted during import, see the following article
-                https://auth0.com/docs/users/references/user-profile-structure#user-profile-attributes
+                https://auth0.com/docs/users/references/user-profile-structure#user-profile-attributes.
 
-            send_completion_email (bool): When set to True, an email will be sent to notify the completion of this job.
+            send_completion_email (bool, optional): When set to True, an email will be sent to notify the completion of this job.
                 When set to False, no email will be sent. Defaults to True.
 
-            external_id (str):  Customer-defined ID.
+            external_id (str, optional):  Customer-defined ID.
 
         See: https://auth0.com/docs/api/management/v2#!/Jobs/post_users_imports
         """
@@ -108,6 +110,8 @@ class Jobs(object):
         verify their email address.
 
         Args:
-            body (dict): Please see: https://auth0.com/docs/api/v2#!/Jobs/post_verification_email
+            body (dict): Details of verification email request.
+
+        See: https://auth0.com/docs/api/v2#!/Jobs/post_verification_email
         """
         return self.client.post(self._url('verification-email'), data=body)
diff --git a/auth0/v3/management/logs.py b/auth0/v3/management/logs.py
index 854c4ac..afaf45a 100644
--- a/auth0/v3/management/logs.py
+++ b/auth0/v3/management/logs.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class Logs(object):
-
     """Auth0 logs endpoints
 
     Args:
@@ -35,32 +34,35 @@ class Logs(object):
         """Search log events.
 
         Args:
-            page (int, optional): The result's page number (zero based).
+            page (int, optional): The result's page number (zero based). By default,
+               retrieves the first page of results.
 
-            per_page (int, optional): The amount of entries per page.
+            per_page (int, optional): The amount of entries per page. By default,
+               retrieves 50 results per page.
 
             sort (str, optional): The field to use for sorting.
                 1 == ascending and -1 == descending. (e.g: date:1)
+                When not set, the default value is up to the server.
 
             q (str, optional): Query in Lucene query string syntax.
 
             fields (list of str, optional): A list of fields to include or
-                exclude from the result (depending on include_fields). Empty to
+                exclude from the result (depending on include_fields). Leave empty to
                 retrieve all fields.
 
             include_fields (bool, optional): True if the fields specified are
-                to be included in the result, False otherwise.
+                to be included in the result, False otherwise. Defaults to True.
 
             include_totals (bool, optional): True if the query summary is
-                to be included in the result, False otherwise.
+                to be included in the result, False otherwise. Defaults to True.
 
             from_param (str, optional): Log Event Id to start retrieving logs. You can
-                limit the amount of logs using the take parameter
+                limit the amount of logs using the take parameter.
 
             take (int, optional): The total amount of entries to retrieve when
-                using the from parameter.
+                using the from parameter. When not set, the default value is up to the server.
 
-        https://auth0.com/docs/api/management/v2#!/Logs/get_logs
+        See: https://auth0.com/docs/api/management/v2#!/Logs/get_logs
         """
         params = {
             'per_page': per_page,
@@ -79,8 +81,7 @@ class Logs(object):
         """Retrieves the data related to the log entry identified by id.
 
         Args:
-            id (str): The log_id of the log to retrieve
-
+            id (str): The log_id of the log to retrieve.
 
         See: https://auth0.com/docs/api/management/v2#!/Logs/get_logs_by_id
         """
diff --git a/auth0/v3/management/resource_servers.py b/auth0/v3/management/resource_servers.py
index 61115db..e4aeaee 100644
--- a/auth0/v3/management/resource_servers.py
+++ b/auth0/v3/management/resource_servers.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class ResourceServers(object):
-
     """Auth0 resource servers endpoints
 
     Args:
@@ -33,8 +32,9 @@ class ResourceServers(object):
         """Create a new resource server.
 
         Args:
-           body (dict): Attributes for the new resource Server
-              See: https://auth0.com/docs/api/management/v2#!/Resource_Servers/post_resource_servers
+           body (dict): Attributes for the new resource Server.
+
+        See: https://auth0.com/docs/api/management/v2#!/Resource_Servers/post_resource_servers
         """
 
         return self.client.post(self._url(), data=body)
@@ -43,12 +43,15 @@ class ResourceServers(object):
         """Retrieves all resource servers
 
         Args:
-            page (int, optional): The result's page number (zero based).
+            page (int, optional): The result's page number (zero based). When not set,
+              the default value is up to the server.
 
-            per_page (int, optional): The amount of entries per page.
+            per_page (int, optional): The amount of entries per page. When not set,
+              the default value is up to the server.
 
             include_totals (bool, optional): True if the query summary is
-                to be included in the result, False otherwise.
+                to be included in the result, False otherwise. Defaults to False.
+
 
         See: https://auth0.com/docs/api/management/v2#!/Resource_Servers/get_resource_servers
         """
@@ -65,7 +68,8 @@ class ResourceServers(object):
         """Retrieves a resource server by its id.
 
         Args:
-           id (str): Id of the resource server to get.
+           id (str): id of the resource server to get.
+
 
         See: https://auth0.com/docs/api/management/v2#!/Resource_Servers/get_resource_servers_by_id
         """
@@ -78,6 +82,7 @@ class ResourceServers(object):
         Args:
            id (str): Id of resource server to delete.
 
+
         See: https://auth0.com/docs/api/management/v2#!/Resource_Servers/delete_resource_servers_by_id
         """
 
@@ -90,7 +95,8 @@ class ResourceServers(object):
            id (str): The id of the resource server to update.
 
            body (dict): Attributes to modify.
-              See: https://auth0.com/docs/api/management/v2#!/Resource_Servers/patch_resource_servers_by_id
+
+        See: https://auth0.com/docs/api/management/v2#!/Resource_Servers/patch_resource_servers_by_id
         """
 
         return self.client.patch(self._url(id), data=body)
diff --git a/auth0/v3/management/roles.py b/auth0/v3/management/roles.py
index 31c004e..9cbdcd7 100644
--- a/auth0/v3/management/roles.py
+++ b/auth0/v3/management/roles.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class Roles(object):
-
     """Auth0 roles endpoints
 
     Args:
@@ -33,15 +32,17 @@ class Roles(object):
         """List or search roles.
 
         Args:
-            page (int, optional): The result's page number (zero based).
+            page (int, optional): The result's page number (zero based). By default,
+               retrieves the first page of results.
 
-            per_page (int, optional): The amount of entries per page.
+            per_page (int, optional): The amount of entries per page. By default,
+               retrieves 25 results per page.
 
             include_totals (bool, optional): True if the query summary is
-                to be included in the result, False otherwise.
+                to be included in the result, False otherwise. Defaults to True.
 
             name_filter (str, optional): A case-insensitive filter to apply
-                to search for roles by name            
+                to search for roles by name.
 
         See: https://auth0.com/docs/api/management/v2#!/Roles/get_roles
         """
@@ -57,7 +58,9 @@ class Roles(object):
         """Creates a new role.
 
         Args:
-            body (dict): Please see: https://auth0.com/docs/api/v2#!/Roles/post_roles
+            body (dict): the attributes for the role to create.
+
+        See: https://auth0.com/docs/api/v2#!/Roles/post_roles
         """
         return self.client.post(self._url(), data=body)
 
@@ -88,7 +91,9 @@ class Roles(object):
         Args:
             id (str): The id of the role to update.
 
-            body (dict): Please see: https://auth0.com/docs/api/management/v2#!/Roles/patch_roles_by_id
+            body (dict): the attributes to update on the role.
+
+        See: https://auth0.com/docs/api/management/v2#!/Roles/patch_roles_by_id
         """
         return self.client.patch(self._url(id), data=body)
 
@@ -98,12 +103,14 @@ class Roles(object):
         Args:
             id (str): The role's id.
 
-            page (int, optional): The result's page number (zero based). 
-  
-            per_page (int, optional): The amount of entries per page. 
+            page (int, optional): The result's page number (zero based). By default,
+               retrieves the first page of results.
+
+            per_page (int, optional): The amount of entries per page. By default,
+               retrieves 25 results per page.
 
             include_totals (bool, optional): True if the query summary is
-                to be included in the result, False otherwise.
+                to be included in the result, False otherwise. Defaults to True.
 
         See https://auth0.com/docs/api/management/v2#!/Roles/get_role_user
         """
@@ -122,7 +129,7 @@ class Roles(object):
         Args:
             id (str): The role's id.
 
-            users (list of str): A list of users ids to add to this role
+            users (list of str): A list of users ids to add to this role.
 
         See https://auth0.com/docs/api/management/v2#!/Roles/post_role_users
         """
@@ -136,12 +143,14 @@ class Roles(object):
         Args:
             id (str): The role's id.
 
-            page (int, optional): The result's page number (zero based). 
-  
-            per_page (int, optional): The amount of entries per page. 
+            page (int, optional): The result's page number (zero based). By default,
+               retrieves the first page of results.
+
+            per_page (int, optional): The amount of entries per page. By default,
+               retrieves 25 results per page.
 
             include_totals (bool, optional): True if the query summary is
-                to be included in the result, False otherwise.
+                to be included in the result, False otherwise. Defaults to True.
 
         See https://auth0.com/docs/api/management/v2#!/Roles/get_role_permission
         """
@@ -167,7 +176,6 @@ class Roles(object):
         body = {'permissions': permissions}
         return self.client.delete(url, data=body)
 
-
     def add_permissions(self, id, permissions):
         """Associates permissions with a role.
 
@@ -180,4 +188,4 @@ class Roles(object):
         """
         url = self._url('{}/permissions'.format(id))
         body = {'permissions': permissions}
-        return self.client.post(url, data=body)
\ No newline at end of file
+        return self.client.post(url, data=body)
diff --git a/auth0/v3/management/rules.py b/auth0/v3/management/rules.py
index 1017362..73d4fa2 100644
--- a/auth0/v3/management/rules.py
+++ b/auth0/v3/management/rules.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class Rules(object):
-
     """Rules endpoint implementation.
 
     Args:
@@ -34,26 +33,27 @@ class Rules(object):
         """Retrieves a list of all rules.
 
         Args:
-            stage (str, optional):  Retrieves rules that match the execution
-                stage (defaults to login_success).
+            stage (str, optional):  Retrieves rules that match the execution stage.
+                Defaults to login_success.
 
             enabled (bool, optional): If provided, retrieves rules that match
                 the value, otherwise all rules are retrieved.
 
             fields (list, optional): A list of fields to include or exclude
-                (depending on include_fields) from the result, empty to
+                (depending on include_fields) from the result. Leave empty to
                 retrieve all fields.
 
             include_fields (bool, optional): True if the fields specified are
-                to be included in the result, False otherwise
-                (defaults to true).
+                to be included in the result, False otherwise. Defaults to True.
 
-            page (int, optional): The result's page number (zero based).
+            page (int, optional): The result's page number (zero based). When not set,
+                the default value is up to the server.
 
-            per_page (int, optional): The amount of entries per page.
+            per_page (int, optional): The amount of entries per page. When not set,
+                the default value is up to the server.
 
             include_totals (bool, optional): True if the query summary is
-                to be included in the result, False otherwise.
+                to be included in the result, False otherwise. Defaults to False.
 
         See: https://auth0.com/docs/api/management/v2#!/Rules/get_rules
         """
@@ -77,8 +77,9 @@ class Rules(object):
         """Creates a new rule.
 
         Args:
-            body (dict): Attributes for the newly created rule,
-                See: https://auth0.com/docs/api/v2#!/Rules/post_rules
+            body (dict): Attributes for the newly created rule.
+
+        See: https://auth0.com/docs/api/v2#!/Rules/post_rules
         """
         return self.client.post(self._url(), data=body)
 
@@ -89,12 +90,11 @@ class Rules(object):
             id (str): The id of the rule to retrieve.
 
             fields (list, optional): A list of fields to include or exclude
-                (depending on include_fields) from the result, empty to
+                (depending on include_fields) from the result. Leave empty to
                 retrieve all fields.
 
             include_fields (bool, optional): True if the fields specified are
-                to be included in the result, False otherwise
-                (defaults to true).
+                to be included in the result, False otherwise. Defaults to True.
 
         See: https://auth0.com/docs/api/management/v2#!/Rules/get_rules_by_id
         """
@@ -119,6 +119,7 @@ class Rules(object):
             id (str): The id of the rule to modify.
 
             body (dict): Attributes to modify.
-                See: https://auth0.com/docs/api/v2#!/Rules/patch_rules_by_id
+
+        See: https://auth0.com/docs/api/v2#!/Rules/patch_rules_by_id
         """
         return self.client.patch(self._url(id), data=body)
diff --git a/auth0/v3/management/rules_configs.py b/auth0/v3/management/rules_configs.py
index b29cebe..f4c97b3 100644
--- a/auth0/v3/management/rules_configs.py
+++ b/auth0/v3/management/rules_configs.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class RulesConfigs(object):
-
     """RulesConfig endpoint implementation.
 
     Args:
@@ -40,7 +39,7 @@ class RulesConfigs(object):
         """Removes the rules config for a given key.
 
         Args:
-            key (str): rules config key to remove
+            key (str): rules config key to remove.
 
         See: https://auth0.com/docs/api/management/v2#!/Rules_Configs/delete_rules_configs_by_key
         """
@@ -50,13 +49,12 @@ class RulesConfigs(object):
         """Sets the rules config for a given key.
 
         Args:
-            key (str): rules config key to set
+            key (str): rules config key to set.
 
-            value (str): value to set for the rules config key
+            value (str): value to set for the rules config key.
 
         See: https://auth0.com/docs/api/management/v2#!/Rules_Configs/put_rules_configs_by_key
         """
         url = self._url('{}'.format(key))
         body = {'value': value}
         return self.client.put(url, data=body)
-
diff --git a/auth0/v3/management/stats.py b/auth0/v3/management/stats.py
index 8c34ad5..cb93398 100644
--- a/auth0/v3/management/stats.py
+++ b/auth0/v3/management/stats.py
@@ -30,7 +30,6 @@ class Stats(object):
 
         Returns: An integer.
 
-
         See: https://auth0.com/docs/api/management/v2#!/Stats/get_active_users
         """
 
@@ -40,10 +39,10 @@ class Stats(object):
         """Gets the daily stats for a particular period.
 
         Args:
-           from_date (str): The first day of the period (inclusive) in
+           from_date (str, optional): The first day of the period (inclusive) in
               YYYYMMDD format.
 
-           to_date (str): The last day of the period (inclusive) in
+           to_date (str, optional): The last day of the period (inclusive) in
               YYYYMMDD format.
 
         See: https://auth0.com/docs/api/management/v2#!/Stats/get_daily
diff --git a/auth0/v3/management/tenants.py b/auth0/v3/management/tenants.py
index 8b6ba72..76fba30 100644
--- a/auth0/v3/management/tenants.py
+++ b/auth0/v3/management/tenants.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class Tenants(object):
-
     """Auth0 tenants endpoints
 
     Args:
@@ -31,13 +30,13 @@ class Tenants(object):
 
         Args:
            fields (list of str, optional): A list of fields to include or
-              exclude from the result (depending on include_fields). Empty to
+              exclude from the result (depending on include_fields). Leave empty to
               retrieve all fields.
 
            include_fields (bool, optional): True if the fields specified are
-              to be included in the result, False otherwise.
+              to be included in the result, False otherwise. Defaults to True.
               
-           See: https://auth0.com/docs/api/management/v2#!/Tenants/get_settings
+        See: https://auth0.com/docs/api/management/v2#!/Tenants/get_settings
         """
 
         params = {'fields': fields and ','.join(fields) or None,
@@ -49,6 +48,8 @@ class Tenants(object):
         """Update tenant settings.
 
         Args:
-            body (dict): Please see: https://auth0.com/docs/api/v2#!/Tenants/patch_settings
+            body (dict): the attributes to update in the tenant.
+
+        See: https://auth0.com/docs/api/v2#!/Tenants/patch_settings
         """
         return self.client.patch(self._url(), data=body)
diff --git a/auth0/v3/management/tickets.py b/auth0/v3/management/tickets.py
index 7667787..985d1b4 100644
--- a/auth0/v3/management/tickets.py
+++ b/auth0/v3/management/tickets.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class Tickets(object):
-
     """Auth0 tickets endpoints
 
     Args:
@@ -30,7 +29,9 @@ class Tickets(object):
         """Create an email verification ticket.
 
         Args:
-            body (dict): Please see: https://auth0.com/docs/api/v2#!/Tickets/post_email_verification
+            body (dict): attributes to set on the email verification request.
+
+        See: https://auth0.com/docs/api/v2#!/Tickets/post_email_verification
         """
         return self.client.post(self._url('email-verification'), data=body)
 
@@ -38,6 +39,8 @@ class Tickets(object):
         """Create password change ticket.
 
         Args:
-            body (dict): Please see: https://auth0.com/docs/api/v2#!/Tickets/post_password_change
+            body (dict): attributes to set on the password change request.
+
+        See: https://auth0.com/docs/api/v2#!/Tickets/post_password_change
         """
         return self.client.post(self._url('password-change'), data=body)
diff --git a/auth0/v3/management/user_blocks.py b/auth0/v3/management/user_blocks.py
index e7670a3..1c36f87 100644
--- a/auth0/v3/management/user_blocks.py
+++ b/auth0/v3/management/user_blocks.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class UserBlocks(object):
-
     """Auth0 user blocks endpoints
 
     Args:
diff --git a/auth0/v3/management/users.py b/auth0/v3/management/users.py
index 6353970..d90c5a4 100644
--- a/auth0/v3/management/users.py
+++ b/auth0/v3/management/users.py
@@ -1,9 +1,9 @@
-from .rest import RestClient
 import warnings
 
+from .rest import RestClient
 
-class Users(object):
 
+class Users(object):
     """Auth0 users endpoints
 
     Args:
@@ -36,12 +36,15 @@ class Users(object):
         """List or search users.
 
         Args:
-            page (int, optional): The result's page number (zero based).
+            page (int, optional): The result's page number (zero based). By default,
+               retrieves the first page of results.
 
-            per_page (int, optional): The amount of entries per page.
+            per_page (int, optional): The amount of entries per page. By default,
+               retrieves 25 results per page.
 
             sort (str, optional): The field to use for sorting.
                 1 == ascending and -1 == descending. (e.g: email:1)
+                When not set, the default value is up to the server.
 
             connection (str, optional): Connection filter.
 
@@ -51,17 +54,17 @@ class Users(object):
 
             search_engine (str, optional): The version of the search_engine to use
                 when querying for users. Will default to the latest version available.
-                See: https://auth0.com/docs/users/search
+                See: https://auth0.com/docs/users/search.
 
             include_totals (bool, optional): True if the query summary is
-                to be included in the result, False otherwise.
+                to be included in the result, False otherwise. Defaults to True.
 
             fields (list of str, optional): A list of fields to include or
-                exclude from the result (depending on include_fields). Empty to
+                exclude from the result (depending on include_fields). Leave empty to
                 retrieve all fields.
 
             include_fields (bool, optional): True if the fields specified are
-                to be include in the result, False otherwise.
+                to be include in the result, False otherwise. Defaults to True.
 
         See: https://auth0.com/docs/api/management/v2#!/Users/get_users
         """
@@ -82,7 +85,9 @@ class Users(object):
         """Creates a new user.
 
         Args:
-            body (dict): Please see: https://auth0.com/docs/api/v2#!/Users/post_users
+            body (dict): the attributes to set on the user to create.
+
+        See: https://auth0.com/docs/api/v2#!/Users/post_users
         """
         return self.client.post(self._url(), data=body)
 
@@ -102,11 +107,11 @@ class Users(object):
             id (str): The user_id of the user to retrieve.
 
             fields (list of str, optional): A list of fields to include or
-                exclude from the result (depending on include_fields). Empty to
+                exclude from the result (depending on include_fields). Leave empty to
                 retrieve all fields.
 
             include_fields (bool, optional): True if the fields specified are
-                to be included in the result, False otherwise.
+                to be included in the result, False otherwise. Defaults to True.
 
         See: https://auth0.com/docs/api/management/v2#!/Users/get_users_by_id
         """
@@ -133,7 +138,9 @@ class Users(object):
         Args:
             id (str): The user_id of the user to update.
 
-            body (dict): Please see: https://auth0.com/docs/api/v2#!/Users/patch_users_by_id
+            body (dict): The attributes of the user to update.
+
+        See: https://auth0.com/docs/api/v2#!/Users/patch_users_by_id
         """
         return self.client.patch(self._url(id), data=body)
 
@@ -143,12 +150,14 @@ class Users(object):
         Args:
             id (str): The user's id.
 
-            page (int, optional): The result's page number (zero based). 
-  
-            per_page (int, optional): The amount of entries per page. 
+            page (int, optional): The result's page number (zero based). By default,
+               retrieves the first page of results.
+
+            per_page (int, optional): The amount of entries per page. By default,
+               retrieves 25 results per page.
 
             include_totals (bool, optional): True if the query summary is
-                to be included in the result, False otherwise.
+               to be included in the result, False otherwise. Defaults to True.
 
         See https://auth0.com/docs/api/management/v2#!/Users/get_user_roles
         """
@@ -195,12 +204,14 @@ class Users(object):
         Args:
             id (str): The user's id.
 
-            page (int, optional): The result's page number (zero based). 
-  
-            per_page (int, optional): The amount of entries per page. 
+            page (int, optional): The result's page number (zero based). By default,
+               retrieves the first page of results.
+
+            per_page (int, optional): The amount of entries per page. By default,
+               retrieves 25 results per page.
 
             include_totals (bool, optional): True if the query summary is
-                to be included in the result, False otherwise.
+                to be included in the result, False otherwise. Defaults to True.
 
         See https://auth0.com/docs/api/management/v2#!/Users/get_permissions
         """
@@ -248,7 +259,7 @@ class Users(object):
             id (str): The user's id.
 
             provider (str): The multifactor provider. Supported values 'duo'
-                or 'google-authenticator'
+                or 'google-authenticator'.
 
         See: https://auth0.com/docs/api/management/v2#!/Users/delete_multifactor_by_provider
         """
@@ -280,7 +291,9 @@ class Users(object):
             id (str): The user_id of the primary identity where you are linking
                 the secondary account to.
 
-            body (dict): Please see: https://auth0.com/docs/api/v2#!/Users/post_identities
+            body (dict): the attributes to send as part of this request.
+
+        See: https://auth0.com/docs/api/v2#!/Users/post_identities
         """
         url = self._url('{}/identities'.format(user_id))
         return self.client.post(url, data=body)
@@ -300,7 +313,7 @@ class Users(object):
         """Retrieves all Guardian enrollments.
 
         Args:
-            user_id (str):  The user_id of the user to retrieve
+            user_id (str):  The user_id of the user to retrieve.
 
         See: https://auth0.com/docs/api/management/v2#!/Users/get_enrollments
         """
@@ -309,24 +322,26 @@ class Users(object):
 
     def get_log_events(self, user_id, page=0, per_page=50, sort=None,
                        include_totals=False):
-        """Retrieve every log event for a specific user id
+        """Retrieve every log event for a specific user id.
 
         Args:
-            user_id (str):  The user_id of the logs to retrieve
+            user_id (str):  The user_id of the logs to retrieve.
 
-            page (int, optional): The result's page number (zero based).
+            page (int, optional): The result's page number (zero based). By default,
+                retrieves the first page of results.
 
-            per_page (int, optional): The amount of entries per page.
-                Default: 50. Max value: 100
+            per_page (int, optional): The amount of entries per page. By default,
+                retrieves 50 results per page.
 
             sort (str, optional):  The field to use for sorting. Use field:order
                 where order is 1 for ascending and -1 for descending.
                 For example date:-1
+                When not set, the default value is up to the server.
 
             include_totals (bool, optional): True if the query summary is
-                to be included in the result, False otherwise.
+                to be included in the result, False otherwise. Defaults to False.
 
-            See: https://auth0.com/docs/api/management/v2#!/Users/get_logs_by_user
+        See: https://auth0.com/docs/api/management/v2#!/Users/get_logs_by_user
         """
 
         params = {
diff --git a/auth0/v3/management/users_by_email.py b/auth0/v3/management/users_by_email.py
index 295ea0b..edb2f37 100644
--- a/auth0/v3/management/users_by_email.py
+++ b/auth0/v3/management/users_by_email.py
@@ -2,7 +2,6 @@ from .rest import RestClient
 
 
 class UsersByEmail(object):
-
     """Auth0 users by email endpoints
 
     Args:
@@ -32,10 +31,10 @@ class UsersByEmail(object):
 
         Args:
 
-            email: Email to search
+            email: Email to search.
 
             fields (list of str, optional): A list of fields to include or
-                exclude from the result (depending on include_fields). Empty to
+                exclude from the result (depending on include_fields). Leave empty to
                 retrieve all fields.
 
             include_fields (bool, optional): True if the fields specified are


Test patch:
diff --git a/auth0/v3/test/authentication/test_database.py b/auth0/v3/test/authentication/test_database.py
index 0291f2f..d614fd1 100644
--- a/auth0/v3/test/authentication/test_database.py
+++ b/auth0/v3/test/authentication/test_database.py
@@ -1,5 +1,7 @@
 import unittest
+
 import mock
+
 from ...authentication.database import Database
 
 
@@ -7,7 +9,6 @@ class TestDatabase(unittest.TestCase):
 
     @mock.patch('auth0.v3.authentication.database.Database.post')
     def test_login(self, mock_post):
-
         d = Database('my.domain.com')
 
         d.login(client_id='cid',
@@ -35,7 +36,6 @@ class TestDatabase(unittest.TestCase):
 
     @mock.patch('auth0.v3.authentication.database.Database.post')
     def test_signup(self, mock_post):
-
         d = Database('my.domain.com')
 
         # using only email and password
@@ -48,16 +48,13 @@ class TestDatabase(unittest.TestCase):
 
         self.assertEqual(args[0], 'https://my.domain.com/dbconnections/signup')
         self.assertEqual(kwargs['data'], {
-                         'client_id': 'cid',
-                         'email': 'a@b.com',
-                         'password': 'pswd',
-                         'connection': 'conn',
-                         'username': None,
-                         'user_metadata': None
-                        })
-
+            'client_id': 'cid',
+            'email': 'a@b.com',
+            'password': 'pswd',
+            'connection': 'conn',
+        })
 
-        # Using also username and metadata
+        # Using also optional properties
         sample_meta = {
             'hobby': 'surfing',
             'preference': {
@@ -69,25 +66,35 @@ class TestDatabase(unittest.TestCase):
                  password='pswd',
                  connection='conn',
                  username='usr',
-                 user_metadata=sample_meta)
+                 user_metadata=sample_meta,
+                 given_name='john',
+                 family_name='doe',
+                 name='john doe',
+                 nickname='johnny',
+                 picture='avatars.com/john-doe')
 
         args, kwargs = mock_post.call_args
 
         self.assertEqual(args[0], 'https://my.domain.com/dbconnections/signup')
         self.assertEqual(kwargs['data'], {
-                         'client_id': 'cid',
-                         'email': 'a@b.com',
-                         'password': 'pswd',
-                         'connection': 'conn',
-                         'username': 'usr',
-                         'user_metadata': sample_meta
-                        })
+            'client_id': 'cid',
+            'email': 'a@b.com',
+            'password': 'pswd',
+            'connection': 'conn',
+            'username': 'usr',
+            'user_metadata': sample_meta,
+            'given_name': 'john',
+            'family_name': 'doe',
+            'name': 'john doe',
+            'nickname': 'johnny',
+            'picture': 'avatars.com/john-doe',
+        })
 
     @mock.patch('auth0.v3.authentication.database.Database.post')
     def test_change_password(self, mock_post):
-
         d = Database('my.domain.com')
 
+        # ignores the password argument
         d.change_password(client_id='cid',
                           email='a@b.com',
                           password='pswd',
@@ -100,6 +107,5 @@ class TestDatabase(unittest.TestCase):
         self.assertEqual(kwargs['data'], {
             'client_id': 'cid',
             'email': 'a@b.com',
-            'password': 'pswd',
             'connection': 'conn',
         })
diff --git a/auth0/v3/test/authentication/test_revoke_token.py b/auth0/v3/test/authentication/test_revoke_token.py
index 0aa40fd..57a1d21 100644
--- a/auth0/v3/test/authentication/test_revoke_token.py
+++ b/auth0/v3/test/authentication/test_revoke_token.py
@@ -11,16 +11,14 @@ class TestRevokeToken(unittest.TestCase):
         a = RevokeToken('my.domain.com')
 
         # regular apps
-        a.revoke_refresh_token(client_id='cid',
-                    token='tkn')
+        a.revoke_refresh_token(client_id='cid', token='tkn')
 
         args, kwargs = mock_post.call_args
 
         self.assertEqual(args[0], 'https://my.domain.com/oauth/revoke')
         self.assertEqual(kwargs['data'], {
             'client_id': 'cid',
-            'token': 'tkn',
-            'client_secret': None
+            'token': 'tkn'
         })
 
         # confidential apps
diff --git a/auth0/v3/test/management/test_auth0.py b/auth0/v3/test/management/test_auth0.py
index 51e2f8d..a3fa8b5 100644
--- a/auth0/v3/test/management/test_auth0.py
+++ b/auth0/v3/test/management/test_auth0.py
@@ -10,6 +10,7 @@ from ...management.emails import Emails
 from ...management.email_templates import EmailTemplates
 from ...management.grants import Grants
 from ...management.guardian import Guardian
+from ...management.hooks import Hooks
 from ...management.jobs import Jobs
 from ...management.logs import Logs
 from ...management.resource_servers import ResourceServers
@@ -61,6 +62,9 @@ class TestAuth0(unittest.TestCase):
     def test_guardian(self):
         self.assertIsInstance(self.a0.guardian, Guardian)
 
+    def test_hooks(self):
+        self.assertIsInstance(self.a0.hooks, Hooks)
+
     def test_jobs(self):
         self.assertIsInstance(self.a0.jobs, Jobs)
 
diff --git a/auth0/v3/test/management/test_blacklists.py b/auth0/v3/test/management/test_blacklists.py
index cbf74e9..7c62e57 100644
--- a/auth0/v3/test/management/test_blacklists.py
+++ b/auth0/v3/test/management/test_blacklists.py
@@ -28,6 +28,16 @@ class TestBlacklists(unittest.TestCase):
         mock_instance = mock_rc.return_value
 
         t = Blacklists(domain='domain', token='jwttoken')
+
+        # create without audience
+        t.create(jti='the-jti')
+
+        args, kwargs = mock_instance.post.call_args
+
+        self.assertEqual('https://domain/api/v2/blacklists/tokens', args[0])
+        self.assertEqual(kwargs['data'], {'jti': 'the-jti'})
+
+        # create with audience
         t.create(jti='the-jti', aud='the-aud')
 
         args, kwargs = mock_instance.post.call_args
diff --git a/auth0/v3/test/management/test_hooks.py b/auth0/v3/test/management/test_hooks.py
new file mode 100644
index 0000000..5376b1c
--- /dev/null
+++ b/auth0/v3/test/management/test_hooks.py
@@ -0,0 +1,163 @@
+import unittest
+import mock
+from ...management.hooks import Hooks
+
+
+class TestRules(unittest.TestCase):
+
+    def test_init_with_optionals(self):
+        t = Hooks(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
+    @mock.patch('auth0.v3.management.hooks.RestClient')
+    def test_all(self, mock_rc):
+        mock_instance = mock_rc.return_value
+
+        c = Hooks(domain='domain', token='jwttoken')
+
+        # with default params
+        c.all()
+
+        args, kwargs = mock_instance.get.call_args
+
+        self.assertEqual('https://domain/api/v2/hooks', args[0])
+        self.assertEqual(kwargs['params'], {
+            "enabled": 'true',
+            "fields": None,
+            "include_fields": 'true',
+            "page": None,
+            "per_page": None,
+            "include_totals": 'false',
+        })
+
+        # with fields params
+        c.all(enabled=False, fields=['a', 'b'],
+              include_fields=False)
+
+        args, kwargs = mock_instance.get.call_args
+
+        self.assertEqual('https://domain/api/v2/hooks', args[0])
+        self.assertEqual(kwargs['params'], {'fields': 'a,b',
+                                            'include_fields': 'false',
+                                            'enabled': 'false',
+                                            'page': None,
+                                            'per_page': None,
+                                            'include_totals': 'false'})
+
+        # with pagination params
+        c.all(page=3, per_page=27, include_totals=True)
+
+        args, kwargs = mock_instance.get.call_args
+
+        self.assertEqual('https://domain/api/v2/hooks', args[0])
+        self.assertEqual(kwargs['params'], {'fields': None,
+                                            'include_fields': 'true',
+                                            'enabled': 'true',
+                                            'page': 3,
+                                            'per_page': 27,
+                                            'include_totals': 'true'})
+
+    @mock.patch('auth0.v3.management.hooks.RestClient')
+    def test_create(self, mock_rc):
+        mock_instance = mock_rc.return_value
+
+        c = Hooks(domain='domain', token='jwttoken')
+        c.create({'a': 'b', 'c': 'd'})
+
+        args, kwargs = mock_instance.post.call_args
+
+        self.assertEqual('https://domain/api/v2/hooks', args[0])
+        self.assertEqual(kwargs['data'], {'a': 'b', 'c': 'd'})
+
+    @mock.patch('auth0.v3.management.hooks.RestClient')
+    def test_get(self, mock_rc):
+        mock_instance = mock_rc.return_value
+
+        c = Hooks(domain='domain', token='jwttoken')
+        c.get('an-id')
+
+        args, kwargs = mock_instance.get.call_args
+
+        self.assertEqual('https://domain/api/v2/hooks/an-id', args[0])
+        self.assertEqual(kwargs['params'], {'fields': None})
+
+        c.get('an-id', fields=['a', 'b'])
+
+        args, kwargs = mock_instance.get.call_args
+
+        self.assertEqual('https://domain/api/v2/hooks/an-id', args[0])
+        self.assertEqual(kwargs['params'], {'fields': 'a,b'})
+
+    @mock.patch('auth0.v3.management.hooks.RestClient')
+    def test_delete(self, mock_rc):
+        mock_instance = mock_rc.return_value
+
+        c = Hooks(domain='domain', token='jwttoken')
+        c.delete('an-id')
+
+        mock_instance.delete.assert_called_with(
+            'https://domain/api/v2/hooks/an-id'
+        )
+
+    @mock.patch('auth0.v3.management.hooks.RestClient')
+    def test_update(self, mock_rc):
+        mock_instance = mock_rc.return_value
+
+        c = Hooks(domain='domain', token='jwttoken')
+        c.update('an-id', {'a': 'b', 'c': 'd'})
+
+        args, kwargs = mock_instance.patch.call_args
+
+        self.assertEqual('https://domain/api/v2/hooks/an-id', args[0])
+        self.assertEqual(kwargs['data'], {'a': 'b', 'c': 'd'})
+
+    # test for hooks secrets
+    @mock.patch('auth0.v3.management.hooks.RestClient')
+    def test_add_secret(self, mock_rc):
+        mock_instance = mock_rc.return_value
+
+        c = Hooks(domain='domain', token='jwttoken')
+        c.add_secrets('an-id', {'a': 'b', 'c': 'd'})
+
+        args, kwargs = mock_instance.post.call_args
+
+        self.assertEqual('https://domain/api/v2/hooks/an-id/secrets', args[0])
+        self.assertEqual(kwargs['data'], {'a': 'b', 'c': 'd'})
+
+    @mock.patch('auth0.v3.management.hooks.RestClient')
+    def test_get_secrets(self, mock_rc):
+        mock_instance = mock_rc.return_value
+
+        c = Hooks(domain='domain', token='jwttoken')
+        c.get_secrets('an-id')
+
+        args, kwargs = mock_instance.get.call_args
+
+        self.assertEqual('https://domain/api/v2/hooks/an-id/secrets', args[0])
+        self.assertNotIn("params", kwargs)
+
+    @mock.patch('auth0.v3.management.hooks.RestClient')
+    def test_delete_secrets(self, mock_rc):
+        mock_instance = mock_rc.return_value
+
+        c = Hooks(domain='domain', token='jwttoken')
+        c.delete_secrets('an-id', ['a', 'b'])
+
+        args, kwargs = mock_instance.delete.call_args
+
+        self.assertEqual('https://domain/api/v2/hooks/an-id/secrets', args[0])
+        self.assertEqual(kwargs['data'], ['a', 'b'])
+
+    @mock.patch('auth0.v3.management.hooks.RestClient')
+    def test_update_secrets(self, mock_rc):
+        mock_instance = mock_rc.return_value
+
+        c = Hooks(domain='domain', token='jwttoken')
+        c.update_secrets('an-id', {'a': 'b', 'c': 'd'})
+
+        args, kwargs = mock_instance.patch.call_args
+
+        self.assertEqual('https://domain/api/v2/hooks/an-id/secrets', args[0])
+        self.assertEqual(kwargs['data'], {'a': 'b', 'c': 'd'})