A JSON Web Token looks like a long random string, but two thirds of it is ordinary JSON that anyone can read. Decoding one is the quickest way to debug a login problem or an API that answers 401 — as long as you remember what decoding does not tell you.
The three parts
A JWT is three pieces separated by dots:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJleHAiOjE3OTk5OTk5OTl9.<signature>
- Header — which algorithm signed the token, for example HS256 or RS256, and the type, JWT.
- Payload — the claims: who the token is about, who issued it, when it expires, and any custom data such as roles.
- Signature — computed by the issuer over the first two parts with a secret key (HS256) or a private key (RS256, ES256).
The first two parts are Base64URL-encoded, not encrypted. Base64URL is Base64 with "-" and "_" in place of "+" and "/" and the padding removed, so the token can sit in a URL or an HTTP header. That is why a decoder needs no key to show you the contents.
How to decode one
- Paste the token into JWT Decoder and press Decode JWT.
- You get the header and the payload as formatted JSON, ready to copy.
- The signature is not checked — the tool says so — and nothing is uploaded: decoding happens in the page.
Reading the claims
The standard claims are defined in RFC 7519:
| Claim | Meaning |
|---|---|
| iss | issuer — who created the token |
| sub | subject — usually the user ID |
| aud | audience — which service the token is meant for |
| exp | expiry time |
| nbf | not valid before this time |
| iat | issued at |
| jti | unique token ID |
The three time claims are NumericDate values: seconds since 1 January 1970 UTC, not milliseconds. A value such as 1799999999 is a moment in early 2027. Paste it into Unix Timestamp Converter to see it as a date in your time zone. A surprising number of "token expired" bugs come down to one side treating these as milliseconds, or to clocks on two servers disagreeing by a few minutes.
What decoding does not prove
Anyone can write a token with any payload they like and Base64URL-encode it. Only the signature, checked with the right key, shows that the issuer created it and that nobody changed it since. So:
- Never make a security decision from a decoded token on the client. Use decoding to inspect and debug. Authorisation belongs on the server, after verifying the signature.
- Verify with a maintained library, not by hand, and tell it which algorithm to expect. A classic class of JWT vulnerabilities came from libraries that trusted the algorithm named in the header — including the value "none", meaning unsigned.
- Check exp, nbf and aud after the signature. A valid signature on an expired token, or on a token meant for another service, is still a reason to refuse it.
Is it safe to paste a token?
A live token is a key: whoever has it can use it until it expires. A decoder that runs in your browser, like this one, does not send the token anywhere. The risk that remains is everywhere else a token ends up — screenshots, chat messages, issue trackers, clipboard history. Prefer decoding expired or test tokens, and if you pasted a production token somewhere you shouldn't have, revoke it.
Common errors
- "That doesn't look like a valid JWT." Usually a token copied with the word "Bearer " in front of it, a line break in the middle, or only one part of it. Paste the string from the first "eyJ" to the end.
- Five parts instead of three. That is a JWE — an encrypted token. Its payload cannot be read without the decryption key, by design.
