we-promise/sure · warning · Provider::Trading212::RateLimitError
Trading 212 rate limit exceeded. Please wait before retrying
Error message
Trading 212 rate limit exceeded. Please wait before retrying.
What it means
Provider::Trading212::RateLimitError raised in handle_response when the Trading 212 API answers HTTP 429. Trading 212 enforces roughly 1 request/second per connection and tighter limits on history endpoints (the client even sleeps 10s between history pages), so bursts trigger this response.
Source
Thrown at app/models/provider/trading212.rb:137
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
delay = [ 2**attempt, 30 ].min
DebugLogEntry.capture(View on GitHub (pinned to e69894adb9)
Solutions
- Wait before retrying: back off at least 1–10 seconds (history endpoints need ~10s between calls) and use exponential backoff
- Serialize requests per API key (a mutex or single worker) so concurrent jobs don't burst past ~1 req/s
- Rescue Provider::Trading212::RateLimitError separately from AuthenticationError and schedule a delayed retry (e.g. retry_job wait: 30) instead of failing the sync
- Reduce page volume by keeping the built-in PAGE_LIMIT/MAX_PAGES pagination rather than fetching unpaginated
Example fix
// before begin client.fetch_account_summary rescue Provider::Trading212::Error retry # tight loop -> 429 loop end // after begin client.fetch_account_summary rescue Provider::Trading212::RateLimitError sleep 30 retry rescue Provider::Trading212::AuthenticationError raise # do not retry auth failures end
Defensive patterns
Strategy: retry
Try / catch
begin client.fetch_positions rescue Provider::Trading212::RateLimitError sleep 30 * attempt # exponential-ish backoff, cap attempts retry if (attempt += 1) <= 3 rescue Provider::Trading212::AuthenticationError raise end
Prevention
- Serialize Trading 212 requests per API key (single worker/mutex) to stay under ~1 req/s
- Keep the built-in 10s sleep between history pages — history endpoints allow only ~6 req/min
- Rescue RateLimitError distinctly from AuthenticationError so backoff applies only where it helps
When it happens
Trigger: Calling fetch_account_summary/fetch_positions in quick succession; parallel jobs syncing the same or multiple Trading 212 accounts; ignoring the pacing in fetch_all_pages (which sleeps 10s per page because history endpoints allow ~6 req/min); an immediate retry after a previous request.
Common situations: Background jobs overlapping for different users on the same API key; manual console testing while a sync job runs; retry logic without backoff hammering the API.
Related errors
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/c6004224fb860fa0.
Report an issue: GitHub.