How TradeLoop Keeps Your Connected Accounts Authenticated Without You Lifting a Finger
The Problem: Silent Token Expiry
OAuth access tokens expire. The tokens for the accounts a trader connects — a brokerage data feed, a Google Sheets trade journal, a Notion thesis workspace — typically last anywhere from an hour to a day. When one expires mid-task, your AI agent gets a 401 Unauthorized, the tool call fails, and the agent either halts or produces a confusing error right as you're trying to log a fill or pull a position.
The naive fix is to refresh the token when the error happens. The problem: by the time the agent sees the 401, it's already mid-task. Recovering from a mid-task auth failure is hard — the agent may have already taken steps that are awkward to unwind, like writing half a journal entry.
TradeLoop's approach is different: refresh tokens *proactively*, before they expire, so the agent never encounters a stale credential in the first place.
How the Token Keeper Works
When the TradeLoop daemon starts, it spawns a background goroutine called the token keeper. It runs a keep-alive cycle on a fixed interval and handles three layers of freshness:
Layer 1: Supabase session (your TradeLoop login)
The daemon checks whether your Supabase refresh token is within 15 minutes of expiry. If so, it refreshes via the Supabase token endpoint and writes the new session to disk. If the refresh token itself has permanently expired, the daemon logs a warning and sets a flag so the CLI surfaces a clear tradeloop login prompt — no cryptic 401s.
Layer 2: Provider OAuth tokens (journal, broker, research accounts)
Every 5 minutes, the daemon iterates over all stored OAuth tokens and checks each one's expires_at field. Any token within 10 minutes of expiry gets refreshed immediately via the TradeLoop vault API, which handles the provider-specific refresh grant flow. The refreshed token is written back to disk encrypted.
Token keeper cycle (every 5 minutes):
├── Check Supabase session expiry (buffer: 15 min)
│ └── If expiring → refresh via Supabase token endpoint
├── For each connected-account OAuth token:
│ └── If expires_at < now + 10 min → refresh via vault API
└── Full vault sync (throttled to every 30 minutes)Layer 3: Periodic vault sync
Every 30 minutes, the daemon does a full pull from the TradeLoop vault. This catches credentials updated from another device — re-authorize your journal on your laptop, and your desktop picks up the new tokens automatically.
What Happens at Tool Call Time
When your agent invokes a tool that needs a connected account — say, writing a fill to your Google Sheets journal — the daemon spawns the skill process and injects the current access token just before execution:
SHEETS_ACCESS_TOKEN=ya29.current-fresh-token # injected by daemon
SHEETS_REFRESH_TOKEN=1//... # injected by daemon
TRADELOOP_USER_JWT=eyJ... # injected by daemonThe skill reads these variables and calls the API. It never touches the credential store and never implements refresh logic. By the time it runs, the daemon has already ensured the token is fresh.
Recovery from Permanent Expiry
If a token can't be refreshed — you revoked access, the OAuth app was deleted, the refresh token expired — the daemon marks that provider as requiring re-authorization and surfaces a clear error:
Authentication failed for your journal account. The token may be expired or revoked.
Fix: re-authorize at https://tradeloop.top/connect, then run `tradeloop update` to sync.This message lands in the tool-call result returned to the agent, so it can tell you the next step instead of a generic failure.
The Result
In practice you never think about token expiry. The daemon handles it silently. The only time you see an auth message is when a token has genuinely been revoked and needs human action — and even then the fix is one URL visit and one CLI command, not a debugging session in the middle of logging a trade.
Try TradeLoop for free
Connect 50+ tools to Claude, Cursor, and Windsurf in under 5 minutes. No API keys required to get started.