we-promise/sure · critical · Provider::Trading212::AuthenticationError

Trading 212 authentication failed (#{response.code}). Check

Error message

Trading 212 authentication failed (#{response.code}). Check your API key.

What it means

Provider::Trading212::AuthenticationError raised in handle_response when the Trading 212 REST API answers HTTP 401 or 403. It means the Basic auth header (Base64 api_key:api_secret) was rejected: wrong credentials, regenerated key, or API access disabled on the account.

Source

Thrown at app/models/provider/trading212.rb:135

      end

      items
    end

    def extract_cursor(next_page_path)
      uri = URI.parse("https://placeholder#{next_page_path}")
      params = URI.decode_www_form(uri.query.to_s).to_h
      params["cursor"]
    rescue URI::InvalidURIError
      nil
    end

    def handle_response(response)
      case response.code
      when 200, 201
        response.parsed_response
      when 401, 403
        raise AuthenticationError, "Trading 212 authentication failed (#{response.code}). Check your API key."
      when 429
        raise RateLimitError, "Trading 212 rate limit exceeded. Please wait before retrying."
      else
        raise ApiError.new(
          "Trading 212 API error (status #{response.code})",
          status_code: response.code,
          response_body: response.body
        )
      end
    end

    def with_retries(label, max_retries: 3)
      attempt = 0
      begin
        attempt += 1
        yield
      rescue *RETRYABLE_ERRORS => e
        raise if attempt >= max_retries

View on GitHub (pinned to e69894adb9)

Solutions

  1. Verify the api_key/api_secret pair in Trading 212 under Settings > API and confirm API access is enabled for that environment (live vs demo must match the environment argument)
  2. Re-enter both credentials in the app's provider settings and retry the connection — stale regenerated keys are the most common cause
  3. If using demo, instantiate with environment: "demo" and use a key generated in the demo app
  4. Handle this error in sync jobs by marking the account connection as 'needs reconnection' rather than retrying — credentials will not fix themselves

Example fix

// before
summary = client.fetch_account_summary

// after
begin
  summary = client.fetch_account_summary
rescue Provider::Trading212::AuthenticationError
  account_provider.update!(status: "reauth_required")
  notify_user("Reconnect your Trading 212 account")
end
Defensive patterns

Strategy: try-catch

Try / catch

begin
  client.fetch_account_summary
rescue Provider::Trading212::AuthenticationError
  account_provider.update!(status: "reauth_required")
  notify_user("Trading 212 credentials rejected — reconnect the account")
  # never retry: credentials are stale until a human acts
end

Prevention

When it happens

Trigger: Any GET via the provider — /equity/account/summary, /equity/positions, /equity/history/orders pagination — where Trading 212 returns 401 (bad credentials) or 403 (key valid but not entitled, e.g. API not enabled or read-only restriction).

Common situations: User regenerated the Trading 212 API key in the app so the stored secret is now stale; the API key was created for the demo environment but the client is set to live (or vice versa); Trading 212 revoked API access for the account; key/secret swapped when copying.

Understand the failure class

Related errors


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/65df956b26472457. Report an issue: GitHub.