JWT Token Decoder

How to use 3 steps
  1. Paste the token under Paste Encoded JWT Token.
  2. Press Decode JWT Payload.
  3. Read the header, claims and expiry. Decoding does not verify the signature.
Decoded JWT Payload

How this tool works

A JSON Web Token is three parts separated by full stops: a header naming the algorithm, a payload of claims, and a signature. The first two are base64url — a variant where dash and underscore stand in for plus and slash and the padding is dropped — so they are encoded rather than encrypted. Anyone holding a token can read its contents, which is the single most important thing to understand about the format.

Both segments are decoded and printed as formatted JSON, with the time claims translated out of seconds-since-the-epoch into readable dates, since expiry is usually what someone opens a decoder to check. The signature is not decoded and not checked: verifying it needs the secret or public key the token was signed with, which belongs on your server and should never be pasted into a web page.

What a decoded token does and does not tell you

  • Decoding is not verifying: a payload that reads correctly is no evidence the token is genuine. A forged token decodes exactly as cleanly as a real one, and only the signature check distinguishes them.
  • Never put secrets in a payload: claims are readable by anyone who obtains the token. Internal identifiers, roles and email addresses in a payload are effectively public to whoever holds it.
  • The time claims are seconds, not milliseconds: exp, iat and nbf are all in seconds since the epoch, which is a factor of a thousand away from what JavaScript's Date expects and a routine source of tokens that appear to expire in 1970.
  • An expired token is still readable: expiry is enforced by whatever validates the token, not by the format. Reading one that has expired tells you nothing about whether the system accepted it.

Encoded, not encrypted

A JSON Web Token is three parts separated by full stops: a header naming the algorithm, a payload of claims, and a signature. The first two are base64url — ordinary base64 with dash and underscore standing in for plus and slash, and the padding dropped — which means they are encoded rather than encrypted. Anyone holding the token can read every claim inside it, which is the single fact that matters most about the format before using the [msm_tool slug="jwt-decoder"] on anything real.

Decoding a token is not the same as verifying it

A payload that decodes cleanly and reads correctly is not evidence that the token is genuine. A forged token, built by anyone who understands the format, decodes exactly as cleanly as a real one — only checking the signature against the key it was signed with distinguishes the two, and that check needs a secret or public key that belongs on a server and should never be pasted into any web page, including this one.

The time claims are seconds, not milliseconds

`exp`, `iat` and `nbf` are all expressed in seconds since the epoch, which is a factor of a thousand away from what JavaScript's own `Date` expects by default. Feeding one of these values into `Date` without converting it first produces a date somewhere in 1970 rather than the intended expiry, which is a routine and easy mistake to make when reading a token by hand.

An expired token still decodes perfectly well

Nothing about the format itself prevents an expired token from being read — expiry is enforced by whatever system validates the token during a real request, not by the token's own structure. Decoding one that has already expired shows exactly what it claims and says nothing about whether any system would still accept it.

Nothing belongs in a payload that is not already public

Because the payload is readable by anyone who obtains the token, internal identifiers, roles and email addresses placed inside one are effectively visible to whoever is holding it, not protected in any meaningful sense. Anything genuinely sensitive needs to live somewhere the token merely references, not inside the token itself.

A token is a credential, even one you are only reading

Decoding happens entirely in the browser and nothing is transmitted anywhere by this tool, but a live, valid token grants whatever access it was issued for to anyone holding it. Pasting one anywhere — here or elsewhere — is worth exactly the same caution as pasting a password.

Frequently Asked Questions

Specific to the JWT Token Decoder. Broader questions about this category are answered on the category page.

No. It decodes the header and payload. Verifying the signature requires the signing key, which belongs on your server and should never be pasted into a web page.
No, only encoded. The payload is base64url text that anyone holding the token can read, which is why secrets must never go in one.
Almost certainly base64url. JWTs use dash and underscore where standard base64 uses plus and slash, and a decoder not expecting them rejects the token.
The time claims are in seconds since the epoch. Treating them as milliseconds puts the date in 1970; they are converted correctly here.
It is decoded in your browser and never sent anywhere. That said, a live token is a credential — treat pasting one anywhere with the same care you would a password.

Subscribe to receive notifications about new tools, features, and productivity tips.