JWT Decoder

Decode a JSON Web Token's header, payload, and expiry in your browser.

100% Browser-Based Local Processing

Paste your JWT here

Invalid JWT format. Ensure the token contains three distinct Base64URL parts.

Header

{}

Payload

{}

Signature

No token detected

Privacy Focused

🔒 Local Processing. Your code never leaves your device.

Instant Results

🌐 Fully Client-Side. Runs instantly in your browser.

No Signup

⚡ No accounts. No API keys. Just open and use.

Browser Based

🚀 No installs, no CLI, no build step.

Read what's inside a JSON Web Token — without sending it anywhere

A JWT decoder splits a JSON Web Token into its three dot-separated parts and base64url-decodes the header and payload so you can read the claims. A JWT is encoded, not encrypted — anyone holding it can read it. Decoding is not verifying: this tool runs entirely in your browser and does not check signatures.

A JSON Web Token is three base64url-encoded strings joined by dots: a header saying which algorithm signed it, a payload holding the claims, and a signature. A JWT decoder reverses the first two so you can actually read them. Paste a token here and it decodes as you type — no button to press, no upload, no account.

Two things about JWTs surprise people, and both matter more than any feature list. The first: a JWT is encoded, not encrypted. Base64url is a transport format, not a lock. Anyone who gets hold of your token — in a log file, a browser extension, a screenshot — can read every claim in it without a key or a secret. That is by design, and it is why user emails, roles, tenant IDs, and internal flags should be treated as public the moment they go into a payload.

The second: decoding a token is not verifying it. This tool reads what a token claims; it cannot tell you whether those claims are true. Confirming a token is authentic means checking the signature against the signing secret or public key, and that key is not something you should ever paste into a web page. So this decoder deliberately doesn't ask for one, and it doesn't verify. The signature panel shows you the raw third segment and says so plainly.

What it does do is fast and useful: decoded header and payload as formatted JSON, plus a panel showing the algorithm, issued-at and expiration times as real dates with a relative reading like "expired 3 days ago", and a status of Valid, Expired, Not yet valid, or No Expiry. If the header says alg: none, it's flagged as unsigned.

And it stays on your machine. Everything happens in your browser's JavaScript — the token is never transmitted, and the page keeps working offline. Related: Base64 Encoder/Decoder, Unix Timestamp Converter.

When a JWT decoder helps

  • Debugging auth. See which claims your identity provider is actually issuing.
  • Checking expiry. Find out whether a 401 is an expired token or something else.
  • Reading someone else's token format. Compare what two services put in a payload.
  • Spotting oversharing. Notice PII or internal IDs that shouldn't be in a payload at all.
  • Catching alg: none. See immediately when a token carries no integrity protection.
  • Sensitive tokens. Inspect a token without it leaving your device — or, better, use a throwaway one.

How to decode a JWT

Paste the token

Drop the full JWT into the box. It decodes live as you type — there's no Decode button, and nothing is uploaded.

Read the header

The first panel shows the decoded header JSON: the signing algorithm (alg) and usually the type (typ).

Read the payload

The second panel shows the claims — sub, iss, aud, exp, and any custom fields your service added.

Check the metadata panel

Status, Issued At, Expiration, and Algorithm are pulled out as human-readable values, with a relative time on the expiry.

Copy or reset

Copy the header or payload JSON, or hit Reset Decoder to clear everything. To confirm the token is genuine, verify the signature in your own code — not here.

Realistic example

Paste a token whose payload is {"sub":"1234567890","name":"John Doe","iat":1516239022} and you'll see the claims formatted, with Issued At rendered as a real date and Status showing No Expiry — because that payload has no exp claim at all, which is itself worth knowing.

Advanced tip

If Status says Valid, that means one thing only: the exp claim is in the future. It says nothing about whether the signature is good, whether the issuer is who you expect, or whether the token was revoked.

Common mistake to avoid

Don't paste a live production token into any online decoder — including this one — if you can avoid it. Use an expired or test token, or run atob(token.split('.')[1]) in your own browser console.

What to keep in mind

  • This decodes, it does not verify. There is no signature verification on this page — no key input, no crypto check. A decoded token is not a trusted token.
  • "Valid" means "not expired". The status field compares exp to your clock and nothing else. It is not a verdict on authenticity.
  • Your payload is readable by anyone. Base64url is encoding, not encryption. Never put secrets in a JWT payload.
  • Nothing is transmitted. Decoding runs in your browser — no request carries your token, and the page works offline. Open your network tab and confirm it.
  • Signed tokens only. An encrypted JWT (JWE) has five segments, not three, and will be rejected. This tool can't decrypt anything.
  • Treat any pasted token as spent. The safest habit with any web-based decoder is to use tokens you're willing to throw away.
  • Free, no signup, no limits. There's no account and nothing metered.

Frequently Asked Questions

What does a JWT decoder actually do?

It splits a JSON Web Token on its two dots and base64url-decodes the first two segments — the header and the payload — back into readable JSON. That's it. The header tells you the signing algorithm; the payload holds the claims. The third segment, the signature, stays encoded and is shown raw. No key or secret is needed to decode, because nothing in those first two parts is encrypted.

Is a JWT encrypted — can anyone read my token?

A standard JWT is encoded, not encrypted, so yes: anyone holding the token can read the header and payload. Base64url is a transport format, not a lock — no key required. That's why you should never put passwords, secrets, or data you wouldn't want disclosed into a payload. The signature protects against tampering, not against reading. If you need real confidentiality, you need JWE.

Does this tool verify the JWT signature?

No. This decoder reads tokens; it never verifies them. There's no key field, no secret input, and no cryptographic check anywhere on the page — the signature is displayed as raw text and nothing more. Verifying authenticity requires the signing secret or public key, which you should never paste into a web page. A decoded token is not a trusted token. Treat everything you see here as unverified claims.

Is my token uploaded anywhere, and does this work offline?

No upload, and yes it works offline. Decoding happens entirely in your browser's JavaScript — the page makes no request that carries your token, no server receives it, and nothing is stored or logged. You can verify this yourself: open your browser's network tab, paste a token, and watch that no request fires. Once the page has loaded, it keeps decoding with your connection switched off.

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

Honestly: prefer not to, with any tool including this one. A live token is a working credential, and web pages carry risk you can't fully audit — browser extensions can read what you type, and lookalike clone sites of popular decoders exist. Use an expired or test token where you can. If you must inspect a live one, run atob(token.split('.')[1]) in your own console instead.

How do I know if my JWT is expired?

The metadata panel reads the exp claim, converts it from a Unix timestamp to a real date in your local time, and adds a relative reading like "expired 3 days ago" or "in 2 hours". Status then shows Expired, Valid, Not yet valid, or No Expiry if the token carries no exp at all. Note that this compares against your device clock.

What do exp, iat, and nbf mean?

They're registered claims from the JWT spec, all Unix timestamps in seconds. exp (expiration) is when the token stops being acceptable. iat (issued at) is when it was created — the gap between the two is the token's lifetime. nbf (not before) is the earliest time it may be used. This tool displays exp and iat as dates; nbf is read and reflected in the status.

Which algorithms does this recognise, and what does alg: none mean?

The tool shows whatever the header's alg value says — HS256, RS256, ES256 and the rest are all displayed as-is, with no whitelist and no validation against the signature. The one special case is none, which it flags as unsigned. alg: none means the token has no integrity protection at all, and servers that accept it can be trivially forged against — a well-documented authentication bypass.

Why does my token show "Invalid JWT format"?

Almost always a copy-paste problem. A JWT must have exactly three segments separated by two dots — if you clipped a character, grabbed a Bearer prefix, or picked up a line break, the split fails. If the format is right but decoding still errors, a segment isn't valid base64url or doesn't contain JSON. Also check you haven't pasted a five-segment JWE, which this tool can't read.

What's the difference between JWS and JWE — can this decode an encrypted token?

JWS is a signed token: three segments, readable by anyone, protected against tampering. JWE is an encrypted token: five segments, unreadable without the decryption key. This tool handles JWS only — it requires exactly three parts, so a JWE is rejected outright, and it has no decryption capability regardless. When people say "JWT" they almost always mean JWS.

How do I actually verify a JWT properly?

In your own code, with a maintained library — jsonwebtoken or jose in Node, PyJWT in Python, and so on. Verification means checking the signature against the expected key, pinning the algorithm explicitly so none and algorithm-confusion attacks are impossible, and then validating exp, nbf, iss, and aud. Never trust a client-side decode, and never verify by pasting your signing key into a website.

Is it free, and are there limits?

Yes, completely free — no payment, no signup, no account, no usage caps, and no watermarks. Because the decoding runs entirely in your browser, there's nothing for us to meter or rate-limit; the only practical limit is your own device on an unusually large token. Use it as much as you like, including offline once the page has loaded.

Still have questions?

If you can't find the answer you're looking for, feel free to contact our support team.

Contact Us