HKUDS/Vibe-Trading · error · Trading212APIError

Trading 212 API returned HTTP {response.status_code}: {_erro

Error message

Trading 212 API returned HTTP {response.status_code}: {_error_message(response)}

What it means

Raised by _request for any HTTP response with status >= 400 that is not 401/403. The message includes the status code and _error_message(response), which extracts the API's own error payload when the body is JSON, so you can see the server-side reason.

Source

Thrown at agent/src/trading/connectors/trading212/sdk.py:432

        auth = (config.api_key, config.api_secret)
    else:
        headers["Authorization"] = config.api_key
    try:
        response = requests.request(
            method.upper(),
            url,
            headers=headers,
            auth=auth,
            params=dict(params or {}),
            timeout=config.timeout,
        )
    except requests.RequestException as exc:
        raise Trading212APIError(f"Trading 212 request failed: {exc}") from exc

    if response.status_code in (401, 403):
        raise Trading212APIError("Trading 212 API authentication failed: check api_key/api_secret.")
    if response.status_code >= 400:
        raise Trading212APIError(f"Trading 212 API returned HTTP {response.status_code}: {_error_message(response)}")
    if not response.content:
        return None
    try:
        return response.json()
    except ValueError as exc:
        raise Trading212APIError("Trading 212 API returned invalid JSON.") from exc


def _error_message(response: requests.Response) -> str:
    try:
        payload = response.json()
    except ValueError:
        return response.text.strip() or response.reason or "request failed"
    if isinstance(payload, Mapping):
        for key in ("message", "error", "detail", "title"):
            value = payload.get(key)
            if value:
                return str(value)

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Read the status code and _error_message body in the message — fix params/path accordingly
  2. For 429, slow down polling and add backoff between calls
  3. For 5xx, retry with exponential backoff or check the Trading 212 status page
  4. For 404, verify base_url and the endpoint path are current for your API version

Example fix

# before
while True:
    positions = get_positions(config)  # hammers API -> 429
# after
import time
while True:
    try:
        positions = get_positions(config)
    except Trading212APIError as exc:
        time.sleep(30)  # backoff, then retry
        continue
    time.sleep(60)
Defensive patterns

Strategy: retry

Try / catch

import time
for attempt in range(3):
    try:
        data = get_positions(config)
        break
    except Trading212APIError as exc:
        if "HTTP 429" in str(exc) or "HTTP 5" in str(exc):
            time.sleep(2 ** attempt)
            continue
        raise

Prevention

When it happens

Trigger: Any _get call hitting 400 (bad query params), 404 (wrong path/base_url), 429 (rate limited), or 5xx (server error) from the Trading 212 API.

Common situations: Rate limiting on polling loops calling get_positions frequently; base_url with a stale API path after a version change; malformed params passed by caller code; transient 5xx during API incidents.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/489cfc35b1815981. Report an issue: GitHub.