JWT Decoder
Decode a token, read the claims, see when it expires — without sending it anywhere.
Header
Payload
Decoding happens in your browser. The signature is NOT verified.
What is actually inside a JWT
A JSON Web Token is three base64url strings joined by dots: header, payload, signature. The first two are plain JSON that anyone can read — base64 is an encoding, not encryption. The third is a signature over the first two, and it is the only part that proves the token was issued by someone holding the key.
That split explains what this decoder does and does not do. Reading the claims requires nothing but decoding. Trusting them requires verification with a secret or public key, which belongs on your server, never in a browser form.
Worked example 1: reading the standard claims
A typical payload looks like {"sub":"1234567890","name":"Ada Lovelace","iat":1767225600,"exp":1767229200}. The subject is the user id, iat is when it was issued and exp when it stops being valid — both Unix seconds. The gap here is 3600 seconds, a one-hour token. The decoder converts both stamps into your local time and flags whether now is past exp.
Worked example 2: the "expired" surprise
A token that worked five minutes ago and fails now almost always has a short exp. Decode it, read the expiry, and you have the answer without touching server logs. If exp is missing entirely, the token never expires by itself — a design that shifts the whole revocation burden onto a denylist, which is worth knowing before you ship it.
Worked example 3: checking the algorithm
The header names the signing algorithm, for example {"alg":"HS256","typ":"JWT"}. If you ever see "alg":"none" coming from a real system, treat it as an incident: it names a genuine vulnerability class where servers accepted unsigned tokens. Decoding the header is the quickest way to spot it.
Common claims and what they mean
| Claim | Meaning | Typical value |
|---|---|---|
| iss | Issuer — who minted the token | https://auth.example.com |
| sub | Subject — usually the user id | 1234567890 |
| aud | Audience — who it is meant for | api.example.com |
| exp | Expiry, Unix seconds | 1767229200 |
| iat | Issued at, Unix seconds | 1767225600 |
| nbf | Not valid before | 1767225600 |
| jti | Token id, for replay defence | a3f1… |
Safety notes worth repeating
Never put a private key or shared secret into any online tool, including this one — there is no field for it here precisely so the temptation does not exist. Verification belongs in your backend library, where the key stays in your environment.
Treat any live token as a password. Decoding happens locally here and you can verify that in the devtools network tab, but the safest habit is to decode expired or test tokens and rotate anything you paste into a tool you did not write. Access tokens in particular grant real permissions until they expire.
Finally, remember that a decoded payload is user-controllable data as far as your application is concerned. Read it for debugging, but never make an authorisation decision from a token your server has not verified.
Sources & further reading
- RFC Editor — RFC 7519, the JSON Web Token (JWT) specification and registered claims
- RFC Editor — RFC 7515, JSON Web Signature (JWS) header and signing rules
- MDN Web Docs — how Base64 and base64url encoding work in the browser
- NIST SP 800-63B — digital identity guidance on session tokens and secret handling
Frequently asked questions
Does this tool verify the signature?
No, and that is deliberate. Verifying requires the secret or public key, which you should never paste into a website. This tool only decodes the two base64url segments so you can read the claims. Treat a decoded token as untrusted until your server verifies it.
Is it safe to paste a token here?
The decoding runs entirely in your browser — no network request carries the token, which you can confirm in your devtools network tab. That said, a JWT is a credential: prefer expired or test tokens, and rotate anything you paste into any tool you did not write yourself.
Why do exp and iat look like large numbers?
They are Unix timestamps: seconds since 1 January 1970 UTC. 1767225600 is 1 January 2026. The decoder converts both into your local time so you can see at a glance whether a token is still valid and how long its lifetime was.