JWT Decoder

Paste a JSON Web Token and read what is actually inside it: the header, every claim in the payload, and whether it has already expired.

Runs entirely in your browser. Nothing is uploaded.

How to use the JWT Decoder

  1. Paste the token

    Drop in the full token, including all three dot-separated parts. Strip the Bearer prefix if your token came from an Authorization header.

  2. Read the header and payload

    The header shows the signing algorithm. The payload shows every claim, with the timestamp claims rendered as readable dates.

  3. Check the expiry

    Compare the exp claim against the current time. An expired token is the single most common cause of an unexplained 401 response.

What is inside a JWT

A JSON Web Token is three Base64url-encoded sections separated by dots: a header, a payload and a signature. The header states which algorithm signed the token. The payload holds the claims - who the token is about, who issued it, when it expires, and whatever else the issuing system added.

The registered claims are worth knowing by name. iss is the issuer, sub is the subject, aud is the intended audience, exp is the expiry time, iat is when it was issued, and nbf is the time before which it must not be accepted. All three timestamps are Unix seconds, which is why they look like meaningless numbers until something renders them.

Decoding is not verifying

This is the point that trips people up, and it matters. The payload of a JWT is encoded, not encrypted. Anyone holding the token can read every claim in it without any key at all - which is exactly what this tool does.

What the signature provides is integrity: proof that the claims have not been altered since the issuer signed them. Verifying that signature requires the secret or public key, and it must happen in your backend, never in a browser tool. Treat a decoded payload as information about a token, never as proof that the token is legitimate.

The practical consequence: never put anything confidential in a JWT payload. A user ID is fine. An email address is usually fine. A password, an internal note or a permissions rationale is not, because every holder of the token can read it.

Debugging a token that is being rejected

Start with exp. An expired token is by far the most common cause of a 401 that appeared without any code change - clocks drift, refresh logic misfires, and a token that worked ten minutes ago stops working. Then check aud and iss match what the receiving service expects, since a token minted for a different audience is correctly refused.

If all the claims look right, the problem is the signature or the algorithm. A header saying alg is none, or an algorithm the verifier does not accept, will fail before any claim is even considered.

Frequently asked questions

Is my JWT sent to a server?
No. Decoding happens entirely in your browser. The token is never transmitted, logged or stored anywhere, which is essential because a live token is a credential.
Can this tool verify a JWT signature?
No, and no browser tool should. Verifying requires the signing secret or public key, and pasting that into a web page would defeat its purpose. Verification belongs in your backend.
Is a JWT encrypted?
No. A standard JWT payload is Base64url-encoded, which is encoding rather than encryption. Anyone with the token can read every claim, so never place confidential data inside one.
Why does my token show as expired?
The exp claim holds a Unix timestamp that has passed. This is the most common cause of a sudden 401. Check whether your refresh flow is running and whether the issuing and receiving servers agree on the time.
What do iss, sub, aud and exp mean?
They are registered claims: issuer, subject, audience and expiry time. A verifier typically checks that it is the intended audience, that the issuer is trusted, and that the token has not expired.