Highlights
Browser profile picking is a per-request knob now. Name the browser and OS you want, and the fingerprint plus headers describe the same thing. Single learned to solve two more defenses this week (SiteGround's SG-Captcha and eBay's Argon2 challenge) without spinning up Browser. And the Dashboard's Activity view now records what you asked for, not the plumbing that ran under it.
What's New
Pick your browser profile per request
Until now, unblocker: true picked one signature (whatever our current default was) and that was it. Now you can name one:
{ "url": "https://example.com", "unblocker": true, "profile": "firefox147" }
or ask for a browser and OS pair:
{ "url": "https://example.com", "unblocker": true, "browser": "Chrome", "os": "Windows 10" }
The API rejects unknown combinations by name and lists what IS available, so a typo can't quietly ship a signature you never asked for.
The full catalogue lives at GET /api/profiles. It's public (no key needed), because it's a capability list, not a secret. As of this writing there are 79 presets across Chrome, Firefox, Edge, Safari, and Tor, on Windows, macOS, Android, and iOS. The Playground reads from the same list, so the dropdown always shows exactly what your code can ask for.
Why it matters: if your target profiles requests by OS, or your team is A/B testing which stack gets past a particular wall, you now hold that variable steady while everything else changes.
Single clears SG-Captcha and eBay proof-of-work
Two defenses that used to force a bounce through Browser now clear on Single. eBay ships its own proof-of-work challenge (an Argon2 puzzle) and SiteGround guards a chunk of the shared-hosting web with SG-Captcha. Both solve without rendering, which means the response comes back in the shape of a single HTTP request and gets priced accordingly.
The defense signal in responses grew too. Browser responses now carry defenses: { present, cleared }, so you can see which vendor sat in front of the page and whether we made it through. Billing follows the same rule: any vendor we clear gets attributed, whatever brand it was. Cloudflare was the only paid solve before this window. Akamai Bot Manager, SG-Captcha, and eBay's challenge now sit next to it.
Activity view rebuilt in the Dashboard
Two columns in the Dashboard's Activity list were showing the wrong thing. HTTP method always read POST on every row (all our endpoints are POST, so the column was a constant that told you nothing). And the client IP on Playground calls recorded where the Playground called from, not the person clicking Run.
Both are fixed. The method column now reads the verb you sent inside the request body. The client IP on Playground rows now reads the browser IP of the signed-in user, carried inside a signed Playground token so an API client can't fake it.
The rest of the view got a rebuild while we were there. The table fits on a laptop without hiding columns, the product column folds into the request line, and the detail panel gained tabs so the request, response, and defense summary each get their own scroll.
Billing: 3D Secure on plan change
If your card issuer required a 3DS confirmation for a plan change (not just at initial subscribe), that step didn't fire and the change silently rolled back. It fires now. If you tried to move plans in the last month and it looked like nothing happened, that's why.
Under the Hood
The Playground refuses to build a response header out of a fetched site's data (a header-injection class of bug we caught early). A billing endpoint on the Dashboard verifies the caller owns the resource before answering, closing an IDOR path.
The deploy pipeline itself got a rough week's worth of fixes after an outage on the 6th filled the deploy host's disk mid-build. Every service refuses to build without disk headroom, deploys serialise instead of racing, the gateway stays up when a backend flaps, and services actually exit on SIGTERM instead of hanging until they get killed thirty seconds later.
For a long time, "which browser signature" was our decision to make on your behalf. It doesn't have to be.