Repository: davidteather/TikTok-Api (language: python)

Issue:
[BUG] - Discover Methods Broken
Currently all of the discover methods are broken. It's getting hit consistently with captchas one of my theories about this is that the mobile web app version of TikTok doesn't display trending, but the package feigns a mobile user agent. If someone could investigate this further or make a PR that fixes this that would be helpful

Methods affected
* discover_hashtags
* discover_music
* get_suggested_users_by_id/_crawler
* get_suggested_hashtags_by_id/_crawler
* get_suggested_users_by_id/_crawler
Update README.md



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/create-docs.yml b/.github/workflows/create-docs.yml
new file mode 100644
index 00000000..2ceb09dd
--- /dev/null
+++ b/.github/workflows/create-docs.yml
@@ -0,0 +1,32 @@
+name: Generate Docs
+on:
+  push:
+    branches:
+      - master
+  pull_request:
+    branches:
+      - master
+      - nightly
+      - 'releases/*'
+
+jobs:
+  doc-create:
+    timeout-minutes: 30
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Setup dependencies
+        run: |
+          pip install -r requirements.txt
+          pip install pdoc3
+      - name: Generate Docs
+        run: |
+          pdoc --html --force -o ./docs TikTokApi
+          mv docs/TikTokApi/* docs/
+          rm -r docs/TikTokApi
+      - name: Push
+        run: |
+          git config --global user.name 'David Teather'
+          git config --global user.email 'davidteather@users.noreply.github.com'
+          git commit -am "Automated Doc Generation"
+          git push
\ No newline at end of file
diff --git a/README.md b/README.md
index f6964521..cf982996 100644
--- a/README.md
+++ b/README.md
@@ -25,11 +25,16 @@ This is an unofficial api wrapper for TikTok.com in python. With this api you ar
 
 To get started using this api follow the instructions below.
 
+#### How to support the project
+* Feel free to sponsor me on GitHub
+* Feel free to tip the project using the brave browser
+* Submit PRs for issues :)
+
 ### Installing
 
 If you run into an issue please check the closed issues on the github. You're most likely not the first person to experience this issue. If nothing works feel free to open an issue.
 
-```
+```sh
 pip install TikTokApi
 python -m playwright install
 ```
@@ -43,7 +48,7 @@ If you're on MacOS you may need to install [XCode Developer Tools](https://webki
 
 Clone this repository onto a local machine then run the following commands.
 
-```
+```sh
 docker build . -t tiktokapi:latest
 docker run -v TikTokApi --rm tiktokapi:latest python3 your_script.py
 ```
@@ -62,7 +67,7 @@ Please don't open an issue if you're experiencing one of these just comment if t
 
 Here's a quick bit of code to get the most recent trending on TikTok. There's more examples in the examples directory.
 
-```
+```py
 from TikTokApi import TikTokApi
 api = TikTokApi.get_instance()
 # If playwright doesn't work for you try to use selenium
@@ -84,7 +89,7 @@ print(len(trending))
 To run the example scripts from the repository root, make sure you use the
 module form of python the interpreter
 
-```
+```sh
 python -m examples.getTrending
 ```
 
diff --git a/TikTokApi/__init__.py b/TikTokApi/__init__.py
index fcc48fdb..50c49d35 100644
--- a/TikTokApi/__init__.py
+++ b/TikTokApi/__init__.py
@@ -1,2 +1,2 @@
 from TikTokApi.tiktok import TikTokApi
-from TikTokApi.tiktokuser import TikTokUser
\ No newline at end of file
+from TikTokApi.tiktokuser import TikTokUser
diff --git a/TikTokApi/tiktok.py b/TikTokApi/tiktok.py
index 9cbf83d2..8f13d27c 100644
--- a/TikTokApi/tiktok.py
+++ b/TikTokApi/tiktok.py
@@ -42,6 +42,7 @@ def __init__(self, **kwargs):
         self.custom_verifyFp = kwargs.get("custom_verifyFp")
         self.signer_url = kwargs.get("external_signer", None)
         self.request_delay = kwargs.get("request_delay", None)
+        self.requests_extra_kwargs = kwargs.get("requests_extra_kwargs", {})
 
         if kwargs.get("use_test_endpoints", False):
             global BASE_URL
@@ -184,7 +185,7 @@ def external_signer(self, url, custom_did=None, verifyFp=None):
             query = {"url": url, "custom_did": custom_did, "verifyFp": verifyFp}
         else:
             query = {"url": url, "verifyFp": verifyFp}
-        data = requests.get(self.signer_url + "?{}".format(urlencode(query)))
+        data = requests.get(self.signer_url + "?{}".format(urlencode(query)), **self.requests_extra_kwargs)
         parsed_data = data.json()
 
         return (
@@ -259,10 +260,14 @@ def get_data(self, **kwargs) -> dict:
             },
             cookies=self.get_cookies(**kwargs),
             proxies=self.__format_proxy(proxy),
+            **self.requests_extra_kwargs,
         )
         try:
             json = r.json()
-            if json.get("type") == "verify":
+            if (
+                json.get("type") == "verify"
+                or json.get("verifyConfig", {}).get("type", "") == "verify"
+            ):
                 logging.error(
                     "Tiktok wants to display a catcha. Response is:\n" + r.text
                 )
@@ -401,7 +406,7 @@ def by_trending(self, count=30, **kwargs) -> dict:
             api_url = "{}api/recommend/item_list/?{}&{}".format(
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
             for t in res.get("itemList", []):
                 response.append(t)
 
@@ -488,7 +493,7 @@ def discover_type(self, search_term, prefix, count=28, offset=0, **kwargs) -> li
             api_url = "{}api/discover/{}/?{}&{}".format(
                 BASE_URL, prefix, self.__add_new_params__(), urlencode(query)
             )
-            data = self.getData(url=api_url, **kwargs)
+            data = self.get_data(url=api_url, **kwargs)
 
             if "userInfoList" in data.keys():
                 for x in data["userInfoList"]:
@@ -555,7 +560,7 @@ def user_posts(self, userID, secUID, count=30, cursor=0, **kwargs) -> dict:
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
 
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
             if "itemList" in res.keys():
                 for t in res["itemList"]:
@@ -591,7 +596,7 @@ def by_username(self, username, count=30, **kwargs) -> dict:
             did,
         ) = self.__process_kwargs__(kwargs)
         kwargs["custom_did"] = did
-        data = self.getUserObject(username, **kwargs)
+        data = self.get_user_object(username, **kwargs)
         return self.userPosts(
             data["id"],
             data["secUid"],
@@ -637,7 +642,7 @@ def user_page(self, userID, secUID, page_size=30, cursor=0, **kwargs) -> dict:
             )
         )
 
-        return self.getData(url=api_url, **kwargs)
+        return self.get_data(url=api_url, **kwargs)
 
     def get_user_pager(self, username, page_size=30, cursor=0, **kwargs):
         """Returns a generator to page through a user's feed
@@ -727,7 +732,7 @@ def user_liked(self, userID, secUID, count=30, cursor=0, **kwargs) -> dict:
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
 
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
             try:
                 res["itemList"]
@@ -813,7 +818,7 @@ def by_sound(self, id, count=30, offset=0, **kwargs) -> dict:
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
 
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
             try:
                 for t in res["items"]:
@@ -868,11 +873,35 @@ def get_music_object_full(self, id, **kwargs):
             },
             proxies=self.__format_proxy(kwargs.get("proxy", None)),
             cookies=self.get_cookies(**kwargs),
+            **self.requests_extra_kwargs,
         )
 
         j_raw = self.__extract_tag_contents(r.text)
         return json.loads(j_raw)["props"]["pageProps"]["musicInfo"]
 
+    def get_music_object_full_by_api(self, id, **kwargs):
+        """Returns a music object for a specific sound id, but using the API rather than HTML requests.
+
+        Parameters
+        ----------
+        id: The sound id to get the object for
+            This can be found by using other methods.
+        """
+        (
+            region,
+            language,
+            proxy,
+            maxCount,
+            did,
+        ) = self.__process_kwargs__(kwargs)
+        kwargs["custom_did"] = did
+
+        api_url = "{}node/share/music/-{}?{}".format(
+            BASE_URL, id, self.__add_new_params__()
+        )
+        res = self.get_data(url=api_url, **kwargs)
+        return res['musicInfo']
+
     def by_hashtag(self, hashtag, count=30, offset=0, **kwargs) -> dict:
         """Returns a dictionary listing TikToks with a specific hashtag.
 
@@ -912,7 +941,7 @@ def by_hashtag(self, hashtag, count=30, offset=0, **kwargs) -> dict:
             api_url = "{}api/challenge/item_list/?{}&{}".format(
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
             for t in res["itemList"]:
                 response.append(t)
@@ -945,14 +974,12 @@ def get_hashtag_object(self, hashtag, **kwargs) -> dict:
         api_url = "{}node/share/tag/{}?{}&{}".format(
             BASE_URL, quote(hashtag), self.__add_new_params__(), urlencode(query)
         )
-        data = self.getData(url=api_url, **kwargs)
+        data = self.get_data(url=api_url, **kwargs)
         if data["challengeInfo"].get("challenge") is None:
             raise TikTokNotFoundError("Challenge {} does not exist".format(hashtag))
         return data
 
-    def get_recommended_tiktoks_by_video_id(
-        self, id, count=30, minCursor=0, maxCursor=0, **kwargs
-    ) -> dict:
+    def get_recommended_tiktoks_by_video_id(self, id, count=30, **kwargs) -> dict:
         """Returns a dictionary listing reccomended TikToks for a specific TikTok video.
 
 
@@ -960,6 +987,7 @@ def get_recommended_tiktoks_by_video_id(
         ----------
         id: The id of the video to get suggestions for
             Can be found using other methods
+        count: The count of results you want to return
         """
         (
             region,
@@ -983,8 +1011,6 @@ def get_recommended_tiktoks_by_video_id(
                 "count": realCount,
                 "id": 1,
                 "secUid": "",
-                "maxCursor": maxCursor,
-                "minCursor": minCursor,
                 "sourceType": 12,
                 "appId": 1233,
                 "region": region,
@@ -995,9 +1021,9 @@ def get_recommended_tiktoks_by_video_id(
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
 
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
-            for t in res.get("items", []):
+            for t in res.get("itemList", []):
                 response.append(t)
 
             if not res["hasMore"] and not first:
@@ -1005,7 +1031,6 @@ def get_recommended_tiktoks_by_video_id(
                 return response[:count]
 
             realCount = count - len(response)
-            maxCursor = res["maxCursor"]
 
             first = False
 
@@ -1035,7 +1060,7 @@ def get_tiktok_by_id(self, id, **kwargs) -> dict:
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
 
-        return self.getData(url=api_url, **kwargs)
+        return self.get_data(url=api_url, **kwargs)
 
     def get_tiktok_by_url(self, url, **kwargs) -> dict:
         """Returns a dictionary of a TikTok object by url.
@@ -1098,6 +1123,7 @@ def get_tiktok_by_html(self, url, **kwargs) -> dict:
             },
             proxies=self.__format_proxy(kwargs.get("proxy", None)),
             cookies=self.get_cookies(**kwargs),
+            **self.requests_extra_kwargs,
         )
 
         t = r.text
@@ -1113,9 +1139,7 @@ def get_tiktok_by_html(self, url, **kwargs) -> dict:
         data = json.loads(j_raw)["props"]["pageProps"]
 
         if data["serverCode"] == 404:
-            raise TikTokNotFoundError(
-                "TikTok with that url doesn't exist"
-            )
+            raise TikTokNotFoundError("TikTok with that url doesn't exist")
 
         return data
 
@@ -1133,8 +1157,7 @@ def discover_hashtags(self, **kwargs) -> dict:
         api_url = "{}node/share/discover?{}&{}".format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
-
-        return self.getData(url=api_url, **kwargs)["body"][1]["exploreList"]
+        return self.get_data(url=api_url, **kwargs)["body"][1]["exploreList"]
 
     def discover_music(self, **kwargs) -> dict:
         """Discover page, consists of music"""
@@ -1146,12 +1169,12 @@ def discover_music(self, **kwargs) -> dict:
             did,
         ) = self.__process_kwargs__(kwargs)
         kwargs["custom_did"] = did
-        query = {"noUser": 1, "userCount": 30, "scene": 0}
+        query = {"noUser": 0, "userCount": 28, "scene": 17}
         api_url = "{}node/share/discover?{}&{}".format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
 
-        return self.getData(url=api_url, **kwargs)["body"][2]["exploreList"]
+        return self.get_data(url=api_url, **kwargs)["body"][2]["exploreList"]
 
     def get_user_object(self, username, **kwargs) -> dict:
         """Gets a user object (dictionary)
@@ -1197,6 +1220,7 @@ def get_user(self, username, **kwargs) -> dict:
             },
             proxies=self.__format_proxy(kwargs.get("proxy", None)),
             cookies=self.get_cookies(**kwargs),
+            **self.requests_extra_kwargs,
         )
 
         t = r.text
@@ -1247,9 +1271,9 @@ def get_suggested_users_by_id(
         api_url = "{}node/share/discover?{}&{}".format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
-
+        print(api_url)
         res = []
-        for x in self.getData(url=api_url, **kwargs)["body"][0]["exploreList"]:
+        for x in self.get_data(url=api_url, **kwargs)["body"][0]["exploreList"]:
             res.append(x["cardItem"])
         return res[:count]
 
@@ -1314,9 +1338,8 @@ def get_suggested_hashtags_by_id(
         api_url = "{}node/share/discover?{}&{}".format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
-
         res = []
-        for x in self.getData(url=api_url, **kwargs)["body"][1]["exploreList"]:
+        for x in self.get_data(url=api_url, **kwargs)["body"][1]["exploreList"]:
             res.append(x["cardItem"])
         return res[:count]
 
@@ -1384,7 +1407,7 @@ def get_suggested_music_by_id(
         )
 
         res = []
-        for x in self.getData(url=api_url, **kwargs)["body"][2]["exploreList"]:
+        for x in self.get_data(url=api_url, **kwargs)["body"][2]["exploreList"]:
             res.append(x["cardItem"])
         return res[:count]
 
@@ -1529,6 +1552,7 @@ def get_video_no_watermark(self, video_url, return_bytes=1, **kwargs) -> bytes:
                 "user-agent": "okhttp",
             },
             proxies=self.__format_proxy(proxy),
+            **self.requests_extra_kwargs,
         )
 
         if r.text[0] == "{":
@@ -1555,6 +1579,7 @@ def get_music_title(self, id, **kwargs):
             },
             proxies=self.__format_proxy(kwargs.get("proxy", None)),
             cookies=self.get_cookies(**kwargs),
+            **self.requests_extra_kwargs,
         )
         t = r.text
         j_raw = self.__extract_tag_contents(r.text)
@@ -1586,6 +1611,7 @@ def get_secuid(self, username, **kwargs):
             proxies=self.__format_proxy(
                 kwargs.get("proxy", None), cookies=self.get_cookies(**kwargs)
             ),
+            **self.requests_extra_kwargs,
         )
         try:
             return r.text.split('"secUid":"')[1].split('","secret":')[0]
@@ -1619,6 +1645,7 @@ def __get_js(self, proxy=None) -> str:
         return requests.get(
             "https://sf16-muse-va.ibytedtos.com/obj/rc-web-sdk-gcs/acrawler.js",
             proxies=self.__format_proxy(proxy),
+            **self.requests_extra_kwargs,
         ).text
 
     def __format_new_params__(self, parm) -> str:
@@ -1656,7 +1683,8 @@ def __extract_tag_contents(self, html):
         nonce_end = '">'
         nonce = html.split(nonce_start)[1].split(nonce_end)[0]
         j_raw = html.split(
-            '<script id="__NEXT_DATA__" type="application/json" nonce="%s" crossorigin="anonymous">' % nonce
+            '<script id="__NEXT_DATA__" type="application/json" nonce="%s" crossorigin="anonymous">'
+            % nonce
         )[1].split("</script>")[0]
         return j_raw
 
diff --git a/docs/browser.html b/docs/TikTokApi/browser.html
similarity index 99%
rename from docs/browser.html
rename to docs/TikTokApi/browser.html
index fd135127..698e7ec9 100644
--- a/docs/browser.html
+++ b/docs/TikTokApi/browser.html
@@ -542,7 +542,8 @@ <h3>Methods</h3>
     try:
         self.browser.close()
     except Exception:
-        logging.info(&#34;cleanup failed&#34;)</code></pre>
+        logging.info(&#34;cleanup failed&#34;)
+    # playwright.stop()</code></pre>
 </details>
 </dd>
 <dt id="TikTokApi.browser.browser.create_context"><code class="name flex">
diff --git a/docs/browser_selenium.html b/docs/TikTokApi/browser_selenium.html
similarity index 100%
rename from docs/browser_selenium.html
rename to docs/TikTokApi/browser_selenium.html
diff --git a/docs/exceptions.html b/docs/TikTokApi/exceptions.html
similarity index 100%
rename from docs/exceptions.html
rename to docs/TikTokApi/exceptions.html
diff --git a/docs/get_acrawler.html b/docs/TikTokApi/get_acrawler.html
similarity index 100%
rename from docs/get_acrawler.html
rename to docs/TikTokApi/get_acrawler.html
diff --git a/docs/index.html b/docs/TikTokApi/index.html
similarity index 100%
rename from docs/index.html
rename to docs/TikTokApi/index.html
diff --git a/docs/stealth.html b/docs/TikTokApi/stealth.html
similarity index 100%
rename from docs/stealth.html
rename to docs/TikTokApi/stealth.html
diff --git a/docs/tiktok.html b/docs/TikTokApi/tiktok.html
similarity index 95%
rename from docs/tiktok.html
rename to docs/TikTokApi/tiktok.html
index 30fdccf4..cb3714cf 100644
--- a/docs/tiktok.html
+++ b/docs/TikTokApi/tiktok.html
@@ -70,6 +70,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
         self.custom_verifyFp = kwargs.get(&#34;custom_verifyFp&#34;)
         self.signer_url = kwargs.get(&#34;external_signer&#34;, None)
         self.request_delay = kwargs.get(&#34;request_delay&#34;, None)
+        self.requests_extra_kwargs = kwargs.get(&#34;requests_extra_kwargs&#34;, {})
 
         if kwargs.get(&#34;use_test_endpoints&#34;, False):
             global BASE_URL
@@ -212,7 +213,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
             query = {&#34;url&#34;: url, &#34;custom_did&#34;: custom_did, &#34;verifyFp&#34;: verifyFp}
         else:
             query = {&#34;url&#34;: url, &#34;verifyFp&#34;: verifyFp}
-        data = requests.get(self.signer_url + &#34;?{}&#34;.format(urlencode(query)))
+        data = requests.get(self.signer_url + &#34;?{}&#34;.format(urlencode(query)), **self.requests_extra_kwargs)
         parsed_data = data.json()
 
         return (
@@ -287,10 +288,14 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
             },
             cookies=self.get_cookies(**kwargs),
             proxies=self.__format_proxy(proxy),
+            **self.requests_extra_kwargs,
         )
         try:
             json = r.json()
-            if json.get(&#34;type&#34;) == &#34;verify&#34;:
+            if (
+                json.get(&#34;type&#34;) == &#34;verify&#34;
+                or json.get(&#34;verifyConfig&#34;, {}).get(&#34;type&#34;, &#34;&#34;) == &#34;verify&#34;
+            ):
                 logging.error(
                     &#34;Tiktok wants to display a catcha. Response is:\n&#34; + r.text
                 )
@@ -429,7 +434,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
             api_url = &#34;{}api/recommend/item_list/?{}&amp;{}&#34;.format(
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
             for t in res.get(&#34;itemList&#34;, []):
                 response.append(t)
 
@@ -505,18 +510,18 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
         response = []
         while len(response) &lt; count:
             query = {
-                &#34;discoverType&#34;: count,
+                &#34;discoverType&#34;: 1,
                 &#34;needItemList&#34;: False,
                 &#34;keyWord&#34;: search_term,
                 &#34;offset&#34;: offset,
-                &#34;count&#34;: 99,
+                &#34;count&#34;: count,
                 &#34;useRecommend&#34;: False,
                 &#34;language&#34;: &#34;en&#34;,
             }
             api_url = &#34;{}api/discover/{}/?{}&amp;{}&#34;.format(
                 BASE_URL, prefix, self.__add_new_params__(), urlencode(query)
             )
-            data = self.getData(url=api_url, **kwargs)
+            data = self.get_data(url=api_url, **kwargs)
 
             if &#34;userInfoList&#34; in data.keys():
                 for x in data[&#34;userInfoList&#34;]:
@@ -583,7 +588,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
 
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
             if &#34;itemList&#34; in res.keys():
                 for t in res[&#34;itemList&#34;]:
@@ -619,7 +624,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
             did,
         ) = self.__process_kwargs__(kwargs)
         kwargs[&#34;custom_did&#34;] = did
-        data = self.getUserObject(username, **kwargs)
+        data = self.get_user_object(username, **kwargs)
         return self.userPosts(
             data[&#34;id&#34;],
             data[&#34;secUid&#34;],
@@ -665,7 +670,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
             )
         )
 
-        return self.getData(url=api_url, **kwargs)
+        return self.get_data(url=api_url, **kwargs)
 
     def get_user_pager(self, username, page_size=30, cursor=0, **kwargs):
         &#34;&#34;&#34;Returns a generator to page through a user&#39;s feed
@@ -755,7 +760,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
 
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
             try:
                 res[&#34;itemList&#34;]
@@ -841,7 +846,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
 
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
             try:
                 for t in res[&#34;items&#34;]:
@@ -896,13 +901,35 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
             },
             proxies=self.__format_proxy(kwargs.get(&#34;proxy&#34;, None)),
             cookies=self.get_cookies(**kwargs),
+            **self.requests_extra_kwargs,
         )
-        t = r.text
-        j_raw = t.split(
-            &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
-        )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+
+        j_raw = self.__extract_tag_contents(r.text)
         return json.loads(j_raw)[&#34;props&#34;][&#34;pageProps&#34;][&#34;musicInfo&#34;]
 
+    def get_music_object_full_by_api(self, id, **kwargs):
+        &#34;&#34;&#34;Returns a music object for a specific sound id, but using the API rather than HTML requests.
+
+        Parameters
+        ----------
+        id: The sound id to get the object for
+            This can be found by using other methods.
+        &#34;&#34;&#34;
+        (
+            region,
+            language,
+            proxy,
+            maxCount,
+            did,
+        ) = self.__process_kwargs__(kwargs)
+        kwargs[&#34;custom_did&#34;] = did
+
+        api_url = &#34;{}node/share/music/-{}?{}&#34;.format(
+            BASE_URL, id, self.__add_new_params__()
+        )
+        res = self.get_data(url=api_url, **kwargs)
+        return res[&#39;musicInfo&#39;]
+
     def by_hashtag(self, hashtag, count=30, offset=0, **kwargs) -&gt; dict:
         &#34;&#34;&#34;Returns a dictionary listing TikToks with a specific hashtag.
 
@@ -942,7 +969,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
             api_url = &#34;{}api/challenge/item_list/?{}&amp;{}&#34;.format(
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
             for t in res[&#34;itemList&#34;]:
                 response.append(t)
@@ -975,14 +1002,12 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
         api_url = &#34;{}node/share/tag/{}?{}&amp;{}&#34;.format(
             BASE_URL, quote(hashtag), self.__add_new_params__(), urlencode(query)
         )
-        data = self.getData(url=api_url, **kwargs)
+        data = self.get_data(url=api_url, **kwargs)
         if data[&#34;challengeInfo&#34;].get(&#34;challenge&#34;) is None:
             raise TikTokNotFoundError(&#34;Challenge {} does not exist&#34;.format(hashtag))
         return data
 
-    def get_recommended_tiktoks_by_video_id(
-        self, id, count=30, minCursor=0, maxCursor=0, **kwargs
-    ) -&gt; dict:
+    def get_recommended_tiktoks_by_video_id(self, id, count=30, **kwargs) -&gt; dict:
         &#34;&#34;&#34;Returns a dictionary listing reccomended TikToks for a specific TikTok video.
 
 
@@ -990,6 +1015,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
         ----------
         id: The id of the video to get suggestions for
             Can be found using other methods
+        count: The count of results you want to return
         &#34;&#34;&#34;
         (
             region,
@@ -1013,8 +1039,6 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
                 &#34;count&#34;: realCount,
                 &#34;id&#34;: 1,
                 &#34;secUid&#34;: &#34;&#34;,
-                &#34;maxCursor&#34;: maxCursor,
-                &#34;minCursor&#34;: minCursor,
                 &#34;sourceType&#34;: 12,
                 &#34;appId&#34;: 1233,
                 &#34;region&#34;: region,
@@ -1025,9 +1049,9 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
 
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
-            for t in res.get(&#34;items&#34;, []):
+            for t in res.get(&#34;itemList&#34;, []):
                 response.append(t)
 
             if not res[&#34;hasMore&#34;] and not first:
@@ -1035,7 +1059,6 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
                 return response[:count]
 
             realCount = count - len(response)
-            maxCursor = res[&#34;maxCursor&#34;]
 
             first = False
 
@@ -1065,7 +1088,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
 
-        return self.getData(url=api_url, **kwargs)
+        return self.get_data(url=api_url, **kwargs)
 
     def get_tiktok_by_url(self, url, **kwargs) -&gt; dict:
         &#34;&#34;&#34;Returns a dictionary of a TikTok object by url.
@@ -1128,13 +1151,12 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
             },
             proxies=self.__format_proxy(kwargs.get(&#34;proxy&#34;, None)),
             cookies=self.get_cookies(**kwargs),
+            **self.requests_extra_kwargs,
         )
 
         t = r.text
         try:
-            j_raw = t.split(
-                &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
-            )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+            j_raw = self.__extract_tag_contents(r.text)
         except IndexError:
             if not t:
                 logging.error(&#34;TikTok response is empty&#34;)
@@ -1145,9 +1167,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
         data = json.loads(j_raw)[&#34;props&#34;][&#34;pageProps&#34;]
 
         if data[&#34;serverCode&#34;] == 404:
-            raise TikTokNotFoundError(
-                &#34;TikTok with that url doesn&#39;t exist&#34;.format(username)
-            )
+            raise TikTokNotFoundError(&#34;TikTok with that url doesn&#39;t exist&#34;)
 
         return data
 
@@ -1165,8 +1185,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
         api_url = &#34;{}node/share/discover?{}&amp;{}&#34;.format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
-
-        return self.getData(url=api_url, **kwargs)[&#34;body&#34;][1][&#34;exploreList&#34;]
+        return self.get_data(url=api_url, **kwargs)[&#34;body&#34;][1][&#34;exploreList&#34;]
 
     def discover_music(self, **kwargs) -&gt; dict:
         &#34;&#34;&#34;Discover page, consists of music&#34;&#34;&#34;
@@ -1178,12 +1197,12 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
             did,
         ) = self.__process_kwargs__(kwargs)
         kwargs[&#34;custom_did&#34;] = did
-        query = {&#34;noUser&#34;: 1, &#34;userCount&#34;: 30, &#34;scene&#34;: 0}
+        query = {&#34;noUser&#34;: 0, &#34;userCount&#34;: 28, &#34;scene&#34;: 17}
         api_url = &#34;{}node/share/discover?{}&amp;{}&#34;.format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
 
-        return self.getData(url=api_url, **kwargs)[&#34;body&#34;][2][&#34;exploreList&#34;]
+        return self.get_data(url=api_url, **kwargs)[&#34;body&#34;][2][&#34;exploreList&#34;]
 
     def get_user_object(self, username, **kwargs) -&gt; dict:
         &#34;&#34;&#34;Gets a user object (dictionary)
@@ -1229,14 +1248,13 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
             },
             proxies=self.__format_proxy(kwargs.get(&#34;proxy&#34;, None)),
             cookies=self.get_cookies(**kwargs),
+            **self.requests_extra_kwargs,
         )
 
         t = r.text
 
         try:
-            j_raw = t.split(
-                &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
-            )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+            j_raw = self.__extract_tag_contents(r.text)
         except IndexError:
             if not t:
                 logging.error(&#34;Tiktok response is empty&#34;)
@@ -1281,9 +1299,9 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
         api_url = &#34;{}node/share/discover?{}&amp;{}&#34;.format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
-
+        print(api_url)
         res = []
-        for x in self.getData(url=api_url, **kwargs)[&#34;body&#34;][0][&#34;exploreList&#34;]:
+        for x in self.get_data(url=api_url, **kwargs)[&#34;body&#34;][0][&#34;exploreList&#34;]:
             res.append(x[&#34;cardItem&#34;])
         return res[:count]
 
@@ -1348,9 +1366,8 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
         api_url = &#34;{}node/share/discover?{}&amp;{}&#34;.format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
-
         res = []
-        for x in self.getData(url=api_url, **kwargs)[&#34;body&#34;][1][&#34;exploreList&#34;]:
+        for x in self.get_data(url=api_url, **kwargs)[&#34;body&#34;][1][&#34;exploreList&#34;]:
             res.append(x[&#34;cardItem&#34;])
         return res[:count]
 
@@ -1418,7 +1435,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
         )
 
         res = []
-        for x in self.getData(url=api_url, **kwargs)[&#34;body&#34;][2][&#34;exploreList&#34;]:
+        for x in self.get_data(url=api_url, **kwargs)[&#34;body&#34;][2][&#34;exploreList&#34;]:
             res.append(x[&#34;cardItem&#34;])
         return res[:count]
 
@@ -1563,6 +1580,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
                 &#34;user-agent&#34;: &#34;okhttp&#34;,
             },
             proxies=self.__format_proxy(proxy),
+            **self.requests_extra_kwargs,
         )
 
         if r.text[0] == &#34;{&#34;:
@@ -1589,11 +1607,10 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
             },
             proxies=self.__format_proxy(kwargs.get(&#34;proxy&#34;, None)),
             cookies=self.get_cookies(**kwargs),
+            **self.requests_extra_kwargs,
         )
         t = r.text
-        j_raw = t.split(
-            &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
-        )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+        j_raw = self.__extract_tag_contents(r.text)
 
         music_object = json.loads(j_raw)[&#34;props&#34;][&#34;pageProps&#34;][&#34;musicInfo&#34;]
         if not music_object.get(&#34;title&#34;, None):
@@ -1622,6 +1639,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
             proxies=self.__format_proxy(
                 kwargs.get(&#34;proxy&#34;, None), cookies=self.get_cookies(**kwargs)
             ),
+            **self.requests_extra_kwargs,
         )
         try:
             return r.text.split(&#39;&#34;secUid&#34;:&#34;&#39;)[1].split(&#39;&#34;,&#34;secret&#34;:&#39;)[0]
@@ -1655,6 +1673,7 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
         return requests.get(
             &#34;https://sf16-muse-va.ibytedtos.com/obj/rc-web-sdk-gcs/acrawler.js&#34;,
             proxies=self.__format_proxy(proxy),
+            **self.requests_extra_kwargs,
         ).text
 
     def __format_new_params__(self, parm) -&gt; str:
@@ -1687,6 +1706,16 @@ <h1 class="title">Module <code>TikTokApi.tiktok</code></h1>
         }
         return urlencode(query)
 
+    def __extract_tag_contents(self, html):
+        nonce_start = &#39;&lt;head nonce=&#34;&#39;
+        nonce_end = &#39;&#34;&gt;&#39;
+        nonce = html.split(nonce_start)[1].split(nonce_end)[0]
+        j_raw = html.split(
+            &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; nonce=&#34;%s&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
+            % nonce
+        )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+        return j_raw
+
     # Process the kwargs
     def __process_kwargs__(self, kwargs):
         region = kwargs.get(&#34;region&#34;, &#34;US&#34;)
@@ -1819,6 +1848,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
         self.custom_verifyFp = kwargs.get(&#34;custom_verifyFp&#34;)
         self.signer_url = kwargs.get(&#34;external_signer&#34;, None)
         self.request_delay = kwargs.get(&#34;request_delay&#34;, None)
+        self.requests_extra_kwargs = kwargs.get(&#34;requests_extra_kwargs&#34;, {})
 
         if kwargs.get(&#34;use_test_endpoints&#34;, False):
             global BASE_URL
@@ -1961,7 +1991,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
             query = {&#34;url&#34;: url, &#34;custom_did&#34;: custom_did, &#34;verifyFp&#34;: verifyFp}
         else:
             query = {&#34;url&#34;: url, &#34;verifyFp&#34;: verifyFp}
-        data = requests.get(self.signer_url + &#34;?{}&#34;.format(urlencode(query)))
+        data = requests.get(self.signer_url + &#34;?{}&#34;.format(urlencode(query)), **self.requests_extra_kwargs)
         parsed_data = data.json()
 
         return (
@@ -2036,10 +2066,14 @@ <h2 class="section-title" id="header-classes">Classes</h2>
             },
             cookies=self.get_cookies(**kwargs),
             proxies=self.__format_proxy(proxy),
+            **self.requests_extra_kwargs,
         )
         try:
             json = r.json()
-            if json.get(&#34;type&#34;) == &#34;verify&#34;:
+            if (
+                json.get(&#34;type&#34;) == &#34;verify&#34;
+                or json.get(&#34;verifyConfig&#34;, {}).get(&#34;type&#34;, &#34;&#34;) == &#34;verify&#34;
+            ):
                 logging.error(
                     &#34;Tiktok wants to display a catcha. Response is:\n&#34; + r.text
                 )
@@ -2178,7 +2212,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
             api_url = &#34;{}api/recommend/item_list/?{}&amp;{}&#34;.format(
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
             for t in res.get(&#34;itemList&#34;, []):
                 response.append(t)
 
@@ -2254,18 +2288,18 @@ <h2 class="section-title" id="header-classes">Classes</h2>
         response = []
         while len(response) &lt; count:
             query = {
-                &#34;discoverType&#34;: count,
+                &#34;discoverType&#34;: 1,
                 &#34;needItemList&#34;: False,
                 &#34;keyWord&#34;: search_term,
                 &#34;offset&#34;: offset,
-                &#34;count&#34;: 99,
+                &#34;count&#34;: count,
                 &#34;useRecommend&#34;: False,
                 &#34;language&#34;: &#34;en&#34;,
             }
             api_url = &#34;{}api/discover/{}/?{}&amp;{}&#34;.format(
                 BASE_URL, prefix, self.__add_new_params__(), urlencode(query)
             )
-            data = self.getData(url=api_url, **kwargs)
+            data = self.get_data(url=api_url, **kwargs)
 
             if &#34;userInfoList&#34; in data.keys():
                 for x in data[&#34;userInfoList&#34;]:
@@ -2332,7 +2366,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
 
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
             if &#34;itemList&#34; in res.keys():
                 for t in res[&#34;itemList&#34;]:
@@ -2368,7 +2402,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
             did,
         ) = self.__process_kwargs__(kwargs)
         kwargs[&#34;custom_did&#34;] = did
-        data = self.getUserObject(username, **kwargs)
+        data = self.get_user_object(username, **kwargs)
         return self.userPosts(
             data[&#34;id&#34;],
             data[&#34;secUid&#34;],
@@ -2414,7 +2448,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
             )
         )
 
-        return self.getData(url=api_url, **kwargs)
+        return self.get_data(url=api_url, **kwargs)
 
     def get_user_pager(self, username, page_size=30, cursor=0, **kwargs):
         &#34;&#34;&#34;Returns a generator to page through a user&#39;s feed
@@ -2504,7 +2538,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
 
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
             try:
                 res[&#34;itemList&#34;]
@@ -2590,7 +2624,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
 
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
             try:
                 for t in res[&#34;items&#34;]:
@@ -2645,13 +2679,35 @@ <h2 class="section-title" id="header-classes">Classes</h2>
             },
             proxies=self.__format_proxy(kwargs.get(&#34;proxy&#34;, None)),
             cookies=self.get_cookies(**kwargs),
+            **self.requests_extra_kwargs,
         )
-        t = r.text
-        j_raw = t.split(
-            &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
-        )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+
+        j_raw = self.__extract_tag_contents(r.text)
         return json.loads(j_raw)[&#34;props&#34;][&#34;pageProps&#34;][&#34;musicInfo&#34;]
 
+    def get_music_object_full_by_api(self, id, **kwargs):
+        &#34;&#34;&#34;Returns a music object for a specific sound id, but using the API rather than HTML requests.
+
+        Parameters
+        ----------
+        id: The sound id to get the object for
+            This can be found by using other methods.
+        &#34;&#34;&#34;
+        (
+            region,
+            language,
+            proxy,
+            maxCount,
+            did,
+        ) = self.__process_kwargs__(kwargs)
+        kwargs[&#34;custom_did&#34;] = did
+
+        api_url = &#34;{}node/share/music/-{}?{}&#34;.format(
+            BASE_URL, id, self.__add_new_params__()
+        )
+        res = self.get_data(url=api_url, **kwargs)
+        return res[&#39;musicInfo&#39;]
+
     def by_hashtag(self, hashtag, count=30, offset=0, **kwargs) -&gt; dict:
         &#34;&#34;&#34;Returns a dictionary listing TikToks with a specific hashtag.
 
@@ -2691,7 +2747,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
             api_url = &#34;{}api/challenge/item_list/?{}&amp;{}&#34;.format(
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
             for t in res[&#34;itemList&#34;]:
                 response.append(t)
@@ -2724,14 +2780,12 @@ <h2 class="section-title" id="header-classes">Classes</h2>
         api_url = &#34;{}node/share/tag/{}?{}&amp;{}&#34;.format(
             BASE_URL, quote(hashtag), self.__add_new_params__(), urlencode(query)
         )
-        data = self.getData(url=api_url, **kwargs)
+        data = self.get_data(url=api_url, **kwargs)
         if data[&#34;challengeInfo&#34;].get(&#34;challenge&#34;) is None:
             raise TikTokNotFoundError(&#34;Challenge {} does not exist&#34;.format(hashtag))
         return data
 
-    def get_recommended_tiktoks_by_video_id(
-        self, id, count=30, minCursor=0, maxCursor=0, **kwargs
-    ) -&gt; dict:
+    def get_recommended_tiktoks_by_video_id(self, id, count=30, **kwargs) -&gt; dict:
         &#34;&#34;&#34;Returns a dictionary listing reccomended TikToks for a specific TikTok video.
 
 
@@ -2739,6 +2793,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
         ----------
         id: The id of the video to get suggestions for
             Can be found using other methods
+        count: The count of results you want to return
         &#34;&#34;&#34;
         (
             region,
@@ -2762,8 +2817,6 @@ <h2 class="section-title" id="header-classes">Classes</h2>
                 &#34;count&#34;: realCount,
                 &#34;id&#34;: 1,
                 &#34;secUid&#34;: &#34;&#34;,
-                &#34;maxCursor&#34;: maxCursor,
-                &#34;minCursor&#34;: minCursor,
                 &#34;sourceType&#34;: 12,
                 &#34;appId&#34;: 1233,
                 &#34;region&#34;: region,
@@ -2774,9 +2827,9 @@ <h2 class="section-title" id="header-classes">Classes</h2>
                 BASE_URL, self.__add_new_params__(), urlencode(query)
             )
 
-            res = self.getData(url=api_url, **kwargs)
+            res = self.get_data(url=api_url, **kwargs)
 
-            for t in res.get(&#34;items&#34;, []):
+            for t in res.get(&#34;itemList&#34;, []):
                 response.append(t)
 
             if not res[&#34;hasMore&#34;] and not first:
@@ -2784,7 +2837,6 @@ <h2 class="section-title" id="header-classes">Classes</h2>
                 return response[:count]
 
             realCount = count - len(response)
-            maxCursor = res[&#34;maxCursor&#34;]
 
             first = False
 
@@ -2814,7 +2866,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
 
-        return self.getData(url=api_url, **kwargs)
+        return self.get_data(url=api_url, **kwargs)
 
     def get_tiktok_by_url(self, url, **kwargs) -&gt; dict:
         &#34;&#34;&#34;Returns a dictionary of a TikTok object by url.
@@ -2877,13 +2929,12 @@ <h2 class="section-title" id="header-classes">Classes</h2>
             },
             proxies=self.__format_proxy(kwargs.get(&#34;proxy&#34;, None)),
             cookies=self.get_cookies(**kwargs),
+            **self.requests_extra_kwargs,
         )
 
         t = r.text
         try:
-            j_raw = t.split(
-                &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
-            )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+            j_raw = self.__extract_tag_contents(r.text)
         except IndexError:
             if not t:
                 logging.error(&#34;TikTok response is empty&#34;)
@@ -2894,9 +2945,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
         data = json.loads(j_raw)[&#34;props&#34;][&#34;pageProps&#34;]
 
         if data[&#34;serverCode&#34;] == 404:
-            raise TikTokNotFoundError(
-                &#34;TikTok with that url doesn&#39;t exist&#34;.format(username)
-            )
+            raise TikTokNotFoundError(&#34;TikTok with that url doesn&#39;t exist&#34;)
 
         return data
 
@@ -2914,8 +2963,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
         api_url = &#34;{}node/share/discover?{}&amp;{}&#34;.format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
-
-        return self.getData(url=api_url, **kwargs)[&#34;body&#34;][1][&#34;exploreList&#34;]
+        return self.get_data(url=api_url, **kwargs)[&#34;body&#34;][1][&#34;exploreList&#34;]
 
     def discover_music(self, **kwargs) -&gt; dict:
         &#34;&#34;&#34;Discover page, consists of music&#34;&#34;&#34;
@@ -2927,12 +2975,12 @@ <h2 class="section-title" id="header-classes">Classes</h2>
             did,
         ) = self.__process_kwargs__(kwargs)
         kwargs[&#34;custom_did&#34;] = did
-        query = {&#34;noUser&#34;: 1, &#34;userCount&#34;: 30, &#34;scene&#34;: 0}
+        query = {&#34;noUser&#34;: 0, &#34;userCount&#34;: 28, &#34;scene&#34;: 17}
         api_url = &#34;{}node/share/discover?{}&amp;{}&#34;.format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
 
-        return self.getData(url=api_url, **kwargs)[&#34;body&#34;][2][&#34;exploreList&#34;]
+        return self.get_data(url=api_url, **kwargs)[&#34;body&#34;][2][&#34;exploreList&#34;]
 
     def get_user_object(self, username, **kwargs) -&gt; dict:
         &#34;&#34;&#34;Gets a user object (dictionary)
@@ -2978,14 +3026,13 @@ <h2 class="section-title" id="header-classes">Classes</h2>
             },
             proxies=self.__format_proxy(kwargs.get(&#34;proxy&#34;, None)),
             cookies=self.get_cookies(**kwargs),
+            **self.requests_extra_kwargs,
         )
 
         t = r.text
 
         try:
-            j_raw = t.split(
-                &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
-            )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+            j_raw = self.__extract_tag_contents(r.text)
         except IndexError:
             if not t:
                 logging.error(&#34;Tiktok response is empty&#34;)
@@ -3030,9 +3077,9 @@ <h2 class="section-title" id="header-classes">Classes</h2>
         api_url = &#34;{}node/share/discover?{}&amp;{}&#34;.format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
-
+        print(api_url)
         res = []
-        for x in self.getData(url=api_url, **kwargs)[&#34;body&#34;][0][&#34;exploreList&#34;]:
+        for x in self.get_data(url=api_url, **kwargs)[&#34;body&#34;][0][&#34;exploreList&#34;]:
             res.append(x[&#34;cardItem&#34;])
         return res[:count]
 
@@ -3097,9 +3144,8 @@ <h2 class="section-title" id="header-classes">Classes</h2>
         api_url = &#34;{}node/share/discover?{}&amp;{}&#34;.format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
-
         res = []
-        for x in self.getData(url=api_url, **kwargs)[&#34;body&#34;][1][&#34;exploreList&#34;]:
+        for x in self.get_data(url=api_url, **kwargs)[&#34;body&#34;][1][&#34;exploreList&#34;]:
             res.append(x[&#34;cardItem&#34;])
         return res[:count]
 
@@ -3167,7 +3213,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
         )
 
         res = []
-        for x in self.getData(url=api_url, **kwargs)[&#34;body&#34;][2][&#34;exploreList&#34;]:
+        for x in self.get_data(url=api_url, **kwargs)[&#34;body&#34;][2][&#34;exploreList&#34;]:
             res.append(x[&#34;cardItem&#34;])
         return res[:count]
 
@@ -3312,6 +3358,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
                 &#34;user-agent&#34;: &#34;okhttp&#34;,
             },
             proxies=self.__format_proxy(proxy),
+            **self.requests_extra_kwargs,
         )
 
         if r.text[0] == &#34;{&#34;:
@@ -3338,11 +3385,10 @@ <h2 class="section-title" id="header-classes">Classes</h2>
             },
             proxies=self.__format_proxy(kwargs.get(&#34;proxy&#34;, None)),
             cookies=self.get_cookies(**kwargs),
+            **self.requests_extra_kwargs,
         )
         t = r.text
-        j_raw = t.split(
-            &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
-        )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+        j_raw = self.__extract_tag_contents(r.text)
 
         music_object = json.loads(j_raw)[&#34;props&#34;][&#34;pageProps&#34;][&#34;musicInfo&#34;]
         if not music_object.get(&#34;title&#34;, None):
@@ -3371,6 +3417,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
             proxies=self.__format_proxy(
                 kwargs.get(&#34;proxy&#34;, None), cookies=self.get_cookies(**kwargs)
             ),
+            **self.requests_extra_kwargs,
         )
         try:
             return r.text.split(&#39;&#34;secUid&#34;:&#34;&#39;)[1].split(&#39;&#34;,&#34;secret&#34;:&#39;)[0]
@@ -3404,6 +3451,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
         return requests.get(
             &#34;https://sf16-muse-va.ibytedtos.com/obj/rc-web-sdk-gcs/acrawler.js&#34;,
             proxies=self.__format_proxy(proxy),
+            **self.requests_extra_kwargs,
         ).text
 
     def __format_new_params__(self, parm) -&gt; str:
@@ -3436,6 +3484,16 @@ <h2 class="section-title" id="header-classes">Classes</h2>
         }
         return urlencode(query)
 
+    def __extract_tag_contents(self, html):
+        nonce_start = &#39;&lt;head nonce=&#34;&#39;
+        nonce_end = &#39;&#34;&gt;&#39;
+        nonce = html.split(nonce_start)[1].split(nonce_end)[0]
+        j_raw = html.split(
+            &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; nonce=&#34;%s&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
+            % nonce
+        )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+        return j_raw
+
     # Process the kwargs
     def __process_kwargs__(self, kwargs):
         region = kwargs.get(&#34;region&#34;, &#34;US&#34;)
@@ -3677,7 +3735,7 @@ <h2 id="parameters">Parameters</h2>
         api_url = &#34;{}api/challenge/item_list/?{}&amp;{}&#34;.format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
-        res = self.getData(url=api_url, **kwargs)
+        res = self.get_data(url=api_url, **kwargs)
 
         for t in res[&#34;itemList&#34;]:
             response.append(t)
@@ -3745,7 +3803,7 @@ <h2 id="parameters">Parameters</h2>
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
 
-        res = self.getData(url=api_url, **kwargs)
+        res = self.get_data(url=api_url, **kwargs)
 
         try:
             for t in res[&#34;items&#34;]:
@@ -3822,7 +3880,7 @@ <h2 id="parameters">Parameters</h2>
         api_url = &#34;{}api/recommend/item_list/?{}&amp;{}&#34;.format(
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
-        res = self.getData(url=api_url, **kwargs)
+        res = self.get_data(url=api_url, **kwargs)
         for t in res.get(&#34;itemList&#34;, []):
             response.append(t)
 
@@ -3873,7 +3931,7 @@ <h2 id="parameters">Parameters</h2>
         did,
     ) = self.__process_kwargs__(kwargs)
     kwargs[&#34;custom_did&#34;] = did
-    data = self.getUserObject(username, **kwargs)
+    data = self.get_user_object(username, **kwargs)
     return self.userPosts(
         data[&#34;id&#34;],
         data[&#34;secUid&#34;],
@@ -3919,8 +3977,7 @@ <h2 id="parameters">Parameters</h2>
     api_url = &#34;{}node/share/discover?{}&amp;{}&#34;.format(
         BASE_URL, self.__add_new_params__(), urlencode(query)
     )
-
-    return self.getData(url=api_url, **kwargs)[&#34;body&#34;][1][&#34;exploreList&#34;]</code></pre>
+    return self.get_data(url=api_url, **kwargs)[&#34;body&#34;][1][&#34;exploreList&#34;]</code></pre>
 </details>
 </dd>
 <dt id="TikTokApi.tiktok.TikTokApi.discover_music"><code class="name flex">
@@ -3942,12 +3999,12 @@ <h2 id="parameters">Parameters</h2>
         did,
     ) = self.__process_kwargs__(kwargs)
     kwargs[&#34;custom_did&#34;] = did
-    query = {&#34;noUser&#34;: 1, &#34;userCount&#34;: 30, &#34;scene&#34;: 0}
+    query = {&#34;noUser&#34;: 0, &#34;userCount&#34;: 28, &#34;scene&#34;: 17}
     api_url = &#34;{}node/share/discover?{}&amp;{}&#34;.format(
         BASE_URL, self.__add_new_params__(), urlencode(query)
     )
 
-    return self.getData(url=api_url, **kwargs)[&#34;body&#34;][2][&#34;exploreList&#34;]</code></pre>
+    return self.get_data(url=api_url, **kwargs)[&#34;body&#34;][2][&#34;exploreList&#34;]</code></pre>
 </details>
 </dd>
 <dt id="TikTokApi.tiktok.TikTokApi.discover_type"><code class="name flex">
@@ -3992,18 +4049,18 @@ <h2 id="parameters">Parameters</h2>
     response = []
     while len(response) &lt; count:
         query = {
-            &#34;discoverType&#34;: count,
+            &#34;discoverType&#34;: 1,
             &#34;needItemList&#34;: False,
             &#34;keyWord&#34;: search_term,
             &#34;offset&#34;: offset,
-            &#34;count&#34;: 99,
+            &#34;count&#34;: count,
             &#34;useRecommend&#34;: False,
             &#34;language&#34;: &#34;en&#34;,
         }
         api_url = &#34;{}api/discover/{}/?{}&amp;{}&#34;.format(
             BASE_URL, prefix, self.__add_new_params__(), urlencode(query)
         )
-        data = self.getData(url=api_url, **kwargs)
+        data = self.get_data(url=api_url, **kwargs)
 
         if &#34;userInfoList&#34; in data.keys():
             for x in data[&#34;userInfoList&#34;]:
@@ -4065,7 +4122,7 @@ <h2 id="parameters">Parameters</h2>
         query = {&#34;url&#34;: url, &#34;custom_did&#34;: custom_did, &#34;verifyFp&#34;: verifyFp}
     else:
         query = {&#34;url&#34;: url, &#34;verifyFp&#34;: verifyFp}
-    data = requests.get(self.signer_url + &#34;?{}&#34;.format(urlencode(query)))
+    data = requests.get(self.signer_url + &#34;?{}&#34;.format(urlencode(query)), **self.requests_extra_kwargs)
     parsed_data = data.json()
 
     return (
@@ -4258,10 +4315,14 @@ <h2 id="parameters">Parameters</h2>
         },
         cookies=self.get_cookies(**kwargs),
         proxies=self.__format_proxy(proxy),
+        **self.requests_extra_kwargs,
     )
     try:
         json = r.json()
-        if json.get(&#34;type&#34;) == &#34;verify&#34;:
+        if (
+            json.get(&#34;type&#34;) == &#34;verify&#34;
+            or json.get(&#34;verifyConfig&#34;, {}).get(&#34;type&#34;, &#34;&#34;) == &#34;verify&#34;
+        ):
             logging.error(
                 &#34;Tiktok wants to display a catcha. Response is:\n&#34; + r.text
             )
@@ -4320,7 +4381,7 @@ <h2 id="parameters">Parameters</h2>
     api_url = &#34;{}node/share/tag/{}?{}&amp;{}&#34;.format(
         BASE_URL, quote(hashtag), self.__add_new_params__(), urlencode(query)
     )
-    data = self.getData(url=api_url, **kwargs)
+    data = self.get_data(url=api_url, **kwargs)
     if data[&#34;challengeInfo&#34;].get(&#34;challenge&#34;) is None:
         raise TikTokNotFoundError(&#34;Challenge {} does not exist&#34;.format(hashtag))
     return data</code></pre>
@@ -4392,14 +4453,51 @@ <h2 id="parameters">Parameters</h2>
         },
         proxies=self.__format_proxy(kwargs.get(&#34;proxy&#34;, None)),
         cookies=self.get_cookies(**kwargs),
+        **self.requests_extra_kwargs,
     )
-    t = r.text
-    j_raw = t.split(
-        &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
-    )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+
+    j_raw = self.__extract_tag_contents(r.text)
     return json.loads(j_raw)[&#34;props&#34;][&#34;pageProps&#34;][&#34;musicInfo&#34;]</code></pre>
 </details>
 </dd>
+<dt id="TikTokApi.tiktok.TikTokApi.get_music_object_full_by_api"><code class="name flex">
+<span>def <span class="ident">get_music_object_full_by_api</span></span>(<span>self, id, **kwargs)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns a music object for a specific sound id, but using the API rather than HTML requests.</p>
+<h2 id="parameters">Parameters</h2>
+<dl>
+<dt><strong><code>id</code></strong> :&ensp;<code>The sound id to get the object for</code></dt>
+<dd>This can be found by using other methods.</dd>
+</dl></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_music_object_full_by_api(self, id, **kwargs):
+    &#34;&#34;&#34;Returns a music object for a specific sound id, but using the API rather than HTML requests.
+
+    Parameters
+    ----------
+    id: The sound id to get the object for
+        This can be found by using other methods.
+    &#34;&#34;&#34;
+    (
+        region,
+        language,
+        proxy,
+        maxCount,
+        did,
+    ) = self.__process_kwargs__(kwargs)
+    kwargs[&#34;custom_did&#34;] = did
+
+    api_url = &#34;{}node/share/music/-{}?{}&#34;.format(
+        BASE_URL, id, self.__add_new_params__()
+    )
+    res = self.get_data(url=api_url, **kwargs)
+    return res[&#39;musicInfo&#39;]</code></pre>
+</details>
+</dd>
 <dt id="TikTokApi.tiktok.TikTokApi.get_music_title"><code class="name flex">
 <span>def <span class="ident">get_music_title</span></span>(<span>self, id, **kwargs)</span>
 </code></dt>
@@ -4433,11 +4531,10 @@ <h2 id="parameters">Parameters</h2>
         },
         proxies=self.__format_proxy(kwargs.get(&#34;proxy&#34;, None)),
         cookies=self.get_cookies(**kwargs),
+        **self.requests_extra_kwargs,
     )
     t = r.text
-    j_raw = t.split(
-        &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
-    )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+    j_raw = self.__extract_tag_contents(r.text)
 
     music_object = json.loads(j_raw)[&#34;props&#34;][&#34;pageProps&#34;][&#34;musicInfo&#34;]
     if not music_object.get(&#34;title&#34;, None):
@@ -4447,7 +4544,7 @@ <h2 id="parameters">Parameters</h2>
 </details>
 </dd>
 <dt id="TikTokApi.tiktok.TikTokApi.get_recommended_tiktoks_by_video_id"><code class="name flex">
-<span>def <span class="ident">get_recommended_tiktoks_by_video_id</span></span>(<span>self, id, count=30, minCursor=0, maxCursor=0, **kwargs) ‑> dict</span>
+<span>def <span class="ident">get_recommended_tiktoks_by_video_id</span></span>(<span>self, id, count=30, **kwargs) ‑> dict</span>
 </code></dt>
 <dd>
 <div class="desc"><p>Returns a dictionary listing reccomended TikToks for a specific TikTok video.</p>
@@ -4455,14 +4552,14 @@ <h2 id="parameters">Parameters</h2>
 <dl>
 <dt><strong><code>id</code></strong> :&ensp;<code>The id</code> of <code>the video to get suggestions for</code></dt>
 <dd>Can be found using other methods</dd>
+<dt><strong><code>count</code></strong> :&ensp;<code>The count</code> of <code>results you want to return</code></dt>
+<dd>&nbsp;</dd>
 </dl></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def get_recommended_tiktoks_by_video_id(
-    self, id, count=30, minCursor=0, maxCursor=0, **kwargs
-) -&gt; dict:
+<pre><code class="python">def get_recommended_tiktoks_by_video_id(self, id, count=30, **kwargs) -&gt; dict:
     &#34;&#34;&#34;Returns a dictionary listing reccomended TikToks for a specific TikTok video.
 
 
@@ -4470,6 +4567,7 @@ <h2 id="parameters">Parameters</h2>
     ----------
     id: The id of the video to get suggestions for
         Can be found using other methods
+    count: The count of results you want to return
     &#34;&#34;&#34;
     (
         region,
@@ -4493,8 +4591,6 @@ <h2 id="parameters">Parameters</h2>
             &#34;count&#34;: realCount,
             &#34;id&#34;: 1,
             &#34;secUid&#34;: &#34;&#34;,
-            &#34;maxCursor&#34;: maxCursor,
-            &#34;minCursor&#34;: minCursor,
             &#34;sourceType&#34;: 12,
             &#34;appId&#34;: 1233,
             &#34;region&#34;: region,
@@ -4505,9 +4601,9 @@ <h2 id="parameters">Parameters</h2>
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
 
-        res = self.getData(url=api_url, **kwargs)
+        res = self.get_data(url=api_url, **kwargs)
 
-        for t in res.get(&#34;items&#34;, []):
+        for t in res.get(&#34;itemList&#34;, []):
             response.append(t)
 
         if not res[&#34;hasMore&#34;] and not first:
@@ -4515,7 +4611,6 @@ <h2 id="parameters">Parameters</h2>
             return response[:count]
 
         realCount = count - len(response)
-        maxCursor = res[&#34;maxCursor&#34;]
 
         first = False
 
@@ -4557,6 +4652,7 @@ <h2 id="parameters">Parameters</h2>
         proxies=self.__format_proxy(
             kwargs.get(&#34;proxy&#34;, None), cookies=self.get_cookies(**kwargs)
         ),
+        **self.requests_extra_kwargs,
     )
     try:
         return r.text.split(&#39;&#34;secUid&#34;:&#34;&#39;)[1].split(&#39;&#34;,&#34;secret&#34;:&#39;)[0]
@@ -4609,9 +4705,8 @@ <h2 id="parameters">Parameters</h2>
     api_url = &#34;{}node/share/discover?{}&amp;{}&#34;.format(
         BASE_URL, self.__add_new_params__(), urlencode(query)
     )
-
     res = []
-    for x in self.getData(url=api_url, **kwargs)[&#34;body&#34;][1][&#34;exploreList&#34;]:
+    for x in self.get_data(url=api_url, **kwargs)[&#34;body&#34;][1][&#34;exploreList&#34;]:
         res.append(x[&#34;cardItem&#34;])
     return res[:count]</code></pre>
 </details>
@@ -4715,7 +4810,7 @@ <h2 id="parameters">Parameters</h2>
     )
 
     res = []
-    for x in self.getData(url=api_url, **kwargs)[&#34;body&#34;][2][&#34;exploreList&#34;]:
+    for x in self.get_data(url=api_url, **kwargs)[&#34;body&#34;][2][&#34;exploreList&#34;]:
         res.append(x[&#34;cardItem&#34;])
     return res[:count]</code></pre>
 </details>
@@ -4814,9 +4909,9 @@ <h2 id="parameters">Parameters</h2>
     api_url = &#34;{}node/share/discover?{}&amp;{}&#34;.format(
         BASE_URL, self.__add_new_params__(), urlencode(query)
     )
-
+    print(api_url)
     res = []
-    for x in self.getData(url=api_url, **kwargs)[&#34;body&#34;][0][&#34;exploreList&#34;]:
+    for x in self.get_data(url=api_url, **kwargs)[&#34;body&#34;][0][&#34;exploreList&#34;]:
         res.append(x[&#34;cardItem&#34;])
     return res[:count]</code></pre>
 </details>
@@ -4917,13 +5012,12 @@ <h2 id="parameters">Parameters</h2>
         },
         proxies=self.__format_proxy(kwargs.get(&#34;proxy&#34;, None)),
         cookies=self.get_cookies(**kwargs),
+        **self.requests_extra_kwargs,
     )
 
     t = r.text
     try:
-        j_raw = t.split(
-            &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
-        )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+        j_raw = self.__extract_tag_contents(r.text)
     except IndexError:
         if not t:
             logging.error(&#34;TikTok response is empty&#34;)
@@ -4934,9 +5028,7 @@ <h2 id="parameters">Parameters</h2>
     data = json.loads(j_raw)[&#34;props&#34;][&#34;pageProps&#34;]
 
     if data[&#34;serverCode&#34;] == 404:
-        raise TikTokNotFoundError(
-            &#34;TikTok with that url doesn&#39;t exist&#34;.format(username)
-        )
+        raise TikTokNotFoundError(&#34;TikTok with that url doesn&#39;t exist&#34;)
 
     return data</code></pre>
 </details>
@@ -4979,7 +5071,7 @@ <h2 id="parameters">Parameters</h2>
         BASE_URL, self.__add_new_params__(), urlencode(query)
     )
 
-    return self.getData(url=api_url, **kwargs)</code></pre>
+    return self.get_data(url=api_url, **kwargs)</code></pre>
 </details>
 </dd>
 <dt id="TikTokApi.tiktok.TikTokApi.get_tiktok_by_url"><code class="name flex">
@@ -5071,14 +5163,13 @@ <h2 id="parameters">Parameters</h2>
         },
         proxies=self.__format_proxy(kwargs.get(&#34;proxy&#34;, None)),
         cookies=self.get_cookies(**kwargs),
+        **self.requests_extra_kwargs,
     )
 
     t = r.text
 
     try:
-        j_raw = t.split(
-            &#39;&lt;script id=&#34;__NEXT_DATA__&#34; type=&#34;application/json&#34; crossorigin=&#34;anonymous&#34;&gt;&#39;
-        )[1].split(&#34;&lt;/script&gt;&#34;)[0]
+        j_raw = self.__extract_tag_contents(r.text)
     except IndexError:
         if not t:
             logging.error(&#34;Tiktok response is empty&#34;)
@@ -5367,6 +5458,7 @@ <h2 id="parameters">Parameters</h2>
             &#34;user-agent&#34;: &#34;okhttp&#34;,
         },
         proxies=self.__format_proxy(proxy),
+        **self.requests_extra_kwargs,
     )
 
     if r.text[0] == &#34;{&#34;:
@@ -5531,7 +5623,7 @@ <h2 id="parameters">Parameters</h2>
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
 
-        res = self.getData(url=api_url, **kwargs)
+        res = self.get_data(url=api_url, **kwargs)
 
         try:
             res[&#34;itemList&#34;]
@@ -5658,7 +5750,7 @@ <h2 id="parameters">Parameters</h2>
         )
     )
 
-    return self.getData(url=api_url, **kwargs)</code></pre>
+    return self.get_data(url=api_url, **kwargs)</code></pre>
 </details>
 </dd>
 <dt id="TikTokApi.tiktok.TikTokApi.user_posts"><code class="name flex">
@@ -5729,7 +5821,7 @@ <h2 id="parameters">Parameters</h2>
             BASE_URL, self.__add_new_params__(), urlencode(query)
         )
 
-        res = self.getData(url=api_url, **kwargs)
+        res = self.get_data(url=api_url, **kwargs)
 
         if &#34;itemList&#34; in res.keys():
             for t in res[&#34;itemList&#34;]:
@@ -5785,6 +5877,7 @@ <h4><code><a title="TikTokApi.tiktok.TikTokApi" href="#TikTokApi.tiktok.TikTokAp
 <li><code><a title="TikTokApi.tiktok.TikTokApi.get_instance" href="#TikTokApi.tiktok.TikTokApi.get_instance">get_instance</a></code></li>
 <li><code><a title="TikTokApi.tiktok.TikTokApi.get_music_object" href="#TikTokApi.tiktok.TikTokApi.get_music_object">get_music_object</a></code></li>
 <li><code><a title="TikTokApi.tiktok.TikTokApi.get_music_object_full" href="#TikTokApi.tiktok.TikTokApi.get_music_object_full">get_music_object_full</a></code></li>
+<li><code><a title="TikTokApi.tiktok.TikTokApi.get_music_object_full_by_api" href="#TikTokApi.tiktok.TikTokApi.get_music_object_full_by_api">get_music_object_full_by_api</a></code></li>
 <li><code><a title="TikTokApi.tiktok.TikTokApi.get_music_title" href="#TikTokApi.tiktok.TikTokApi.get_music_title">get_music_title</a></code></li>
 <li><code><a title="TikTokApi.tiktok.TikTokApi.get_recommended_tiktoks_by_video_id" href="#TikTokApi.tiktok.TikTokApi.get_recommended_tiktoks_by_video_id">get_recommended_tiktoks_by_video_id</a></code></li>
 <li><code><a title="TikTokApi.tiktok.TikTokApi.get_secuid" href="#TikTokApi.tiktok.TikTokApi.get_secuid">get_secuid</a></code></li>
diff --git a/docs/tiktokuser.html b/docs/TikTokApi/tiktokuser.html
similarity index 100%
rename from docs/tiktokuser.html
rename to docs/TikTokApi/tiktokuser.html
diff --git a/docs/utilities.html b/docs/TikTokApi/utilities.html
similarity index 100%
rename from docs/utilities.html
rename to docs/TikTokApi/utilities.html
diff --git a/setup.py b/setup.py
index f582aacb..55c14223 100644
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,7 @@
 setuptools.setup(
     name="TikTokApi",
     packages=["TikTokApi"],
-    version="3.9.5",
+    version="3.9.6",
     license="MIT",
     description="The Unofficial TikTok API Wrapper in Python 3.",
     author="David Teather",


Test patch:
diff --git a/tests/test_discover.py b/tests/test_discover.py
index 7f0c3a23..ee9a2ed0 100644
--- a/tests/test_discover.py
+++ b/tests/test_discover.py
@@ -6,6 +6,6 @@
 )
 
 
-def test_trending():
-    assert len(api.discoverHashtags()) > 0
-    assert len(api.discoverMusic()) > 0
+def test_discover_trending():
+    assert len(api.discover_hashtags()) > 0
+    assert len(api.discover_music()) > 0
diff --git a/tests/test_getMusicObjectFullByApi.py b/tests/test_getMusicObjectFullByApi.py
new file mode 100644
index 00000000..c1472e79
--- /dev/null
+++ b/tests/test_getMusicObjectFullByApi.py
@@ -0,0 +1,12 @@
+from TikTokApi import TikTokApi
+import os
+
+api = TikTokApi.get_instance(
+    custom_verifyFp=os.environ.get("verifyFp", None), use_test_endpoints=True
+)
+
+
+def test_get_music_object_full_by_api():
+    music_id = "6819262113299565318"
+    res = api.get_music_object_full_by_api(music_id)
+    assert res['music']['id'] == music_id
diff --git a/tests/test_suggested.py b/tests/test_suggested.py
index bd616f9b..c679bb63 100644
--- a/tests/test_suggested.py
+++ b/tests/test_suggested.py
@@ -7,12 +7,12 @@
 
 
 def test_suggested():
-    assert len(api.getSuggestedHashtagsbyID()) > 0
-    assert len(api.getSuggestedMusicbyID()) > 0
-    assert len(api.getSuggestedUsersbyID()) > 0
+    assert len(api.get_suggested_users_by_id()) > 0
+    assert len(api.get_suggested_hashtags_by_id()) > 0
+    assert len(api.get_suggested_users_by_id()) > 0
 
 
 def test_suggested_crawlers():
-    assert len(api.getSuggestedUsersbyIDCrawler(count=50)) == 50
-    assert len(api.getSuggestedHashtagsbyIDCrawler(count=10)) > 0
-    assert len(api.getSuggestedMusicIDCrawler(count=10)) > 0
+    assert len(api.get_suggested_users_by_id_crawler(count=50)) == 50
+    assert len(api.get_suggested_hashtags_by_id_crawler(count=10)) > 0
+    assert len(api.get_suggested_music_id_crawler(count=10)) > 0