What is the JWT Decoder?
The JWT Decoder splits a JSON Web Token into its three segments and decodes the header and payload so you can read the claims. It is a debugging aid for inspecting tokens, it decodes them, it does not verify their signatures.
A JWT is three Base64url-encoded segments joined by dots: header.payload.signature. The header names the signing algorithm, the payload carries the claims, and the signature is computed over the first two segments using a secret or private key.
Because the first two segments are only encoded, not encrypted, anyone holding a token can read its contents. This is by design, JWTs provide integrity, not confidentiality. The signature proves the token has not been altered; it does nothing to hide what is inside.
The practical consequence is that you must never put sensitive data in a JWT payload. Passwords, personal data, and internal identifiers in a token are readable by every party that handles it, including the browser it is stored in.
How to use the JWT Decoder
- Paste your token. Drop the full token, including both dots, into the input field.
- Read the decoded header. The header shows the algorithm (alg) and token type (typ), and often a key identifier (kid) telling the server which key to verify with.
- Read the decoded payload. The payload contains the claims, who the token is about, who issued it, when it expires, and any custom fields the application added.
- Check the timestamps. The exp and iat claims are Unix timestamps. An exp in the past means the token has expired, which is a common cause of unexpected 401 responses.
Worked examples
Decoding a token's claims
The payload of a typical access token identifies the subject, the issuer, and the validity window.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NSIsIm5hbWUiOiJKb2huIERvZSIsImlhdCI6MTcwMDAwMDAwMH0.
signatureHeader:
{ "alg": "HS256", "typ": "JWT" }
Payload:
{ "sub": "12345", "name": "John Doe", "iat": 1700000000 }The signature segment is shown but not verified, verification requires the signing key.
Diagnosing an expired token
When an API starts returning 401 for a token that used to work, the exp claim is the first thing to check.
{ "sub": "12345", "exp": 1700000000 }exp = 1700000000
= 14 Nov 2023, 22:13:20 UTC
Status: expiredCommon use cases
- Debugging authentication failures. Decoding the token shows immediately whether it has expired, targets the wrong audience, or is missing a claim your API requires.
- Inspecting scopes and roles. Authorisation problems are often a missing scope or role claim rather than a broken token.
- Verifying your own token issuance. After changing how your service mints tokens, decoding one confirms the claims came out as intended.
- Learning how JWTs are structured. Seeing the segments decoded is the clearest way to understand why payload contents are not secret.
Features and limitations
- Decodes header and payload from Base64url, including tokens without padding.
- Renders the decoded JSON with formatting and highlighting.
- Converts iat, exp, and nbf timestamps into readable dates.
- Does not verify signatures. Verification requires the signing secret or public key, and doing it in a browser tool would mean handling that key, so the tool deliberately does not.
- Encrypted tokens (JWE) are not supported; only signed tokens (JWS) can be decoded.
Frequently asked questions
Does this verify the token's signature?
No. It decodes only. Verifying a signature requires the secret or public key, and you should never paste a signing secret into a web page. Verification belongs on your server, using your JWT library.
Is it safe to paste a token here?
The decoding happens entirely in your browser and nothing is transmitted. That said, a valid access token is a live credential, treat it with the same care as a password, and prefer expired or test tokens when you can.
Why can anyone read my JWT payload?
Because JWT payloads are encoded, not encrypted. The signature guarantees the token has not been tampered with, but the contents are public to anyone holding the token. Never store sensitive data in a payload.
What do sub, iat, exp, and aud mean?
They are registered claims: sub identifies the subject of the token, iat is when it was issued, exp is when it expires, and aud names the intended recipient. All timestamps are seconds since the Unix epoch.
My token was rejected but looks fine. Why?
Common causes are an exp in the past, an aud or iss that does not match what the API expects, clock skew between systems, or the token being signed with a key the verifier does not recognise.
What does alg: none mean?
It indicates an unsigned token. Accepting such tokens is a well-known vulnerability, since anyone can forge one. Any library you use should reject alg: none by default.
All processing happens locally in your browser, your data never leaves your device.
