← home · guides · # troubleshooting
Fix a curl 403 without rewriting in Python
A request that loads in Chrome but returns 403 from curl is almost always a TLS/HTTP-2 fingerprint mismatch — setting a User-Agent will not fix it. recurl detects the block and escalates to a browser-matching fingerprint (and a JS preflight if needed) without you rewriting anything.
- 1
Confirm the block with a debug trace
Run the failing request through recurl with --recurl-debug. The trace shows whether the 403 came from the plain-curl layer and how recurl escalated.
recurl --recurl-debug -s https://protected-site.com/api
- 2
Let escalation resolve it
If impersonation returns 200, a browser-matching JA3/JA4 handshake was enough. If it still 403s, recurl escalates to a headless Chromium preflight, captures cookies, and replays through curl.
# [recurl] layer=impersonate profile=chrome status=200
- 3
Force a fingerprint if needed
Some hosts respond only to a specific browser profile. Force one with --recurl-impersonate to pin the handshake.
recurl --recurl-impersonate firefox -s https://protected-site.com/api
- 4
Wire it into the script
Replace curl with recurl in your script (or alias it). The command line, flags, and output format stay identical, so the rest of your pipeline is untouched.
recurl -s https://protected-site.com/api | jq .
# note
Only use this on hosts you are authorised to fetch from. recurl shares curl’s ethical scope and does not bypass authentication or paywalls.
Next steps
Read the escalation architecture, see the full feature surface, or browse more guides.