The error#
After the last retry, make_request does this:
raise InvalidJSONException()InvalidJSONException does not define __init__. TikTokException.__init__ requires raw_response and message. A call with no arguments does not match that signature, so constructing the exception fails before the docstring (TikTok returned invalid JSON.) can become the message.
The log line just before the raise is:
Failed to decode json response: {result}Earlier retries log Failed a request, retrying ({n}/{retries}) and sleep. exponential_backoff sleeps 2**retry_count seconds. Otherwise the sleep is 1 second.
What triggers it#
json.loads raised JSONDecodeError on the script result, and retry_count == retries. An empty string does not reach this branch. That string raises EmptyResponseException first.
How to confirm#
The traceback names InvalidJSONException and TypeError from TikTokException.__init__, and the log contains Failed to decode json response. You will not see a clean InvalidJSONException: TikTok returned invalid JSON. from this raise, because the constructor is not called the way the class requires.
Fixes#
The body that failed to parse is in that log line. If it is HTML, you are on the bot-detection path described by EmptyResponseException, even though this branch is the JSON decoder. The retries already happened inside make_request. Catching InvalidJSONException does not run unless the constructor succeeds. Catch Exception if you need the TypeError too, and read the log line for the body.
SocialScrape#
Profile is GET /v1/tiktok/profile. Video is GET /v1/tiktok/video. Transcript is GET /v1/tiktok/video/transcript: TikTok's captions when they exist, otherwise AI transcription of the audio.
Failed requests cost 0 credits. New accounts get 100 credits on signup, no card.