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_retriesView on GitHub (pinned to e69894adb9)
Solutions
- 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)
- Re-enter both credentials in the app's provider settings and retry the connection — stale regenerated keys are the most common cause
- If using demo, instantiate with environment: "demo" and use a key generated in the demo app
- 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
- Treat 401/403 as terminal: mark the connection for reconnection, don't retry
- Check credentials with a cheap fetch_account_summary call right after the user saves them
- Alert the user when Trading 212 regenerates keys, since stored secrets go stale immediately
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
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- unauthorized
- Authentication failed (#{operation}): HTTP #{response.status
- unauthorized
- unauthorized
- bad_request
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/65df956b26472457.
Report an issue: GitHub.