Full definition
When your code makes an HTTPS request, the TLS handshake includes details like supported cipher suites, extensions, and elliptic curves. The exact ordering and presence of these fields is unique to each TLS implementation: Chrome's TLS handshake is different from Firefox's, both are different from Python's `requests` library, which is different from Go's `net/http`. The JA3 fingerprint is a hash of these fields — same library = same JA3.
Anti-bot systems maintain databases of "known automation" JA3 hashes. If you scrape with `requests`, your JA3 hash matches the well-known requests/urllib3 fingerprint, and Cloudflare/Akamai block you regardless of how realistic your User-Agent looks.
The fix: use a TLS-fingerprint-spoofing client. `curl-impersonate`, `tls-client` (Go), or `httpx` with `httpcore`/`h2`/spoofed parameters can mimic Chrome's exact JA3. Alternatively, use a headless real browser (Playwright, Puppeteer with stealth plugins) which has a real Chrome fingerprint by definition.