{"record":{"id":"3da8fbb1d2bcf72f","repo":"OpenBB-finance/OpenBB","slug":"unauthorized-intrinio-request-result-get-mess","errorCode":null,"errorMessage":"Unauthorized Intrinio request -> {result.get('message')}","messagePattern":"Unauthorized Intrinio request -> (.+?)","errorType":"exception","errorClass":"UnauthorizedError","httpStatus":null,"severity":"error","filePath":"openbb_platform/providers/intrinio/openbb_intrinio/models/company_news.py","lineNumber":225,"sourceCode":"        api_key = credentials.get(\"intrinio_api_key\") if credentials else \"\"\n\n        base_url = \"https://api-v2.intrinio.com/companies\"\n        ignore = (\n            [\"symbol\", \"page_size\", \"is_spam\"]\n            if not query.source or query.source == \"yahoo\"\n            else [\"symbol\", \"page_size\"]\n        )\n        query_str = get_querystring(query.model_dump(by_alias=True), ignore)\n        symbols = query.symbol.split(\",\") if query.symbol else []\n        news: list = []\n\n        async def callback(response, session):\n            \"\"\"Response callback.\"\"\"\n            result = await response.json()\n\n            if isinstance(result, dict) and \"error\" in result:\n                if \"api key\" in result.get(\"message\", \"\").lower():\n                    raise UnauthorizedError(\n                        f\"Unauthorized Intrinio request -> {result.get('message')}\"\n                    )\n                raise OpenBBError(f\"Error in Intrinio request -> {result}\")\n\n            symbol = response.url.parts[-2]\n            _data = result.get(\"news\", [])\n            data = []\n            data.extend([{\"symbol\": symbol, **d} for d in _data])\n            articles = len(data)\n            next_page = result.get(\"next_page\")\n            # query.limit can be None...\n            limit = query.limit or 2500\n            while next_page and limit > articles:\n                url = (\n                    f\"{base_url}/{symbol}/news?{query_str}\"\n                    + f\"&page_size={query.limit}&api_key={api_key}&next_page={next_page}\"\n                )\n                result = await get_data(url, session=session, **kwargs)","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/providers/intrinio/openbb_intrinio/models/company_news.py#L207-L243","documentation":"Raised inside the async response callback of IntrinioCompanyNewsFetcher when the Intrinio API returns a JSON dict containing an 'error' key whose 'message' mentions 'api key'. It maps the provider response to OpenBB's UnauthorizedError, signaling an authentication failure (missing, malformed, invalid, or insufficient-plan key) rather than a generic API error.","triggerScenarios":"Any GET to api-v2.intrinio.com .../news with a bad credential: intrinio_api_key not set in credentials, an expired/free key, a typo'd key, or a key whose plan does not include the news endpoint. Detection is substring-based: 'api key' must appear in result['message'].lower().","commonSituations":"First run after installing the intrinio provider without obb.account credentials; CI environments where the key env var is not exported; key rotated on Intrinio's dashboard but not updated locally; free-tier key hitting a paid endpoint.","solutions":["Set the credential: obb.account.credentials.intrinio_api_key = '<key>' (or the INTRINIO_API_KEY environment variable), then retry","Verify the key directly: curl 'https://api-v2.intrinio.com/companies/AAPL/news?api_key=<key>' and confirm no error payload","Check your Intrinio subscription plan includes the News API product","Catch UnauthorizedError separately from OpenBBError to surface a 'fix your key' message in your app instead of a generic failure"],"exampleFix":"# before\nobb.account.credentials.intrinio_api_key = \"\"  # empty key\nnews = await obb.news.company_news(provider=\"intrinio\", symbol=\"AAPL\").to_df()\n\n# after\nobb.account.credentials.intrinio_api_key = os.environ[\"INTRINIO_API_KEY\"]\nnews = await obb.news.company_news(provider=\"intrinio\", symbol=\"AAPL\").to_df()","handlingStrategy":"try-catch","validationCode":"def has_intrinio_key() -> bool:\n    creds = obb.account.credentials\n    return bool(getattr(creds, \"intrinio_api_key\", None))","typeGuard":"from openbb_core.provider.utils.errors import UnauthorizedError\n\ndef is_unauthorized(err: BaseException) -> bool:\n    return isinstance(err, UnauthorizedError) or \"Unauthorized Intrinio request\" in str(err)","tryCatchPattern":"from openbb_core.provider.utils.errors import UnauthorizedError, OpenBBError\n\ntry:\n    news = await obb.news.company_news(provider=\"intrinio\", symbol=\"AAPL\")\nexcept UnauthorizedError as e:\n    # auth problem: fix credentials, do not retry\n    raise RuntimeError(f\"Check intrinio_api_key: {e}\") from e\nexcept OpenBBError:\n    raise","preventionTips":["Set intrinio_api_key once at startup and fail fast if missing","Separate UnauthorizedError from OpenBBError in except clauses","Smoke-test the key against a cheap Intrinio endpoint on boot"],"tags":["authentication","api-key","intrinio","news","credentials"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}