I spent two hours fighting a 403 that had nothing to do with my password.
This week I wired my brokerage account to an automation so my portfolio can act on its own rules. The idea is simple: the system scores every holding, and when a position fails the test, it gets rotated. No daily decisions, no emotion, no 'I'll check it Monday.' I'd been building the strategy for months — the scoring model, the rotation rules, the review gate. The last mile was the plumbing, and it fought back.
The first wall was the token exchange. My code got a Cloudflare 403 — error code 1010, which blocks Python's default HTTP client. The fix was embarrassingly simple: shell out to curl with a browser user-agent. Ten seconds of work once I stopped blaming my key.
The second wall was the one I should have seen first. The broker's authorize endpoint rejected the standard client ID entirely — it only accepts whitelisted agent identities. I burned the first hour re-checking credentials that were never the problem. The real issue was the client's reputation, not my password. When auth fails, I blame the key before I question the client.
The fix took an afternoon once I knew what to look for: curl for the token exchange, the whitelisted agent ID through the OAuth flow, and the whole thing now runs on a schedule. The portfolio syncs, the rules evaluate, trades queue for my review. The machine proposes, I dispose. Two hours of my own assumption cost more than the API ever did.
The lesson: 401/403 isn't always your key — sometimes it's the client's reputation. The expensive mistake was mine, not the API's: I assumed the standard path would work and spent two hours proving it instead of checking the client's standing first.
Tools I leaned on: Questrade's API (the broker), curl with a browser user-agent (the token exchange), and the OAuth flow with a whitelisted agent ID.
Next week: the real cost of my content machine — what four videos a week actually cost, line by line.