{"record":{"id":"265602a4ff909392","repo":"ytdl-org/youtube-dl","slug":"s-265602","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"exception","errorClass":"ExtractorError","httpStatus":403,"severity":"error","filePath":"youtube_dl/extractor/sonyliv.py","lineNumber":68,"sourceCode":"    }]\n    _GEO_COUNTRIES = ['IN']\n    _TOKEN = None\n\n    def _call_api(self, version, path, video_id):\n        headers = {}\n        if self._TOKEN:\n            headers['security_token'] = self._TOKEN\n        try:\n            return self._download_json(\n                'https://apiv2.sonyliv.com/AGL/%s/A/ENG/WEB/%s' % (version, path),\n                video_id, headers=headers)['resultObj']\n        except ExtractorError as e:\n            if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403:\n                message = self._parse_json(\n                    e.cause.read().decode(), video_id)['message']\n                if message == 'Geoblocked Country':\n                    self.raise_geo_restricted(countries=self._GEO_COUNTRIES)\n                raise ExtractorError(message)\n            raise\n\n    def _real_initialize(self):\n        self._TOKEN = self._call_api('1.4', 'ALL/GETTOKEN', None)\n\n    def _real_extract(self, url):\n        video_id = self._match_id(url)\n        content = self._call_api(\n            '1.5', 'IN/CONTENT/VIDEOURL/VOD/' + video_id, video_id)\n        if content.get('isEncrypted'):\n            raise ExtractorError('This video is DRM protected.', expected=True)\n        dash_url = content['videoURL']\n        headers = {\n            'x-playback-session-id': '%s-%d' % (uuid.uuid4().hex, time.time() * 1000)\n        }\n        formats = self._extract_mpd_formats(\n            dash_url, video_id, mpd_id='dash', headers=headers, fatal=False)\n        formats.extend(self._extract_m3u8_formats(","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/sonyliv.py#L50-L86","documentation":"SonyLIVIE._call_api wraps _download_json against apiv2.sonyliv.com; on HTTP 403 it parses the body's 'message' field. If the message is 'Geoblocked Country' it raises geo-restriction, otherwise it re-raises the API's message as a plain (unexpected) ExtractorError. Typical messages cover invalid/expired security tokens and unauthorized content.","triggerScenarios":"Any AGL API call (ALL/GETTOKEN, IN/CONTENT/VIDEOURL/VOD/<id>) answered with HTTP 403 and a JSON body: message 'Geoblocked Country' from non-Indian IPs, or token-invalid/auth messages when the security_token header obtained in _real_initialize has expired or failed.","commonSituations":"Using SonyLIV outside India without a VPN (India-only service); the token endpoint itself returning 403 so every later call fails with a token message; Sony rotating their API in ways that break token bootstrap on older youtube-dl versions.","solutions":["If the message says geoblocked, use an Indian VPN/proxy - there is no other workaround.","Update to the latest yt-dlp; SonyLIV's token/bootstrap flow changes frequently and old extractors get 403 everywhere.","Retry after clearing the cache so a fresh security token is minted (transient token failures happen).","If the token call itself 403s, the API contract changed - needs extractor fix, not user action."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    extract(url)\nexcept GeoRestrictedError:\n    retry_via_in_proxy()\nexcept ExtractorError as e:\n    if 'token' in str(e).lower():\n        clear_cache(); retry_once()\n    else:\n        raise","preventionTips":["Use Indian egress for all SonyLIV downloads.","Update yt-dlp before reporting - token bootstrap changes often.","Clear cache to force a fresh security token on strange 403s."],"tags":["sonyliv","geo-restricted","http-403","token","extractor"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}