Free tool
Paste a JA4 or JA4_r and read what the client offered in its TLS handshake.
t13d1516h2_8daaf6152771_e5627efa2ab1
Runs in your browser. Nothing you paste is sent anywhere.
Format
Readable: protocol, version, SNI, cipher count, extension count, first ALPN value.
Cipher suites, sorted, then SHA-256 cut to 12 characters.
Extensions, sorted, without SNI and ALPN, then the signature algorithms in order, hashed the same way.
JA3 vs JA4
| Field | JA3 | JA4 |
|---|---|---|
| Hash | One MD5 of every field | Readable prefix plus two short SHA-256 hashes |
| Extension order | Hashed as sent, so Chrome's shuffled order gives a new JA3 per connection | Sorted first, so the order does not matter |
| Readable without a lookup | No | Protocol, version, SNI, counts, ALPN |
| QUIC | No marker | Starts with q |
| License | BSD 3-Clause | BSD 3-Clause (JA4 only) |
Where it comes from
Only whoever terminates TLS sees the ClientHello. Script in the page never does.
Bot Management puts it in cf.bot_management.ja4 for rules and request.cf.botManagement.ja4 in Workers.
Rules can match on the JA4 fingerprint, and the WAF logs record it.
Anything that terminates TLS can compute it and pass it on in a header such as X-JA4.
FoxIO's plugin adds JA4 columns to packet captures.
Agentscan
Send the JA4 with each Agentscan check. It is stored with the verdict, the address and the network, so the log shows which TLS client sat behind each request.
curl -X POST https://ipscanner.io/v1/agentscan/check \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ip": "203.0.113.7",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
"ja4": "t13d1516h2_8daaf6152771_e5627efa2ab1"
}'FAQ
A short string that describes a TLS ClientHello: the protocol and version the client offered, whether it sent a server name, how many cipher suites and extensions it listed and its first ALPN value, followed by two hashes of those lists. FoxIO published it in 2023 as the successor to JA3.
TLS over TCP, version 1.3, a domain name in SNI, 15 cipher suites, 16 extensions and HTTP/2 as the first ALPN value. Every JA4 starts with a part like this, and it is the only part you can read without a lookup.
JA3 is one MD5 of the handshake fields in the order they were sent. Chrome started shuffling its extension order in 2023, which gives the same browser a new JA3 on every connection; JA4 sorts the lists first, so it stays put, and it keeps a readable prefix.
Yes. Tools such as curl-impersonate and uTLS copy a browser's ClientHello, so a browser JA4 on its own does not prove a browser. It is most useful when it disagrees with something else, such as a Chrome user agent arriving with a Python handshake.
No. Parts b and c are SHA-256 hashes cut to 12 characters. To see the cipher suites and extensions behind them, log the JA4_r, which keeps the lists in clear.
From whatever terminates TLS: your CDN, load balancer or reverse proxy. JavaScript in the page cannot read it, because the handshake is over before any script runs.
JA4, the TLS client fingerprint, is BSD 3-Clause. The other JA4+ methods (JA4S, JA4H, JA4X, JA4T and the rest) are under the FoxIO License 1.1, which sets conditions on commercial use, so read it before building those into a product.