A JSON Web Token is three Base64url chunks joined by dots: a header, a payload, and a signature. This tool splits them and shows you what is inside. It does not check the signature, and that omission is deliberate — the reason why is worth two minutes of your time.
Decoding is not verifying
These are completely different operations and conflating them causes security incidents. Decoding needs nothing: the header and payload are Base64url-encoded, not encrypted, so anyone holding the token can read every claim in it. Verifying needs the signing key, and it answers a different question — was this token really issued by who it claims, and has anyone altered it since.
A tool that reads a token proves nothing about its validity. If you paste an expired token here you will still see its contents rendered perfectly. The decode succeeding tells you the string is well-formed, nothing more.
Why this tool refuses to verify signatures
Plenty of JWT websites offer a box for your signing secret next to the token. Think about what that asks of you. For HS256, the secret is the same key that mints valid tokens — hand it to a web page and whoever runs that page can now forge any token they like for your system. There is no way to verify a symmetric signature without surrendering the ability to create signatures.
So this tool does not ask, and you should be wary of any that does. Verify signatures in your own code, in your own runtime, with the key loaded from your own secret store. A signing key belongs in exactly two places: the service that issues tokens and the service that checks them.
The claims that trip people up
The timestamps are the usual culprit. RFC 7519 defines exp, iat and nbf as NumericDate — seconds since the Unix epoch. JavaScript's Date.now() returns milliseconds. Passing one where the other is expected is the most common JWT bug there is: a token that expires in 1970, or one that stays valid for the next fifty thousand years. If a decoded exp renders as a date in the distant past or absurd future, you have found a factor of 1000.
The other frequent surprise is nbf, "not before". A token can be perfectly signed, unexpired, and still rejected because it is not valid yet — usually a symptom of clock skew between the issuing and validating machines rather than anything wrong with the token.
The alg field is an instruction, not a description
The header carries an "alg" claim naming the signing algorithm, and the classic JWT vulnerability is a library that trusts it. If a validator reads alg from the token and then verifies accordingly, an attacker can set alg to "none", strip the signature, and walk in — the token itself told the validator not to check it.
The related attack swaps RS256 for HS256. Under RS256 the token is signed with a private key and verified with the public one. A naive validator that reads alg as HS256 will use that public key as an HMAC secret — and the public key is, by definition, public. Both attacks are old and most maintained libraries now refuse alg values the caller did not explicitly allow. If you are looking at a token whose header says "none", you are either testing something or looking at an attack.
What not to put in a payload
Since the payload is readable by anyone holding the token, it is not a place for anything private. No internal user notes, no permission logic you would rather not explain, no personal data beyond what the token needs to do its job. The signature stops modification, not reading — a distinction that has embarrassed a lot of teams who assumed a signed token was a sealed one.
Common questions
Is my token sent to a server?
No. This tool is marked "client": the split and decode happen in your browser tab and the token never leaves your machine. But treat this as a habit worth questioning generally — a JWT is a live credential. If you pasted a production token into any website, including this one, the safest assumption is that it should be rotated.
Can I check whether this token is valid?
Not here, and not on any site you do not run yourself — see the section above. What you can check by eye is whether the token has expired, since exp is right there in the decoded payload. That covers the most common reason a token stops working, without any key changing hands.
Why does the expiry show as a date in 1970?
Because a millisecond timestamp is being read as a seconds one. Divide by 1000 and the date will look sensible. Whatever produced the token is using Date.now() where RFC 7519 expects Math.floor(Date.now() / 1000).
Can I edit a token and re-sign it here?
No. Changing a single character of the payload invalidates the signature, and producing a new valid one requires the signing key — which, as covered above, is not something to paste into a web page. Editing tokens is something to do in your own test suite with a test key.
The token has dots but will not decode. Why?
Most often it is not a JWT. Encrypted tokens (JWE) have five segments rather than three, and their payload is genuinely unreadable without the key. Truncation is the other common cause: tokens are long and get clipped by log formatters, terminal widths and spreadsheet cells. If the middle segment ends abruptly, you are probably missing characters rather than looking at a malformed token.