JWT Decoder (Decode Header and Payload)

Built and verified by pengchun · Last reviewed · How we verify

Paste a JSON Web Token to read its header, payload and time claims as plain JSON, with expiry spelled out in human terms. Optionally verify the signature with a shared secret or a public key. Nothing leaves your browser.

What a JWT actually is

A JSON Web Token is three base64url strings joined by dots. The first is the header, which names the signing algorithm; the second is the payload, a JSON object of claims; the third is the signature. Because the first two parts are only base64url encoded, anyone holding the token can read them with no key at all. That is by design: the payload is where a server puts facts it wants to hand to a client, such as a user id, a role and an expiry time.

eyJhbGciOiJIUzI1NiJ9 decodes to {"alg":"HS256"}. Nothing was decrypted to get there. A decoder is therefore a convenience, not a security boundary, and reading a payload tells you what the token says, never whether it is real.

Decoding is not verifying

This is the mistake that turns a helpful tool into a dangerous one. A signature is computed over the first two segments with a key. Verification means recomputing that value and comparing, which is the only thing that proves two facts at once: the token was produced by somebody holding the key, and neither the header nor the payload has been altered since.

Anyone can invent a token. Take this page's sample payload, change "role":"admin" to anything you like, and the decoded result still looks perfectly well formed while the signature no longer matches. That is why this page shows a "not verified" badge until you supply a key, and why it never describes a decoded token as valid.

The claims worth looking at

All of these times are UTC and none of them carries a time zone, for the same reason Unix timestamps do not: an instant is unambiguous, a wall-clock string is not.

Common JWT mistakes

How to use this decoder

  1. Paste a token into the box, with or without a leading Bearer. Decoding starts as you type.
  2. Read the header and payload as formatted JSON, then the time claims table, which spells out each timestamp in UTC, in your local time and as a relative phrase.
  3. The badge at the top tells you whether the token is still inside its validity window, expired, or not yet valid.
  4. To check a signature, paste the HMAC secret or a PEM public key and press Verify signature. For HS256 and its siblings the key is the shared secret; for RS, PS and ES you paste the public key only.
  5. Use Copy on either block. The JSON is plain text, so it pastes cleanly into a bug report or a code comment.

The registered claims, and what each one means

A JWT payload is ordinary JSON, so a token can carry any field its issuer likes. A handful of names are registered in the specification, though, and they are the ones the tool highlights because every library agrees on them:

ClaimWhat it saysAn example value
issWhich system issued the tokenhttps://accounts.example.com
subWhich user or subject the token is aboutuser_4812
audWhich service the token is meant forapi.example.com
expExpiry time, as a Unix timestamp in seconds1789689600
nbfNot valid before this time, same format1789603200
iatWhen the token was issued, same format1789603200
jtiA unique id for this token, used to stop replays8f14e45f-ea0f-4a4d-9d1f-1c2b3a4d5e6f

The three time claims are the ones people misread, because they are Unix timestamps rather than readable dates: 1789689600 is a moment in September 2026, not a large number to be skimmed past. The timestamp converter turns any of them into a local date and back, which is the fastest way to answer "has this token expired yet?".

Reading a token is not the same as trusting it. The header and payload are Base64url text, so the Base64 encoder and decoder can decode them as well as this page can — anyone can read your claims, and only the signature decides whether they were tampered with.

FAQ

Is it safe to paste a real JWT into an online decoder?

This decoder runs entirely inside your browser: the token is never uploaded, and the page makes no network request while decoding. That said, a JWT is a credential, so treat it like a password. Avoid pasting production tokens into sites you do not trust, prefer short-lived tokens when testing, and remember that anything you paste into a browser tab can also be seen by browser extensions you have installed.

What is the difference between decoding and verifying a JWT?

Decoding is just base64url + JSON: anyone can read the header and the payload without any key, because the token is only encoded, not hidden. Verifying recomputes the signature with the key and proves the token was issued by whoever holds that key and was not altered afterwards. A decoded token is not a trusted token, which is why this page never calls a token valid on the strength of a successful decode alone.

Why does my JWT show as expired when it should still be valid?

The usual causes are units and clocks. JWT exp, iat and nbf are in seconds since the epoch, so a value copied from a JavaScript Date.now() is a thousand times too large and lands in the year 50000 or beyond. The second cause is clock skew between the machine that issued the token and the machine reading it, which is worth a minute or two. The third is time zone: exp is always UTC, so a token that expires at 23:30 UTC is already gone at 08:00 the next morning in Tokyo.

Which signature algorithms can this tool verify?

HMAC (HS256, HS384, HS512) with the shared secret, and the public-key families RS256/384/512, PS256/384/512 and ES256/384/512 with the PEM public key. You never need the private key, and you should never paste one here. Tokens with alg set to none have no signature at all: this page reports that instead of showing a green result.

Can a JWT be encrypted?

Yes, but that is a different structure. An encrypted token is a JWE and has five dot-separated parts instead of three, and its payload cannot be read without the decryption key. This decoder handles signed tokens (JWS, three parts); if you paste a five-part token it will tell you so rather than show garbage.

← Back to all tools