JWT Decoder
Decode any JSON Web Token to read its header, payload and claims. Nothing is sent anywhere — it decodes in your browser.
Runs entirely in your browser. Nothing you paste is uploaded, logged, or stored.
What a JWT is and how this decoder reads it
A JSON Web Token is three base64url-encoded segments joined by dots: header.payload.signature. The header names the signature algorithm and token type, the payload carries the claims — the actual data the token is vouching for — and the signature is a cryptographic proof, computed over the first two segments, that only the holder of a specific key could have produced. This tool splits the token on ., base64url-decodes the header and payload, and pretty-prints the resulting JSON. Base64url is almost the same as standard base64 but swaps +// for -/_ and drops padding, so decoding it correctly means translating those characters back and re-adding the = padding before the browser's base64 decoder can touch it. This tool also runs the decoded bytes through a proper UTF-8 decoder rather than JavaScript's raw atob(), which otherwise mangles any name, address or other claim value that contains non-ASCII characters.
Decoding is not the same as verifying
This is the single most common misunderstanding about JWTs, so it is worth stating plainly: anyone can decode a JWT. No key, password or permission is required, because the payload is base64-encoded, not encrypted. What the signature proves is that the token was issued by whoever holds the private (or shared) signing key, and that the header and payload have not been altered since. This tool decodes the header and payload for you to read; it does not and cannot verify the signature, because that requires the issuer's public key or shared secret, which never leaves the server that issued the token. Never treat a JWT as trustworthy just because it decodes cleanly — a forged or modified token decodes exactly as easily as a real one.
The registered claims, decoded into plain English
A handful of claim names are standardised by RFC 7519 and appear in almost every JWT. Rather than just showing you the raw JSON, this tool interprets them:
exp(Expiration Time) — shown as an absolute date, a relative phrase like "in 42 minutes" or "3 days ago", and a clear EXPIRED badge once it has passed.iat(Issued At) — when the token was created, with the same relative phrasing.nbf(Not Before) — the earliest the token becomes valid; flagged if that time is still in the future.iss(Issuer),sub(Subject),aud(Audience) andjti(JWT ID) — shown with their plain-English names next to the raw value.
When both iat and exp are present, the tool also computes and displays the token's total lifetime — the gap between issue and expiry — which is often more revealing than either timestamp alone. A one-year access token and a five-minute one carry very different risk if either leaks.
Header claims
The header is smaller but just as important: alg names the signature algorithm (for example RS256 or HS256), typ is almost always JWT, and kid (Key ID) tells a verifier which of several possible keys was used to sign it — useful when an issuer rotates keys over time.
{
"alg": "HS256",
"typ": "JWT"
}Handling errors
Not every string that looks like a token is a valid one. This tool checks for the three required segments, confirms each of the first two decodes as valid base64url, and confirms the decoded bytes parse as JSON — reporting exactly which of those steps failed rather than showing a blank page. A token with the wrong number of dot-separated parts, a truncated copy-paste, or a segment that is not valid JSON will all produce a specific, readable error instead of silence.
Frequently asked questions
What is a JWT?
A JSON Web Token (JWT) is a compact, URL-safe way to represent a set of claims — facts about a user or session — as a signed piece of text. It is the standard format for API access tokens, session tokens and identity tokens (ID tokens in OpenID Connect).
Is decoding a JWT the same as verifying it?
No. Decoding just reads the base64url-encoded header and payload, which anyone can do without any key. Verifying checks the signature against the issuer’s key and proves the token is authentic and unmodified. This tool decodes only — it never has the key needed to verify.
Is it safe to paste a real production token here?
This decoder runs entirely in your browser: there is no server request, no analytics call and no logging, so the token never leaves your machine. That said, treat any tool this way as a habit, not just this one — check for yourself with your browser’s network tab if you want proof.
Why does the payload show information I did not expect?
The payload of a JWT is base64url-encoded, not encrypted. Anything placed in it — user ID, role, email, permissions — is readable by anyone who has the token, including in browser storage, logs, and proxies it passes through.
Why is my token showing as expired?
The "exp" claim is a Unix timestamp for when the token stops being valid. If that time has passed, this tool flags it as expired — the same check a real verifier performs before accepting the token.
Can I decode a token that is not a JWT?
Only if it follows the JWT shape: three dot-separated, base64url-encoded segments where the first two decode to JSON. Opaque tokens, session cookies and API keys that are not JWTs will fail to decode, and that failure itself tells you it is not a JWT.
Does this handle non-ASCII characters in the payload correctly?
Yes. Base64 decoding is done with proper UTF-8 handling, so names, addresses or any other non-ASCII claim values render correctly instead of turning into garbled characters, which is a common bug in quick-and-dirty decoders that only use atob().