OpenBB-finance/OpenBB · error · UnauthorizedError

{error.get('code', '')} -> {error.get('message', '')}

Error message

{error.get('code', '')} -> {error.get('message', '')}

What it means

UnauthorizedError raised by the congress.gov bill-info fetcher when the response error code contains 'API_KEY' — the credentials supplied for congress_gov_api_key were rejected. Identical auth semantics to the amendment endpoint: it exists so OpenBB surfaces credential problems distinctly from other upstream errors.

Source

Thrown at openbb_platform/providers/congress_gov/openbb_congress_gov/models/bill_info.py:103

        from openbb_core.app.model.abstract.error import OpenBBError
        from openbb_core.provider.utils.errors import UnauthorizedError
        from openbb_core.provider.utils.helpers import amake_request

        api_key = credentials.get("congress_gov_api_key", "") if credentials else ""
        bill_url = query.bill_url
        if bill_url[0].isnumeric() or (bill_url[0] == "/" and bill_url[1].isnumeric()):
            # If the bill URL starts with a number, assume it's a congress number and construct the URL
            bill_url = (
                "https://api.congress.gov/v3/bill/"
                + f"{bill_url[1:] if bill_url[0] == '/' else bill_url}?format=json"
            )

        url = bill_url + "&api_key=" + api_key
        base_info: dict = await amake_request(url)  # type: ignore

        if isinstance(base_info, dict) and (error := base_info.get("error", {})):
            if "API_KEY" in error.get("code", ""):
                raise UnauthorizedError(
                    f"{error.get('code', '')} -> {error.get('message', '')}"
                )
            raise OpenBBError(f"{error.get('code', '')} -> {error.get('message', '')}")

        base_info = base_info.get("bill", {})
        cosponsors = base_info.get("cosponsors", {})

        if cosponsors.get("count", 0) > 0:
            cosponsors_url = (
                base_info.get("cosponsors", {}).get("url", "") + "&api_key=" + api_key
            )
            cosponsors_response: dict = await amake_request(cosponsors_url)  # type: ignore
            cosponsors_list = cosponsors_response.get("cosponsors", [])
            base_info["cosponsors"] = cosponsors_list

        subjects = base_info.get("subjects", {})

        if subjects.get("count", 0) > 0:

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. Provision the key: obb.account.credentials.set('congress_gov_api_key', '<key>').
  2. Confirm the key independently with a direct API call before blaming OpenBB.
  3. Cache bill-info responses locally to stay under the hourly quota.

Example fix

# before
obb.congress.bill_info(bill_url='119/hr/1')

# after
obb.account.credentials.set('congress_gov_api_key', KEY)
obb.congress.bill_info(bill_url='119/hr/1')
Defensive patterns

Strategy: validation

Validate before calling

key = obb.account.credentials.get('congress_gov_api_key')
if not key:
    raise RuntimeError('congress_gov_api_key missing — set it before querying bills')

Try / catch

from openbb_core.provider.utils.errors import UnauthorizedError

try:
    res = obb.congress.bill_info(bill_url='119/hr/1')
except UnauthorizedError:
    raise SystemExit('Set a valid congress_gov_api_key') from None

Prevention

When it happens

Trigger: Calling CongressBillInfo with a missing, expired, revoked, or quota-exhausted congress_gov_api_key; the key set in a different OpenBB profile than the one running the request.

Common situations: New machine/profile without stored credentials; the 5,000 requests/hour limit hit by scheduled jobs; stale keys after re-registering on api.congress.gov.

Related errors


AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14). Data as JSON: /api/errors/4468a84b1fdef08f. Report an issue: GitHub.