JWT Decoder
Paste a JSON Web Token to read what is inside it. The header and claims are decoded and formatted, timestamps are converted to readable dates, and expiry is checked against the current time. Nothing is sent anywhere.
- Free, no sign-up
- Runs in your browser
- Nothing uploaded
- Updated Sep 2026
At a glance
- Decodes
- Header and payload of any JWT
- Shows
- Expiry status, issued-at, not-before, standard claims explained
- Verifies
- No — signature verification needs the secret or public key
- Privacy
- Entirely client-side; the token never leaves your browser
- Warning
- A JWT payload is readable by anyone. It is signed, not encrypted
- Cost
- Free, no account
A JWT is signed, not encrypted
This is the single most important thing to understand about JSON Web Tokens, and this page demonstrates it: paste any token and you can read everything in it, with no key and no permission.
The three dot-separated parts are Base64URL-encoded, which is an encoding, not a cipher. The signature at the end proves the token was issued by someone holding the key and has not been altered since. It does not hide anything.
The practical consequence: never put anything confidential in a JWT payload. No passwords, no full dates of birth, no national identifiers, no internal system details you would not publish. A user ID and a role are appropriate; a user's medical status is not. Anyone who obtains the token — through a browser extension, a log file, a proxy, a crash report — can read every claim.
If you genuinely need confidential data in a token, the standard answer is JWE, which encrypts the payload. It is considerably more complex, and the better answer is usually to put an opaque identifier in the token and keep the sensitive data on the server.
Reading the claims
Seven registered claims appear in most tokens, and knowing them makes a payload readable at a glance:
- iss (issuer) — who created the token.
- sub (subject) — who it is about, usually a user ID.
- aud (audience) — who it is intended for. A service should reject a token whose audience is not itself, which is what prevents a token issued for one API being replayed against another.
- exp (expiration) — a Unix timestamp after which the token must be rejected.
- nbf (not before) — a timestamp before which it is not yet valid.
- iat (issued at) — when it was created.
- jti (JWT ID) — a unique identifier, used to prevent replay.
Everything else is a custom claim your application defines. The decoder converts
exp, nbf and iat to readable dates and tells you
whether the token is currently valid — a small thing that answers "is this expired?" much
faster than converting a Unix timestamp by hand.
Why this tool does not verify signatures
Verification requires the signing key. For a symmetric algorithm like HS256, that is the shared secret; for an asymmetric one like RS256, the issuer's public key. Pasting a production signing secret into a web page is a bad idea regardless of how trustworthy the page claims to be, so this tool does not ask for one.
Verify in your own environment, with a library, and check the algorithm explicitly. The
alg: none attack — where an attacker strips the signature and sets the
algorithm to none — works against implementations that trust the header's
algorithm field. So does algorithm confusion, where a token signed with the public key using
HS256 is accepted by a service expecting RS256. Both are defeated by specifying the expected
algorithm at verification time rather than reading it from the token.
The decoder flags alg: none if it sees it, because a token with no signature
should never be accepted and seeing one usually means something is wrong upstream.
How to use the JWT Decoder
-
Paste your token
The full three-part token. A
Bearerprefix is stripped automatically if you paste a whole header value. -
Read the header
It shows the signing algorithm and, often, a key ID identifying which key was used.
-
Check expiry
Expiry, issued-at and not-before are converted to local time, with the token's current validity stated plainly.
-
Verify elsewhere
Signature verification belongs in your own environment with your own key. Never paste a production signing secret into a web page.
Frequently asked questions
Is my token sent to a server?
No. Decoding is Base64 and JSON parsing in your browser tab, with no network request. That matters more here than almost anywhere else, because a JWT is a live credential — a token pasted into a server-side decoder should be treated as compromised.
Can you see my data in a JWT?
Anyone can. The payload is Base64-encoded, not encrypted, and this page reads it with no key. That is why nothing confidential belongs in a JWT payload — the signature proves authenticity, it does not provide secrecy.
Why does this not verify the signature?
Verification needs the signing key, and pasting a production secret into any web page is a bad idea. Verify in your own environment with a library, and specify the expected algorithm explicitly rather than trusting the token's header.
What does alg: none mean?
It means the token carries no signature. It exists in the specification for tokens whose integrity is guaranteed by other means, and in practice it is mostly seen in attacks — an attacker strips the signature and sets the algorithm to none, hoping the server trusts the header. Never accept it.
How do I revoke a JWT before it expires?
You cannot, directly — that is the trade-off that makes JWTs stateless. The usual answers are short expiry times with refresh tokens, or a server-side denylist of revoked token IDs, which reintroduces the state JWTs were meant to avoid. Choose deliberately.
What is a good expiry time?
For access tokens, minutes rather than hours — fifteen minutes is common — paired with a longer-lived refresh token that can be revoked. Long-lived access tokens are convenient and mean a stolen token stays useful for as long as it lasts.