JWT Decoder

Read what is inside a JSON Web Token

The signature is not checked. Nothing here is verified.

A JWT is signed, not encrypted, so anyone can read the payload — including anyone who intercepted it. Decoding proves only that the token is well formed. It cannot tell you the token is genuine, unexpired in the eyes of your server, or that its claims were not edited in transit. That check needs the signing key and belongs on the server. Treat a decoded payload as a claim, never as a fact.

JSON Web Token

About JWT Decoder

A JSON Web Token looks like three runs of gibberish separated by full stops. Two of them are not gibberish at all: the header and the payload are ordinary JSON, Base64url-encoded, and anyone holding the token can read them. This page does that reading and lays the result out — the header, every claim, and the timestamps rendered as dates you can actually parse at a glance.

The part it cannot do is the part that matters for security. The third segment is a signature over the first two, and checking it requires the key that produced it. Nothing in a browser has that key, so nothing in a browser can tell a genuine token from one somebody typed out by hand. Every decoder on the internet is in the same position; this one says so instead of implying otherwise with a green tick.

That makes it a debugging instrument. Use it to find out why an API is returning 401, which audience a token was minted for, or whether a clock somewhere is running fast — not to decide whether to trust the person holding it.

  • Header and payload decoded and pretty-printed
  • exp, iat and nbf shown as dates in your timezone and UTC
  • Says whether a token has expired and by exactly how long
  • Explains each registered claim from RFC 7519
  • Flags alg: none, empty signatures and millisecond timestamps
  • States plainly that the signature is never verified

How to use JWT Decoder

  1. Paste the token

    The whole thing, including both dots. An Authorization header, quotes from a JSON field and stray whitespace are stripped for you.

  2. Read the expiry line first

    It says whether the token is inside its own validity window and by how much, down to the second, against your machine's clock.

  3. Check the claims table

    Every registered claim is listed with what it means and, for exp, iat and nbf, the instant it names in both your timezone and UTC.

  4. Look at the header for alg and kid

    These tell your server which key to verify with. A mismatch between them and what the server expects is a common cause of a rejection that looks like an expiry problem.

What the three parts of a JWT actually contain

The first segment is the header: a small JSON object naming the signing algorithm in alg, usually with typ set to JWT and often a kid identifying which key was used. When an issuer rotates keys, kid is how a verifier picks the right one out of a published key set.

The second is the payload, a JSON object of claims. Seven names are registered by RFC 7519 — iss, sub, aud, exp, nbf, iat and jti — and everything else is whatever the issuer chose to add: a scope list, an email, a tenant id, a role. There is no schema. Two identity providers will disagree about how to spell the same idea.

The third is the signature, computed over the encoded header and payload joined by a dot. It is what makes the token tamper-evident: change a single character of the payload and the signature no longer matches. It does not make the payload private, which is the distinction that trips people up.

Reading exp, iat and nbf without getting the units wrong

All three are NumericDate values: seconds since 1 January 1970 UTC, not milliseconds. A token that expires an hour from now carries an exp of around 1.7 billion — ten digits. If you see thirteen, whatever issued the token multiplied by a thousand it should not have, and a strict verifier will treat that expiry as being somewhere in the year 55000. This page detects that case, converts it sensibly and tells you it did.

nbf, not before, is the mirror of exp. A token can be issued now and only become usable in ten minutes. In practice the claim causes more trouble than it prevents, because a server whose clock is thirty seconds ahead of the issuer's rejects freshly minted tokens with an error that reads like a bug in your code.

That is the real use of seeing all three as dates side by side. If iat is in the future relative to your own clock, you are not looking at a token problem — you are looking at two machines that disagree about what time it is, and the fix is NTP rather than anything in your application.

Why a token that decodes fine is still rejected

Expiry is the obvious one and usually the right answer. After that, the most common cause is audience: aud names who the token is for, and an access token minted for one API is not valid at another, however healthy it looks. Check aud against what the receiving service was configured to accept.

Issuer mismatch is next — iss must match exactly, and a trailing slash or an http/https difference counts as a mismatch. Then there is algorithm: a verifier configured for RS256 must refuse a token that says HS256, because accepting whatever the header asks for is the root of the classic key-confusion attack.

A JWT is also not the only thing shaped like one. Opaque session tokens and some API keys are three Base64 segments as well. If the header decodes to something that is not a JSON object, you have one of those rather than a JWT, and no amount of decoding will produce claims.

How a signature is really verified

For an HMAC algorithm — HS256 and its relatives — the verifier recomputes the signature using a shared secret and compares the two. For RSA and ECDSA — RS256, ES256 and so on — it checks the signature against the issuer's public key, which is typically fetched from a JWKS endpoint and matched to the token by kid.

Do this with a maintained library on your server: jose or jsonwebtoken in Node, PyJWT in Python, java-jwt on the JVM. They also enforce the checks people forget, such as rejecting alg: none and refusing to let the token itself dictate which algorithm is used.

And treat a JWT as the credential it is. It grants whatever the bearer asks for until it expires, so a token in a bug report, a screenshot or a log file is a leaked password. Nothing you paste here leaves your browser, but if a token has been anywhere you are unsure about, the safe response is to revoke the session and issue a new one.

Frequently asked questions

Does this verify the signature?

No, and no browser tool honestly can without your secret or public key. Decoding shows what a token claims; verifying proves it was not tampered with. Never trust a decoded payload for an authorisation decision — that check belongs on your server.

Is it safe to paste a real token here?

The decoding happens entirely in your browser and nothing is uploaded. That said, a JWT is a live credential until it expires, so treat pasting one anywhere the way you would treat pasting a password, and rotate it if you are unsure.

Why can I read the payload without a key?

Because a JWT is signed, not encrypted. The payload is Base64url-encoded, which is an encoding anyone can reverse. That is by design — it is why you must never put a secret in a token's claims.

Last updated 19 Aug 2026 · Free to use · Runs entirely in your browser