Free tool
JWT decoder.
Paste a JSON Web Token and read what it claims: the header, the payload, who issued it, who it is for, and exactly when it stops working. Decoded in this tab — the token never leaves your browser.
{
"alg": "HS256",
"typ": "JWT",
"kid": "2026-09"
}{
"sub": "user_8f21",
"name": "Ada Lovelace",
"email": "ada@example.com",
"role": "admin",
"scope": "reports:read reports:write",
"iss": "https://auth.example.com",
"aud": "commareports.com",
"iat": 1790000000,
"nbf": 1790000000,
"exp": 1790003600
}| sub | user_8f21 |
| name | Ada Lovelace |
| ada@example.com | |
| role | admin |
| scope | reports:read reports:write |
| iss | https://auth.example.com |
| aud | commareports.com |
| iat | 2026-09-21T14:13:20Z |
| nbf | 2026-09-21T14:13:20Z |
| exp | 2026-09-21T15:13:20Z |
Debugging a 401 with someone? Publish the header and payload — never the signature, so the link can't be used as a login — and they can comment on the claim that looks wrong. Free, no card.
Encoded is not encrypted
A JWT is three base64url strings joined by dots. The first two are JSON — the header says how the token was signed, the payload carries the claims — and anyone holding the token can read both, which is exactly what this page does. The third part is the signature, and it is the only thing that stops someone from editing the payload and handing it back. That is why a decoder can tell you what a token says, but only your server, holding the key, can tell you whether to believe it.
Reading a 401
Most rejected tokens fail for one of four reasons, all visible here. exp is in the past. nbf is in the future, usually because two machines' clocks disagree by more than the verifier's leeway. aud names a different API than the one you called. Or iss is a staging issuer hitting a production verifier. Check those four before you look at the signature.
Questions
- How do I decode a JWT?
- Paste the token into the box — with or without the Bearer prefix. The header and payload are base64url-decoded and shown as formatted JSON, and the registered claims (issuer, subject, audience, expiry) are laid out in a table with their timestamps converted to dates. Nothing installs and nothing is uploaded.
- Does this verify the signature?
- No, and on purpose. Verifying needs the signing secret or public key, and pasting a signing secret into a web page is exactly the habit you should not have. Decoding only tells you what the token claims; your server's JWT library is what decides whether to believe it.
- Is it safe to paste a JWT here?
- The decoding runs entirely in your browser and the token is never sent anywhere. That said, a live access token is a credential: anyone who has it can act as its subject until it expires. Prefer expired or test tokens when you can, and treat any tool that sends your token to a server with suspicion.
- How do I check if a JWT is expired?
- Look at the exp claim. It is a Unix timestamp in seconds, and this page shows it as a UTC date plus how long ago or how far ahead that is from your clock. nbf (not before) is shown the same way, because a token that is not valid yet fails with the same generic 401.
- Why can anyone read my JWT's payload?
- Because a signed JWT is encoded, not encrypted. Base64url is a transport format with no key, so the payload is readable by anyone holding the token. Never put a secret in a JWT claim. If the contents must be private, the token has to be a JWE — five parts instead of three.
- What does alg: none mean?
- It means the token is unsigned. Some libraries once accepted such tokens as valid, which let anyone forge one. If a token you received in production says none, treat it as an attack, and make sure your verifier pins the algorithms it will accept.
Related: JSON formatter · URL encoder · YAML to JSON · Base64 image encoder · all free tools